Merge "Fix AddWidgetTest & AddWidgetConfigTest" into sc-dev
diff --git a/go/OWNERS b/go/OWNERS
new file mode 100644
index 0000000..903b3c4
--- /dev/null
+++ b/go/OWNERS
@@ -0,0 +1,2 @@
+rajekumar@google.com
+spivack@google.com
diff --git a/go/quickstep/res/values/strings.xml b/go/quickstep/res/values/strings.xml
index 71e2f3a..61c8cd9 100644
--- a/go/quickstep/res/values/strings.xml
+++ b/go/quickstep/res/values/strings.xml
@@ -10,5 +10,5 @@
<!-- Label for a button that translates a screenshot of the current app. [CHAR_LIMIT=40] -->
<string name="action_translate">Translate</string>
<!-- Label for a button that triggers Search on a screenshot of the current app. [CHAR_LIMIT=40] -->
- <string name="action_search">Search</string>
+ <string name="action_search">Lens</string>
</resources>
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index 36a4e7f..872f168 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -36,6 +36,8 @@
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
import com.android.launcher3.R;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.TaskThumbnailView;
@@ -51,6 +53,7 @@
public static final String ACTION_SEARCH = "com.android.quickstep.ACTION_SEARCH";
public static final String ELAPSED_NANOS = "niu_actions_elapsed_realtime_nanos";
public static final String ACTIONS_URL = "niu_actions_app_url";
+ private static final String ASSIST_KEY_CONTENT = "content";
private static final String TAG = "TaskOverlayFactoryGo";
// Empty constructor required for ResourceBasedOverride
@@ -68,8 +71,6 @@
* @param <T> The type of View in which the overlay will be placed
*/
public static final class TaskOverlayGo<T extends OverviewActionsView> extends TaskOverlay {
- private static final String ASSIST_KEY_CONTENT = "content";
-
private String mNIUPackageName;
private int mTaskId;
private Bundle mAssistData;
@@ -95,7 +96,7 @@
}
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
- boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
+ boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot();
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
mTaskId = task.key.id;
@@ -122,7 +123,11 @@
});
}
- private void sendNIUIntent(String actionType) {
+ /**
+ * Creates and sends an Intent corresponding to the button that was clicked
+ */
+ @VisibleForTesting
+ public void sendNIUIntent(String actionType) {
Intent intent = createNIUIntent(actionType);
mImageApi.shareAsDataWithExplicitIntent(/* crop */ null, intent);
}
@@ -178,6 +183,11 @@
}
}
}
+
+ @VisibleForTesting
+ public void setImageActionsAPI(ImageActionsApi imageActionsApi) {
+ mImageApi = imageActionsApi;
+ }
}
/**
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
index 34ff91d..c61610a 100644
--- a/quickstep/res/layout/overview_clear_all_button.xml
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -22,5 +22,4 @@
android:layout_height="wrap_content"
android:text="@string/recents_clear_all"
android:textColor="?attr/workspaceTextColor"
- android:textSize="14sp"
- android:translationY="@dimen/task_thumbnail_half_top_margin" />
\ No newline at end of file
+ android:textSize="14sp" />
\ No newline at end of file
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 0f9a6aa..7e5b85c 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -13,6 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<!-- NOTE! don't add dimensions for margins / paddings / sizes that change per orientation to this
+ file, they need to be loaded at runtime. -->
<com.android.quickstep.views.TaskView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
@@ -24,8 +26,7 @@
<com.android.quickstep.views.TaskThumbnailView
android:id="@+id/snapshot"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="@dimen/task_thumbnail_top_margin"/>
+ android:layout_height="match_parent"/>
<com.android.quickstep.views.IconView
android:id="@+id/icon"
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index c03eaa2..7cb01f6 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -16,4 +16,6 @@
-->
<resources>
<dimen name="task_card_menu_horizontal_padding">24dp</dimen>
+
+ <dimen name="overview_task_margin">8dp</dimen>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 755bce8..3036341 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -15,11 +15,8 @@
-->
<resources>
-
- <dimen name="task_thumbnail_top_margin">80dp</dimen>
- <dimen name="task_thumbnail_half_top_margin">40dp</dimen>
<dimen name="task_thumbnail_icon_size">48dp</dimen>
- <dimen name="task_icon_top_margin">16dp</dimen>
+ <dimen name="task_thumbnail_icon_size_grid">32dp</dimen>
<!-- For screens without rounded corners -->
<dimen name="task_corner_radius_small">2dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 0764bb3..1603321 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -99,62 +99,61 @@
<!-- Dismiss button string for search education view -->
<string name="search_edu_dismiss">Got it.</string>
-
- <!-- Title shown during interactive part of Back gesture tutorial for right edge. [CHAR LIMIT=30] -->
- <string name="back_gesture_tutorial_playground_title_swipe_inward_right_edge" translatable="false">Try the back gesture</string>
- <!-- Subtitle shown during interactive parts of Back gesture tutorial for right edge. [CHAR LIMIT=60] -->
- <string name="back_gesture_tutorial_engaged_subtitle_swipe_inward_right_edge" translatable="false">Start at the right edge and swipe toward the middle</string>
- <!-- Feedback shown during interactive parts of Back gesture tutorial for right edge when the gesture is too far from the edge. [CHAR LIMIT=100] -->
- <string name="back_gesture_feedback_swipe_too_far_from_right_edge" translatable="false">Make sure you swipe from the far right edge</string>
- <!-- Feedback shown during interactive parts of Back gesture tutorial for right edge when the gesture is cancelled. [CHAR LIMIT=100] -->
- <string name="back_gesture_feedback_cancelled_right_edge" translatable="false">Make sure you swipe straight to the left and let go</string>
-
- <!-- Title shown during interactive part of Back gesture tutorial for left edge. [CHAR LIMIT=30] -->
- <string name="back_gesture_tutorial_playground_title_swipe_inward_left_edge" translatable="false">Try the other side</string>
- <!-- 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>
<!-- Feedback shown during interactive parts of Back gesture tutorial for left edge when the gesture is too far from the edge. [CHAR LIMIT=100] -->
- <string name="back_gesture_feedback_swipe_too_far_from_left_edge" translatable="false">Make sure you swipe from the far left edge</string>
+ <string name="back_gesture_feedback_swipe_too_far_from_left_edge">Make sure you swipe from the far-left edge.</string>
<!-- Feedback shown during interactive parts of Back gesture tutorial for left edge when the gesture is cancelled. [CHAR LIMIT=100] -->
- <string name="back_gesture_feedback_cancelled_left_edge" translatable="false">Make sure you swipe straight to the right and let go</string>
-
+ <string name="back_gesture_feedback_cancelled_left_edge">Make sure you swipe from the left edge to the middle of the screen and let go.</string>
+ <!-- Feedback shown after completing the left back gesture before continuing on to the right edge. [CHAR LIMIT=60] -->
+ <string name="back_gesture_feedback_complete_left_edge">That\'s it! Now try swiping from the right edge.</string>
+ <!-- Feedback shown during interactive parts of Back gesture tutorial for right edge when the gesture is too far from the edge. [CHAR LIMIT=100] -->
+ <string name="back_gesture_feedback_swipe_too_far_from_right_edge">Make sure you swipe from the far-right edge.</string>
+ <!-- Feedback shown during interactive parts of Back gesture tutorial for right edge when the gesture is cancelled. [CHAR LIMIT=100] -->
+ <string name="back_gesture_feedback_cancelled_right_edge">Make sure you swipe from the right edge to the middle of the screen and let go.</string>
+ <!-- Feedback shown during interactive parts of Back gesture tutorial for left edge when the gesture is cancelled. [CHAR LIMIT=100] -->
+ <string name="back_gesture_feedback_complete">You completed the go back gesture. Next up, learn how to go Home.</string>
<!-- Feedback shown during interactive parts of Back gesture tutorial when the gesture is within the nav bar region. [CHAR LIMIT=100] -->
- <string name="back_gesture_feedback_swipe_in_nav_bar" translatable="false">Make sure you don\'t swipe too close to the bottom of the screen</string>
+ <string name="back_gesture_feedback_swipe_in_nav_bar">Make sure you don\'t swipe too close to the bottom of the screen.</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>
+ <string name="back_gesture_tutorial_confirm_subtitle">To change the sensitivity of the back gesture, go to Settings</string>
<!-- Feedback shown during interactive parts of Home gesture tutorial when the gesture is started too far from the edge. [CHAR LIMIT=100] -->
- <string name="home_gesture_feedback_swipe_too_far_from_edge" translatable="false">Make sure you swipe from the bottom edge of the screen</string>
- <!-- Feedback shown during interactive parts of Home gesture tutorial when the Overview gesture is detected. [CHAR LIMIT=100] -->
- <string name="home_gesture_feedback_overview_detected" translatable="false">Make sure you don\'t pause before letting go</string>
- <!-- Feedback shown during interactive parts of Home gesture tutorial when the gesture is horizontal instead of vertical. [CHAR LIMIT=100] -->
- <string name="home_gesture_feedback_wrong_swipe_direction" translatable="false">Make sure you swipe straight up</string>
+ <!-- Introduction title for the Back gesture tutorial. [CHAR LIMIT=100] -->
+ <string name="back_gesture_intro_title">Swipe to go back</string>
+ <!-- Introduction subtitle for the Back gesture tutorial. [CHAR LIMIT=100] -->
+ <string name="back_gesture_intro_subtitle">To go back to the last screen, swipe from the left or right edge to the middle of the screen.</string>
- <!-- Title shown during interactive part of Overview gesture tutorial. [CHAR LIMIT=30] -->
- <string name="overview_gesture_tutorial_playground_title" translatable="false">Tutorial: Switch Apps</string>
- <!-- Subtitle shown during interactive parts of Overview gesture tutorial. [CHAR LIMIT=60] -->
- <string name="overview_gesture_tutorial_playground_subtitle" translatable="false">Swipe up from the bottom of the screen and hold</string>
+ <string name="home_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
+ <!-- Feedback shown during interactive parts of Home gesture tutorial when the Overview gesture is detected. [CHAR LIMIT=100] -->
+ <string name="home_gesture_feedback_overview_detected">Make sure you don\'t pause before letting go.</string>
+ <!-- Feedback shown during interactive parts of Home gesture tutorial when the gesture is horizontal instead of vertical. [CHAR LIMIT=100] -->
+ <string name="home_gesture_feedback_wrong_swipe_direction">Make sure you swipe straight up.</string>
+ <string name="home_gesture_feedback_complete">You completed the go Home gesture. Next up, learn how to switch apps.</string>
+ <!-- Introduction title for the Home gesture tutorial. [CHAR LIMIT=100] -->
+ <string name="home_gesture_intro_title">Swipe to go home</string>
+ <!-- Introduction subtitle for the Home gesture tutorial. [CHAR LIMIT=100] -->
+ <string name="home_gesture_intro_subtitle">Swipe up from the bottom of your screen. This gesture always takes you to the Home screen.</string>
+
<!-- Feedback shown during interactive parts of Overview gesture tutorial when the gesture is started too far from the edge. [CHAR LIMIT=100] -->
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" translatable="false">Make sure you swipe from the bottom edge of the screen</string>
+ <string name="overview_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
<!-- Feedback shown during interactive parts of Overview gesture tutorial when the Home gesture is detected. [CHAR LIMIT=100] -->
- <string name="overview_gesture_feedback_home_detected" translatable="false">Try holding the window for longer before releasing</string>
+ <string name="overview_gesture_feedback_home_detected">Try holding the window for longer before releasing.</string>
<!-- Feedback shown during interactive parts of Overview gesture tutorial when the gesture is horizontal instead of vertical. [CHAR LIMIT=100] -->
- <string name="overview_gesture_feedback_wrong_swipe_direction" translatable="false">Make sure you swipe straight up and pause</string>
+ <string name="overview_gesture_feedback_wrong_swipe_direction">Make sure you swipe straight up, then pause.</string>
+ <string name="overview_gesture_feedback_complete">You completed the switch apps gesture. You\'re ready to use your phone!</string>
+ <!-- Introduction title for the Overview gesture tutorial. [CHAR LIMIT=100] -->
+ <string name="overview_gesture_intro_title">Swipe to switch apps</string>
+ <!-- Introduction subtitle for the Overview gesture tutorial. [CHAR LIMIT=100] -->
+ <string name="overview_gesture_intro_subtitle">Swipe up from the bottom of your screen, hold, then release.</string>
<!-- Title shown during interactive part of Assistant gesture tutorial. [CHAR LIMIT=30] -->
<string name="assistant_gesture_tutorial_playground_title" translatable="false">Tutorial: Assistant</string>
<!-- Subtitle shown during interactive parts of Assistant gesture tutorial. [CHAR LIMIT=60] -->
<string name="assistant_gesture_tutorial_playground_subtitle" translatable="false">Try swiping diagonally from a bottom corner of the screen</string>
<!-- Feedback shown during interactive parts of Assistant gesture tutorial when the gesture is started too far from the corner. [CHAR LIMIT=100] -->
- <string name="assistant_gesture_feedback_swipe_too_far_from_corner" translatable="false">Make sure you swipe from a bottom corner of the screen</string>
+ <string name="assistant_gesture_feedback_swipe_too_far_from_corner" translatable="false">Make sure you swipe from a bottom corner of the screen.</string>
<!-- Feedback shown during interactive parts of Assistant gesture tutorial when the gesture doesn't go diagonally enough. [CHAR LIMIT=100] -->
- <string name="assistant_gesture_feedback_swipe_not_diagonal" translatable="false">Make sure you swipe diagonally</string>
+ <string name="assistant_gesture_feedback_swipe_not_diagonal" translatable="false">Make sure you swipe diagonally.</string>
<!-- Feedback shown during interactive parts of Assistant gesture tutorial when the gesture doesn't go far enough. [CHAR LIMIT=100] -->
- <string name="assistant_gesture_feedback_swipe_not_long_enough" translatable="false">Try swiping further</string>
+ <string name="assistant_gesture_feedback_swipe_not_long_enough" translatable="false">Try swiping further.</string>
<!-- Title shown in sandbox mode part of gesture tutorial. [CHAR LIMIT=30] -->
<string name="sandbox_mode_title" translatable="false">Sandbox Mode</string>
@@ -172,11 +171,19 @@
<string name="sandbox_mode_back_gesture_feedback_swipe_too_far_from_edge" translatable="false">Make sure you swipe from the left/right 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 to leave the tutorial. [CHAR LIMIT=14] -->
- <string name="gesture_tutorial_action_button_label_done" translatable="false">Done</string>
+ <string name="gesture_tutorial_confirm_title">All set</string>
+ <!-- Button text shown on a button on the feedback popup to proceed to the next tutorial step. [CHAR LIMIT=14] -->
+ <string name="gesture_tutorial_action_button_label_next">Next</string>
+ <!-- Button text shown on a button on the feedback popup to complete the tutorial. [CHAR LIMIT=14] -->
+ <string name="gesture_tutorial_action_button_label_done">Done</string>
<!-- Button text shown on a button to go to Settings. [CHAR LIMIT=14] -->
- <string name="gesture_tutorial_action_button_label_settings" translatable="false">Settings</string>
+ <string name="gesture_tutorial_action_button_label_settings">Settings</string>
+ <!-- Feedback title to try again. [CHAR LIMIT=30] -->
+ <string name="gesture_tutorial_try_again">Try again</string>
+ <!-- Feedback title for a successful gesture. [CHAR LIMIT=30] -->
+ <string name="gesture_tutorial_nice">Nice!</string>
+ <!-- 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>
<!-- ******* Overview ******* -->
<!-- Label for a button that causes the current overview app to be shared. [CHAR_LIMIT=40] -->
@@ -185,4 +192,14 @@
<string name="action_screenshot">Screenshot</string>
<!-- Message shown when an action is blocked by a policy enforced by the app or the organization managing the device. [CHAR_LIMIT=NONE] -->
<string name="blocked_by_policy">This action isn\'t allowed by the app or your organization</string>
+
+ <!-- ******* Skip tutorial dialog ******* -->
+ <!-- Title for the dialog that allows the user to skip the gesture navigation tutorial. [CHAR_LIMIT=40] -->
+ <string name="skip_tutorial_dialog_title">Skip navigation tutorial?</string>
+ <!-- Subtitle for the dialog that allows the user to skip the gesture navigation tutorial. [CHAR_LIMIT=40] -->
+ <string name="skip_tutorial_dialog_subtitle">You can find this later in the Tips app</string>
+ <!-- Button text shown on a button on the tutorial skip dialog to return to the tutorial. [CHAR LIMIT=14] -->
+ <string name="gesture_tutorial_action_button_label_cancel">Cancel</string>
+ <!-- Button text shown on a button on the tutorial skip dialog to exit the tutorial. [CHAR LIMIT=14] -->
+ <string name="gesture_tutorial_action_button_label_skip">Skip</string>
</resources>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 9ab49ce..085db6d 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -336,12 +336,16 @@
}
@Override
+ public float getNormalTaskbarScale() {
+ if (mTaskbarController != null) {
+ return mTaskbarController.getTaskbarScaleOnHome();
+ }
+ return super.getNormalTaskbarScale();
+ }
+
+ @Override
public void onDragLayerHierarchyChanged() {
onLauncherStateOrFocusChanged();
-
- if (mTaskbarController != null) {
- mTaskbarController.onLauncherDragLayerHierarchyChanged();
- }
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index fc5e2c1..5513c16 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -35,14 +35,13 @@
private final DeviceProfile mDeviceProfile;
private final LayoutInflater mLayoutInflater;
private final TaskbarContainerView mTaskbarContainerView;
- private final float mIconScale;
public TaskbarActivityContext(BaseQuickstepLauncher launcher) {
super(launcher);
mDeviceProfile = launcher.getDeviceProfile().copy(this);
float taskbarIconSize = getResources().getDimension(R.dimen.taskbar_icon_size);
- mIconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
- mDeviceProfile.updateIconSize(mIconScale, getResources());
+ float iconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
+ mDeviceProfile.updateIconSize(iconScale, getResources());
mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
@@ -73,11 +72,4 @@
public Rect getFolderBoundingBox() {
return mTaskbarContainerView.getFolderBoundingBox();
}
-
- /**
- * @return The ratio of taskbar icon size vs normal workspace/hotseat icon size.
- */
- public float getTaskbarIconScale() {
- return mIconScale;
- }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarVisibilityController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
similarity index 72%
rename from quickstep/src/com/android/launcher3/taskbar/TaskbarVisibilityController.java
rename to quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
index 2228eba..7c54e2d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
@@ -20,36 +20,38 @@
import android.animation.Animator;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.Utilities;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
import com.android.systemui.shared.system.QuickStepContract;
/**
- * Works with TaskbarController to update the TaskbarView's alpha based on LauncherState, whether
- * Launcher is in the foreground, etc.
+ * Works with TaskbarController to update the TaskbarView's visual properties based on factors such
+ * as LauncherState, whether Launcher is in the foreground, etc.
*/
-public class TaskbarVisibilityController {
+public class TaskbarAnimationController {
private static final long IME_VISIBILITY_ALPHA_DURATION = 120;
- private static final long FLOATING_VIEW_VISIBILITY_ALPHA_DURATION = 120;
private final BaseQuickstepLauncher mLauncher;
- private final TaskbarController.TaskbarVisibilityControllerCallbacks mTaskbarCallbacks;
+ private final TaskbarController.TaskbarAnimationControllerCallbacks mTaskbarCallbacks;
// Background alpha.
- private AnimatedFloat mTaskbarBackgroundAlpha = new AnimatedFloat(
+ private final AnimatedFloat mTaskbarBackgroundAlpha = new AnimatedFloat(
this::onTaskbarBackgroundAlphaChanged);
// Overall visibility.
- private AnimatedFloat mTaskbarVisibilityAlphaForLauncherState = new AnimatedFloat(
+ private final AnimatedFloat mTaskbarVisibilityAlphaForLauncherState = new AnimatedFloat(
this::updateVisibilityAlpha);
- private AnimatedFloat mTaskbarVisibilityAlphaForIme = new AnimatedFloat(
- this::updateVisibilityAlpha);
- private AnimatedFloat mTaskbarVisibilityAlphaForFloatingView = new AnimatedFloat(
+ private final AnimatedFloat mTaskbarVisibilityAlphaForIme = new AnimatedFloat(
this::updateVisibilityAlpha);
- public TaskbarVisibilityController(BaseQuickstepLauncher launcher,
- TaskbarController.TaskbarVisibilityControllerCallbacks taskbarCallbacks) {
+ // Scale.
+ private final AnimatedFloat mTaskbarScaleForLauncherState = new AnimatedFloat(
+ this::updateScale);
+
+ public TaskbarAnimationController(BaseQuickstepLauncher launcher,
+ TaskbarController.TaskbarAnimationControllerCallbacks taskbarCallbacks) {
mLauncher = launcher;
mTaskbarCallbacks = taskbarCallbacks;
}
@@ -62,7 +64,6 @@
boolean isImeVisible = (SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags()
& QuickStepContract.SYSUI_STATE_IME_SHOWING) != 0;
mTaskbarVisibilityAlphaForIme.updateValue(isImeVisible ? 0f : 1f);
- mTaskbarVisibilityAlphaForFloatingView.updateValue(1f);
onTaskbarBackgroundAlphaChanged();
updateVisibilityAlpha();
@@ -76,6 +77,10 @@
return mTaskbarVisibilityAlphaForLauncherState;
}
+ protected AnimatedFloat getTaskbarScaleForLauncherState() {
+ return mTaskbarScaleForLauncherState;
+ }
+
protected Animator createAnimToBackgroundAlpha(float toAlpha, long duration) {
return mTaskbarBackgroundAlpha.animateToValue(mTaskbarBackgroundAlpha.value, toAlpha)
.setDuration(duration);
@@ -86,14 +91,10 @@
.setDuration(IME_VISIBILITY_ALPHA_DURATION).start();
}
- protected void animateToVisibilityForFloatingView(float toAlpha) {
- mTaskbarVisibilityAlphaForIme.animateToValue(mTaskbarVisibilityAlphaForFloatingView.value,
- toAlpha).setDuration(FLOATING_VIEW_VISIBILITY_ALPHA_DURATION).start();
- }
-
private void onTaskbarBackgroundAlphaChanged() {
mTaskbarCallbacks.updateTaskbarBackgroundAlpha(mTaskbarBackgroundAlpha.value);
updateVisibilityAlpha();
+ updateScale();
}
private void updateVisibilityAlpha() {
@@ -102,8 +103,7 @@
// LauncherState if Launcher is paused.
float alphaDueToLauncher = Math.max(mTaskbarBackgroundAlpha.value,
mTaskbarVisibilityAlphaForLauncherState.value);
- float alphaDueToOther = mTaskbarVisibilityAlphaForIme.value
- * mTaskbarVisibilityAlphaForFloatingView.value;
+ float alphaDueToOther = mTaskbarVisibilityAlphaForIme.value;
float taskbarAlpha = alphaDueToLauncher * alphaDueToOther;
mTaskbarCallbacks.updateTaskbarVisibilityAlpha(taskbarAlpha);
@@ -111,6 +111,15 @@
setNavBarButtonAlpha(1f - taskbarAlpha);
}
+ private void updateScale() {
+ // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the
+ // assumption being that Taskbar should always be at scale 1f regardless of the current
+ // LauncherState if Launcher is paused.
+ float scale = mTaskbarScaleForLauncherState.value;
+ scale = Utilities.mapRange(mTaskbarBackgroundAlpha.value, scale, 1f);
+ mTaskbarCallbacks.updateTaskbarScale(scale);
+ }
+
private void setNavBarButtonAlpha(float navBarAlpha) {
SystemUiProxy.INSTANCE.get(mLauncher).setNavBarButtonAlpha(navBarAlpha, false);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
index abf6d54..de23ad2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
@@ -19,8 +19,6 @@
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
@@ -75,7 +73,7 @@
// Layout width and height of the Taskbar in the default state.
private final Point mTaskbarSize;
private final TaskbarStateHandler mTaskbarStateHandler;
- private final TaskbarVisibilityController mTaskbarVisibilityController;
+ private final TaskbarAnimationController mTaskbarAnimationController;
private final TaskbarHotseatController mHotseatController;
private final TaskbarRecentsController mRecentsController;
private final TaskbarDragController mDragController;
@@ -104,8 +102,8 @@
mWindowManager = mLauncher.getWindowManager();
mTaskbarSize = new Point(MATCH_PARENT, mLauncher.getDeviceProfile().taskbarSize);
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
- mTaskbarVisibilityController = new TaskbarVisibilityController(mLauncher,
- createTaskbarVisibilityControllerCallbacks());
+ mTaskbarAnimationController = new TaskbarAnimationController(mLauncher,
+ createTaskbarAnimationControllerCallbacks());
mHotseatController = new TaskbarHotseatController(mLauncher,
createTaskbarHotseatControllerCallbacks());
mRecentsController = new TaskbarRecentsController(mLauncher,
@@ -113,8 +111,8 @@
mDragController = new TaskbarDragController(mLauncher);
}
- private TaskbarVisibilityControllerCallbacks createTaskbarVisibilityControllerCallbacks() {
- return new TaskbarVisibilityControllerCallbacks() {
+ private TaskbarAnimationControllerCallbacks createTaskbarAnimationControllerCallbacks() {
+ return new TaskbarAnimationControllerCallbacks() {
@Override
public void updateTaskbarBackgroundAlpha(float alpha) {
mTaskbarViewInApp.setBackgroundAlpha(alpha);
@@ -125,6 +123,12 @@
mTaskbarContainerView.setAlpha(alpha);
mTaskbarViewOnHome.setAlpha(alpha);
}
+
+ @Override
+ public void updateTaskbarScale(float scale) {
+ mTaskbarViewInApp.setScaleX(scale);
+ mTaskbarViewInApp.setScaleY(scale);
+ }
};
}
@@ -151,13 +155,22 @@
ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key,
ActivityOptions.makeBasic());
} else if (tag instanceof FolderInfo) {
- if (mLauncher.hasBeenResumed()) {
- FolderInfo folderInfo = (FolderInfo) tag;
- onClickedOnFolderFromHome(folderInfo);
- } else {
- FolderIcon folderIcon = (FolderIcon) view;
- onClickedOnFolderInApp(folderIcon);
- }
+ FolderIcon folderIcon = (FolderIcon) view;
+ Folder folder = folderIcon.getFolder();
+
+ setTaskbarWindowFullscreen(true);
+
+ mTaskbarContainerView.post(() -> {
+ folder.animateOpen();
+
+ folder.iterateOverItems((itemInfo, itemView) -> {
+ itemView.setOnClickListener(getItemOnClickListener());
+ itemView.setOnLongClickListener(getItemOnLongClickListener());
+ // To play haptic when dragging, like other Taskbar items do.
+ itemView.setHapticFeedbackEnabled(true);
+ return false;
+ });
+ });
} else {
ItemClickHandler.INSTANCE.onClick(view);
}
@@ -167,44 +180,9 @@
};
}
- // Open the real folder in Launcher.
- private void onClickedOnFolderFromHome(FolderInfo folderInfo) {
- alignRealHotseatWithTaskbar();
-
- FolderIcon folderIcon = (FolderIcon) mLauncher.getHotseat()
- .getFirstItemMatch((info, v) -> info == folderInfo);
- folderIcon.post(folderIcon::performClick);
- }
-
- // Open the Taskbar folder, and handle clicks on folder items.
- private void onClickedOnFolderInApp(FolderIcon folderIcon) {
- Folder folder = folderIcon.getFolder();
-
- setTaskbarWindowFullscreen(true);
-
- mTaskbarContainerView.post(() -> {
- folder.animateOpen();
-
- folder.iterateOverItems((itemInfo, itemView) -> {
- itemView.setOnClickListener(getItemOnClickListener());
- itemView.setOnLongClickListener(getItemOnLongClickListener());
- // To play haptic when dragging, like other Taskbar items do.
- itemView.setHapticFeedbackEnabled(true);
- return false;
- });
- });
- }
-
@Override
public View.OnLongClickListener getItemOnLongClickListener() {
- return view -> {
- if (mLauncher.hasBeenResumed() && view.getTag() instanceof ItemInfo) {
- // TODO: remove this path
- return mDragController.startWorkspaceDragOnLongClick(view);
- } else {
- return mDragController.startSystemDragOnLongClick(view);
- }
- };
+ return mDragController::startSystemDragOnLongClick;
}
@Override
@@ -268,12 +246,10 @@
mTaskbarContainerView.init(mTaskbarViewInApp);
addToWindowManager();
mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks());
- mTaskbarVisibilityController.init();
+ mTaskbarAnimationController.init();
mHotseatController.init();
mRecentsController.init();
- SCALE_PROPERTY.set(mTaskbarViewInApp, mLauncher.hasBeenResumed()
- ? getTaskbarScaleOnHome() : 1f);
updateWhichTaskbarViewIsVisible();
}
@@ -281,7 +257,12 @@
return new TaskbarStateHandlerCallbacks() {
@Override
public AnimatedFloat getAlphaTarget() {
- return mTaskbarVisibilityController.getTaskbarVisibilityForLauncherState();
+ return mTaskbarAnimationController.getTaskbarVisibilityForLauncherState();
+ }
+
+ @Override
+ public AnimatedFloat getScaleTarget() {
+ return mTaskbarAnimationController.getTaskbarScaleForLauncherState();
}
};
}
@@ -300,7 +281,7 @@
mTaskbarContainerView.cleanup();
removeFromWindowManager();
mTaskbarStateHandler.setTaskbarCallbacks(null);
- mTaskbarVisibilityController.cleanup();
+ mTaskbarAnimationController.cleanup();
mHotseatController.cleanup();
mRecentsController.cleanup();
}
@@ -368,12 +349,10 @@
*/
public Animator createAnimToLauncher(@Nullable LauncherState toState, long duration) {
PendingAnimation anim = new PendingAnimation(duration);
- anim.add(mTaskbarVisibilityController.createAnimToBackgroundAlpha(0, duration));
+ anim.add(mTaskbarAnimationController.createAnimToBackgroundAlpha(0, duration));
if (toState != null) {
mTaskbarStateHandler.setStateWithAnimation(toState, new StateAnimationConfig(), anim);
}
- anim.addFloat(mTaskbarViewInApp, SCALE_PROPERTY, mTaskbarViewInApp.getScaleX(),
- getTaskbarScaleOnHome(), LINEAR);
anim.addListener(new AnimatorListenerAdapter() {
@Override
@@ -394,8 +373,7 @@
private Animator createAnimToApp(long duration) {
PendingAnimation anim = new PendingAnimation(duration);
- anim.add(mTaskbarVisibilityController.createAnimToBackgroundAlpha(1, duration));
- anim.addFloat(mTaskbarViewInApp, SCALE_PROPERTY, mTaskbarViewInApp.getScaleX(), 1f, LINEAR);
+ anim.add(mTaskbarAnimationController.createAnimToBackgroundAlpha(1, duration));
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
@@ -416,7 +394,7 @@
* Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
*/
public void setIsImeVisible(boolean isImeVisible) {
- mTaskbarVisibilityController.animateToVisibilityForIme(isImeVisible ? 0 : 1);
+ mTaskbarAnimationController.animateToVisibilityForIme(isImeVisible ? 0 : 1);
}
/**
@@ -509,14 +487,6 @@
mTaskbarViewOnHome.getHeight() - hotseatBounds.bottom);
}
- /**
- * A view was added or removed from DragLayer, check if we need to hide our hotseat copy and
- * show the real one instead.
- */
- public void onLauncherDragLayerHierarchyChanged() {
- // TODO: remove, as this is a no-op now
- }
-
private void updateWhichTaskbarViewIsVisible() {
boolean isInApp = !mLauncher.hasBeenResumed() || mIsAnimatingToLauncher
|| mIsAnimatingToApp;
@@ -561,15 +531,17 @@
*/
protected interface TaskbarStateHandlerCallbacks {
AnimatedFloat getAlphaTarget();
+ AnimatedFloat getScaleTarget();
}
/**
- * Contains methods that TaskbarVisibilityController can call to interface with
+ * Contains methods that TaskbarAnimationController can call to interface with
* TaskbarController.
*/
- protected interface TaskbarVisibilityControllerCallbacks {
+ protected interface TaskbarAnimationControllerCallbacks {
void updateTaskbarBackgroundAlpha(float alpha);
void updateTaskbarVisibilityAlpha(float alpha);
+ void updateTaskbarScale(float scale);
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index f51e498..5eb34cb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -33,7 +33,6 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
-import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ClipDescriptionCompat;
@@ -126,38 +125,6 @@
}
/**
- * Starts a drag and drop operation that controls a real Workspace (Hotseat) view.
- * @param view The Taskbar item that was long clicked.
- * @return Whether {@link View#startDragAndDrop} started successfully.
- */
- protected boolean startWorkspaceDragOnLongClick(View view) {
- View.DragShadowBuilder transparentShadowBuilder = new View.DragShadowBuilder(view) {
- private static final int ARBITRARY_SHADOW_SIZE = 10;
-
- @Override
- public void onDrawShadow(Canvas canvas) {
- }
-
- @Override
- public void onProvideShadowMetrics(Point outShadowSize, Point outShadowTouchPoint) {
- outShadowSize.set(ARBITRARY_SHADOW_SIZE, ARBITRARY_SHADOW_SIZE);
- outShadowTouchPoint.set(ARBITRARY_SHADOW_SIZE / 2, ARBITRARY_SHADOW_SIZE / 2);
- }
- };
-
- TaskbarDragListener taskbarDragListener = new TaskbarDragListener(mLauncher,
- (ItemInfo) view.getTag());
- if (view.startDragAndDrop(new ClipData("", new String[] {taskbarDragListener.getMimeType()},
- new ClipData.Item("")),
- transparentShadowBuilder, null /* localState */, View.DRAG_FLAG_GLOBAL)) {
- view.setOnDragListener(getDraggedViewDragListener());
- taskbarDragListener.init(mLauncher.getDragLayer());
- return true;
- }
- return false;
- }
-
- /**
* Hide the original Taskbar item while it is being dragged.
*/
private View.OnDragListener getDraggedViewDragListener() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragListener.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragListener.java
deleted file mode 100644
index dc27df1..0000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragListener.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.launcher3.taskbar;
-
-import android.content.ClipDescription;
-import android.graphics.Point;
-import android.view.DragEvent;
-import android.view.View;
-
-import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.model.data.ItemInfo;
-
-import java.util.UUID;
-
-/**
- * Listens to system drag and drop events initated by the Taskbar, and forwards them to Launcher's
- * internal DragController to move Hotseat items.
- */
-public class TaskbarDragListener implements View.OnDragListener {
-
- private static final String MIME_TYPE_PREFIX = "com.android.launcher3.taskbar.drag_and_drop/";
-
- private final BaseQuickstepLauncher mLauncher;
- private final ItemInfo mDraggedItem;
- // Randomly generated id used to verify the drag event.
- private final String mId;
-
- // Initialized in init().
- DragLayer mDragLayer;
-
- /**
- * @param draggedItem The info of the item that was long clicked, which we will use to find
- * the equivalent match on Hotseat to drag internally.
- */
- public TaskbarDragListener(BaseQuickstepLauncher launcher, ItemInfo draggedItem) {
- mLauncher = launcher;
- mDraggedItem = draggedItem;
- mId = UUID.randomUUID().toString();
- }
-
- protected void init(DragLayer dragLayer) {
- mDragLayer = dragLayer;
- mDragLayer.setOnDragListener(this);
- // Temporarily disable haptics, as system will already play one when drag and drop starts.
- mDragLayer.setHapticFeedbackEnabled(false);
- }
-
- private void cleanup() {
- mDragLayer.setOnDragListener(null);
- mLauncher.setNextWorkspaceDragOptions(null);
- mDragLayer.setHapticFeedbackEnabled(true);
- }
-
- /**
- * Returns a randomly generated id used to verify the drag event.
- */
- protected String getMimeType() {
- return MIME_TYPE_PREFIX + mId;
- }
-
- @Override
- public boolean onDrag(View dragLayer, DragEvent dragEvent) {
- ClipDescription clipDescription = dragEvent.getClipDescription();
- if (dragEvent.getAction() == DragEvent.ACTION_DRAG_STARTED) {
- if (clipDescription == null || !clipDescription.hasMimeType(getMimeType())) {
- // We didn't initiate this drag, ignore.
- cleanup();
- return false;
- }
- View hotseatView = mLauncher.getHotseat().getFirstItemMatch(
- (info, view) -> info == mDraggedItem);
- if (hotseatView == null) {
- cleanup();
- return false;
- }
- DragOptions dragOptions = new DragOptions();
- dragOptions.simulatedDndStartPoint = new Point((int) dragEvent.getX(),
- (int) dragEvent.getY());
- mLauncher.setNextWorkspaceDragOptions(dragOptions);
- hotseatView.performLongClick();
- } else if (dragEvent.getAction() == DragEvent.ACTION_DRAG_ENDED) {
- cleanup();
- }
- return mLauncher.getDragController().onDragEvent(dragEvent);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
index b4b5d8b..9fc7d99 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
@@ -16,14 +16,12 @@
package com.android.launcher3.taskbar;
import static com.android.launcher3.LauncherState.TASKBAR;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_TASKBAR_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.SKIP_TASKBAR;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.states.StateAnimationConfig;
@@ -55,8 +53,10 @@
}
AnimatedFloat alphaTarget = mTaskbarCallbacks.getAlphaTarget();
+ AnimatedFloat scaleTarget = mTaskbarCallbacks.getScaleTarget();
boolean isTaskbarVisible = (state.getVisibleElements(mLauncher) & TASKBAR) != 0;
alphaTarget.updateValue(isTaskbarVisible ? 1f : 0f);
+ scaleTarget.updateValue(state.getTaskbarScale(mLauncher));
}
@Override
@@ -65,13 +65,12 @@
if (mTaskbarCallbacks == null) {
return;
}
- if (config.hasAnimationFlag(SKIP_TASKBAR)) {
- return;
- }
AnimatedFloat alphaTarget = mTaskbarCallbacks.getAlphaTarget();
+ AnimatedFloat scaleTarget = mTaskbarCallbacks.getScaleTarget();
boolean isTaskbarVisible = (toState.getVisibleElements(mLauncher) & TASKBAR) != 0;
- animation.setFloat(alphaTarget, AnimatedFloat.VALUE, isTaskbarVisible ? 1f : 0f,
- config.getInterpolator(ANIM_TASKBAR_FADE, Interpolators.LINEAR));
+ animation.setFloat(alphaTarget, AnimatedFloat.VALUE, isTaskbarVisible ? 1f : 0f, LINEAR);
+ animation.setFloat(scaleTarget, AnimatedFloat.VALUE, toState.getTaskbarScale(mLauncher),
+ LINEAR);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 3567c17..21a2d51 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -120,11 +120,6 @@
}
protected void init(int numHotseatIcons, int numRecentIcons) {
- mLayoutTransition = new LayoutTransition();
- addUpdateListenerForAllLayoutTransitions(
- () -> mControllerCallbacks.onItemPositionsChanged(this));
- setLayoutTransition(mLayoutTransition);
-
mHotseatStartIndex = 0;
mHotseatEndIndex = mHotseatStartIndex + numHotseatIcons - 1;
updateHotseatItems(new ItemInfo[numHotseatIcons]);
@@ -135,6 +130,14 @@
mRecentsStartIndex = dividerIndex + 1;
mRecentsEndIndex = mRecentsStartIndex + numRecentIcons - 1;
updateRecentTasks(new Task[numRecentIcons]);
+
+ mLayoutTransition = new LayoutTransition();
+ addUpdateListenerForAllLayoutTransitions(() -> {
+ if (getLayoutTransition() == mLayoutTransition) {
+ mControllerCallbacks.onItemPositionsChanged(this);
+ }
+ });
+ setLayoutTransition(mLayoutTransition);
}
private void addUpdateListenerForAllLayoutTransitions(Runnable onUpdate) {
@@ -159,10 +162,20 @@
}
protected void cleanup() {
+ endAllLayoutTransitionAnimators();
+ setLayoutTransition(null);
removeAllViews();
mHotseatRecentsDivider = null;
}
+ private void endAllLayoutTransitionAnimators() {
+ mLayoutTransition.getAnimator(LayoutTransition.CHANGE_APPEARING).end();
+ mLayoutTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING).end();
+ mLayoutTransition.getAnimator(LayoutTransition.CHANGING).end();
+ mLayoutTransition.getAnimator(LayoutTransition.APPEARING).end();
+ mLayoutTransition.getAnimator(LayoutTransition.DISAPPEARING).end();
+ }
+
/**
* Sets the alpha of the background color behind all the Taskbar contents.
* @param alpha 0 is fully transparent, 1 is fully opaque.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index d8a5f9b..43e70a3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -83,6 +83,11 @@
}
@Override
+ public float getTaskbarScale(Launcher launcher) {
+ return 1f;
+ }
+
+ @Override
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
return new PageAlphaProvider(DEACCEL_2) {
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index 473fe2d..de7be5d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -18,7 +18,6 @@
import static android.view.View.VISIBLE;
import static com.android.launcher3.LauncherState.HINT_STATE;
-import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator;
@@ -33,12 +32,10 @@
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_TASKBAR_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
@@ -82,7 +79,6 @@
if (toState == NORMAL && fromState == OVERVIEW) {
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
- config.setInterpolator(ANIM_TASKBAR_FADE, ACCEL);
config.setInterpolator(ANIM_ALL_APPS_FADE, ACCEL);
config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL);
@@ -141,7 +137,6 @@
config.setInterpolator(ANIM_DEPTH, OVERSHOOT_1_2);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_2);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, OVERSHOOT_1_2);
- config.setInterpolator(ANIM_TASKBAR_FADE, OVERSHOOT_1_2);
} else if (fromState == HINT_STATE && toState == NORMAL) {
config.setInterpolator(ANIM_DEPTH, DEACCEL_3);
if (mHintToNormalDuration == -1) {
@@ -150,17 +145,6 @@
mHintToNormalDuration = (int) va.getDuration();
}
config.duration = Math.max(config.duration, mHintToNormalDuration);
- } else if (mActivity.getTaskbarController() != null) {
- boolean wasHotseatVisible = fromState.areElementsVisible(mActivity, HOTSEAT_ICONS);
- boolean isHotseatVisible = toState.areElementsVisible(mActivity, HOTSEAT_ICONS);
- if (wasHotseatVisible || isHotseatVisible) {
- config.setInterpolator(ANIM_TASKBAR_FADE, INSTANT);
- config.setInterpolator(ANIM_HOTSEAT_FADE, INSTANT);
-
- if (isHotseatVisible) {
- mActivity.getTaskbarController().alignRealHotseatWithTaskbar();
- }
- }
}
}
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index b492825..1a5f9c2 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
-import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
@@ -97,11 +96,12 @@
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.InputConsumerProxy;
+import com.android.quickstep.util.InputProxyHandlerFactory;
import com.android.quickstep.util.MotionPauseDetector;
-import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.ProtoTracer;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.RectFSpringAnim;
+import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.SwipePipToHomeAnimator;
import com.android.quickstep.util.TransformParams;
@@ -113,12 +113,10 @@
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.TaskInfoCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.function.Consumer;
/**
@@ -200,7 +198,7 @@
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED;
public static final long MAX_SWIPE_DURATION = 350;
- public static final long MIN_OVERSHOOT_DURATION = 120;
+ public static final long HOME_DURATION = StaggeredWorkspaceAnim.DURATION_MS;
public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.7f;
private static final float SWIPE_DURATION_MULTIPLIER =
@@ -255,7 +253,10 @@
mActivityInterface = gestureState.getActivityInterface();
mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
mInputConsumerProxy =
- new InputConsumerProxy(inputConsumer, this::createNewInputProxyHandler);
+ new InputConsumerProxy(inputConsumer, () -> {
+ endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
+ endLauncherTransitionController();
+ }, new InputProxyHandlerFactory(mActivityInterface, mGestureState));
mTaskAnimationManager = taskAnimationManager;
mTouchTimeMs = touchTimeMs;
mContinuingLastGesture = continuingLastGesture;
@@ -783,19 +784,6 @@
handleNormalGestureEnd(endVelocity, isFling, velocity, false /* isCancel */);
}
- /**
- * Called to create a input proxy for the running task
- */
- @UiThread
- protected InputConsumer createNewInputProxyHandler() {
- endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
- endLauncherTransitionController();
-
- StatefulActivity activity = mActivityInterface.getCreatedActivity();
- return activity == null ? InputConsumer.NO_OP
- : new OverviewInputConsumer(mGestureState, activity, null, true);
- }
-
private void endRunningWindowAnim(boolean cancel) {
if (mRunningWindowAnim != null) {
if (cancel) {
@@ -923,6 +911,9 @@
float currentShift = mCurrentShift.value;
final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
isFling, isCancel);
+ // Set the state, but don't notify until the animation completes
+ mGestureState.setEndTarget(endTarget, false /* isAtomic */);
+
float endShift = endTarget.isLauncher ? 1 : 0;
final float startShift;
if (!isFling) {
@@ -945,7 +936,7 @@
}
Interpolator interpolator;
S state = mActivityInterface.stateFromGestureEndTarget(endTarget);
- if (state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) {
+ if (state.displayOverviewTasksAsGrid(mDp)) {
interpolator = ACCEL_DEACCEL;
} else if (endTarget == RECENTS) {
interpolator = OVERSHOOT_1_2;
@@ -957,7 +948,7 @@
mInputConsumerProxy.enable();
}
if (endTarget == HOME) {
- duration = Math.max(MIN_OVERSHOOT_DURATION, duration);
+ duration = HOME_DURATION;
} else if (endTarget == RECENTS) {
if (mRecentsView != null) {
int nearestPage = mRecentsView.getDestinationPage();
@@ -1055,8 +1046,6 @@
@UiThread
private void animateToProgressInternal(float start, float end, long duration,
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
- // Set the state, but don't notify until the animation completes
- mGestureState.setEndTarget(target, false /* isAtomic */);
maybeUpdateRecentsAttachedState();
// If we are transitioning to launcher, then listen for the activity to be restarted while
@@ -1147,10 +1136,8 @@
});
animatorSet.play(windowAnim);
S state = mActivityInterface.stateFromGestureEndTarget(mGestureState.getEndTarget());
- if (mRecentsView != null && state.displayOverviewTasksAsGrid(
- mActivity.getDeviceProfile())) {
+ if (mRecentsView != null && state.displayOverviewTasksAsGrid(mDp)) {
animatorSet.play(ObjectAnimator.ofFloat(mRecentsView, RECENTS_GRID_PROGRESS, 1));
- animatorSet.play(mTaskViewSimulator.gridProgress.animateToValue(0, 1));
}
animatorSet.setDuration(duration).setInterpolator(interpolator);
animatorSet.start();
@@ -1339,6 +1326,7 @@
mInputConsumerProxy.destroy();
mTaskAnimationManager.setLiveTileCleanUpHandler(null);
}
+ mInputConsumerProxy.unregisterCallback();
endRunningWindowAnim(false /* cancel */);
if (mGestureEndCallback != null) {
@@ -1503,36 +1491,13 @@
protected abstract void finishRecentsControllerToHome(Runnable callback);
- private final TaskStackChangeListener mLiveTileRestartListener = new TaskStackChangeListener() {
- @Override
- public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
- boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
- if (mRecentsView.getRunningTaskIndex() != -1
- && mRecentsView.getRunningTaskId() == task.taskId
- && mRecentsAnimationTargets.hasTask(task.taskId)) {
- launchOtherTaskInLiveTileMode(task.taskId, mRecentsAnimationTargets.apps);
- }
- ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
- mLiveTileRestartListener);
- }
- };
-
private void setupLauncherUiAfterSwipeUpToRecentsAnimation() {
endLauncherTransitionController();
mActivityInterface.onSwipeUpToRecentsComplete();
mRecentsView.onSwipeUpAnimationSuccess();
if (LIVE_TILE.get()) {
- mTaskAnimationManager.setLaunchOtherTaskInLiveTileModeHandler(
- appearedTaskTarget -> {
- RemoteAnimationTargetCompat[] apps = Arrays.copyOf(
- mRecentsAnimationTargets.apps,
- mRecentsAnimationTargets.apps.length + 1);
- apps[apps.length - 1] = appearedTaskTarget;
- launchOtherTaskInLiveTileMode(appearedTaskTarget.taskId, apps);
- });
mTaskAnimationManager.setLiveTileCleanUpHandler(mInputConsumerProxy::destroy);
- ActivityManagerWrapper.getInstance().registerTaskStackListener(
- mLiveTileRestartListener);
+ mTaskAnimationManager.enableLiveTileRestartListener();
}
SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
@@ -1540,65 +1505,6 @@
reset();
}
- private void launchOtherTaskInLiveTileMode(int taskId, RemoteAnimationTargetCompat[] apps) {
- AnimatorSet anim = new AnimatorSet();
- TaskView taskView = mRecentsView.getTaskView(taskId);
- if (taskView == null || !mRecentsView.isTaskViewVisible(taskView)) {
- // TODO: Refine this animation.
- SurfaceTransactionApplier surfaceApplier =
- new SurfaceTransactionApplier(mActivity.getDragLayer());
- ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
- appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
- appAnimator.setInterpolator(ACCEL_DEACCEL);
- appAnimator.addUpdateListener(new MultiValueUpdateListener() {
- @Override
- public void onUpdate(float percent) {
- SurfaceParams.Builder builder = new SurfaceParams.Builder(
- apps[apps.length - 1].leash);
- Matrix matrix = new Matrix();
- matrix.postScale(percent, percent);
- matrix.postTranslate(mDp.widthPx * (1 - percent) / 2,
- mDp.heightPx * (1 - percent) / 2);
- builder.withAlpha(percent).withMatrix(matrix);
- surfaceApplier.scheduleApply(builder.build());
- }
- });
- anim.play(appAnimator);
- } else {
- TaskViewUtils.composeRecentsLaunchAnimator(
- anim, taskView, apps,
- mRecentsAnimationTargets.wallpapers, true /* launcherClosing */,
- mActivity.getStateManager(), mRecentsView,
- mActivityInterface.getDepthController());
- }
- anim.addListener(new AnimatorListenerAdapter(){
-
- @Override
- public void onAnimationEnd(Animator animator) {
- cleanUp(false);
- }
-
- @Override
- public void onAnimationCancel(Animator animator) {
- cleanUp(true);
- }
-
- private void cleanUp(boolean canceled) {
- if (mRecentsAnimationController != null) {
- mRecentsAnimationController.finish(false /* toRecents */,
- null /* onFinishComplete */);
- if (canceled) {
- mRecentsAnimationController = null;
- } else {
- mActivityInterface.onLaunchTaskSuccess();
- }
- ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
- }
- }
- });
- anim.start();
- }
-
private static boolean isNotInRecents(RemoteAnimationTargetCompat app) {
return app.isNotInRecents
|| app.activityType == ACTIVITY_TYPE_HOME;
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 5942b3a..0415009 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -31,6 +31,7 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.view.Gravity;
@@ -43,6 +44,7 @@
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
@@ -195,41 +197,53 @@
}
/**
- * Calculates the taskView size for the provided device configuration
+ * Calculates the taskView size for the provided device configuration.
*/
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
PagedOrientationHandler orientedState) {
Resources res = context.getResources();
+ if (dp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
+ Rect gridRect = new Rect();
+ calculateGridSize(context, dp, gridRect);
- int taskMargin = res.getDimensionPixelSize(R.dimen.overview_task_margin);
- int taskIconAndMargin = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size)
- + res.getDimensionPixelSize(R.dimen.task_icon_top_margin);
- int proactiveRowAndMargin = res.getDimensionPixelSize(R.dimen.overview_proactive_row_height)
- + res.getDimensionPixelSize(R.dimen.overview_proactive_row_bottom_margin);
+ int rowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
+ float rowHeight = (gridRect.height() - rowSpacing) / 2f;
- calculateTaskSizeInternal(context, dp,
- taskIconAndMargin + taskMargin,
- proactiveRowAndMargin + getOverviewActionsHeight(context) + taskMargin,
- res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
- outRect);
+ PointF taskDimension = getTaskDimension(context, dp);
+ float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / Math.max(
+ taskDimension.x, taskDimension.y);
+ int outWidth = Math.round(scale * taskDimension.x);
+ int outHeight = Math.round(scale * taskDimension.y);
+
+ int gravity = Gravity.TOP;
+ gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
+ gridRect.inset(0, dp.overviewTaskThumbnailTopMarginPx, 0, 0);
+ Gravity.apply(gravity, outWidth, outHeight, gridRect, outRect);
+ } else {
+ int taskMargin = dp.overviewTaskMarginPx;
+ int proactiveRowAndMargin;
+ if (dp.isVerticalBarLayout()) {
+ // In Vertical Bar Layout the proactive row doesn't have its own space, it's inside
+ // the actions row.
+ proactiveRowAndMargin = 0;
+ } else {
+ proactiveRowAndMargin = res.getDimensionPixelSize(
+ R.dimen.overview_proactive_row_height)
+ + res.getDimensionPixelSize(R.dimen.overview_proactive_row_bottom_margin);
+ }
+ calculateTaskSizeInternal(context, dp,
+ dp.overviewTaskThumbnailTopMarginPx,
+ proactiveRowAndMargin + getOverviewActionsHeight(context) + taskMargin,
+ res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
+ outRect);
+ }
}
private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
int claimedSpaceAbove, int claimedSpaceBelow, int minimumHorizontalPadding,
Rect outRect) {
- float taskWidth, taskHeight;
+ PointF taskDimension = getTaskDimension(context, dp);
Rect insets = dp.getInsets();
- if (dp.isMultiWindowMode) {
- WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
- taskWidth = bounds.availableSize.x;
- taskHeight = bounds.availableSize.y;
- } else if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
- taskWidth = dp.availableWidthPx;
- taskHeight = dp.availableHeightPx;
- } else {
- taskWidth = dp.widthPx;
- taskHeight = dp.heightPx;
- }
Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
@@ -240,14 +254,30 @@
claimedSpaceBelow);
float scale = Math.min(
- potentialTaskRect.width() / taskWidth,
- potentialTaskRect.height() / taskHeight);
- int outWidth = Math.round(scale * taskWidth);
- int outHeight = Math.round(scale * taskHeight);
+ potentialTaskRect.width() / taskDimension.x,
+ potentialTaskRect.height() / taskDimension.y);
+ int outWidth = Math.round(scale * taskDimension.x);
+ int outHeight = Math.round(scale * taskDimension.y);
Gravity.apply(Gravity.CENTER, outWidth, outHeight, potentialTaskRect, outRect);
}
+ private PointF getTaskDimension(Context context, DeviceProfile dp) {
+ PointF dimension = new PointF();
+ if (dp.isMultiWindowMode) {
+ WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
+ dimension.x = bounds.availableSize.x;
+ dimension.y = bounds.availableSize.y;
+ } else if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
+ dimension.x = dp.availableWidthPx;
+ dimension.y = dp.availableHeightPx;
+ } else {
+ dimension.x = dp.widthPx;
+ dimension.y = dp.heightPx;
+ }
+ return dimension;
+ }
+
/**
* Calculates the overview grid size for the provided device configuration.
*/
@@ -267,13 +297,11 @@
* Calculates the modal taskView size for the provided device configuration
*/
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
- Resources res = context.getResources();
calculateTaskSizeInternal(
context, dp,
- res.getDimensionPixelSize(R.dimen.overview_task_margin),
- getOverviewActionsHeight(context)
- + res.getDimensionPixelSize(R.dimen.overview_task_margin),
- res.getDimensionPixelSize(R.dimen.overview_task_margin),
+ dp.overviewTaskMarginPx,
+ getOverviewActionsHeight(context) + dp.overviewTaskMarginPx,
+ dp.overviewTaskMarginPx,
outRect);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
index da0a664..718c5ba 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
@@ -41,13 +41,4 @@
public boolean hasTargets() {
return unfilteredApps.length != 0;
}
-
- public boolean hasTask(int taskId) {
- for (RemoteAnimationTargetCompat target : unfilteredApps) {
- if (target.taskId == taskId) {
- return true;
- }
- }
- return false;
- }
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 9a454f2..b6dad2d 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -17,10 +17,11 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
+import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -31,13 +32,13 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
+import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.RemoteTransitionCompat;
-
-import java.util.function.Consumer;
+import com.android.systemui.shared.system.TaskStackChangeListener;
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
public static final boolean ENABLE_SHELL_TRANSITIONS =
@@ -49,10 +50,24 @@
// Temporary until we can hook into gesture state events
private GestureState mLastGestureState;
private RemoteAnimationTargetCompat mLastAppearedTaskTarget;
- private Consumer<RemoteAnimationTargetCompat> mLaunchOtherTaskHandler;
private Runnable mLiveTileCleanUpHandler;
private Context mCtx;
+ private final TaskStackChangeListener mLiveTileRestartListener = new TaskStackChangeListener() {
+ @Override
+ public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+ boolean homeTaskVisible, boolean clearedTask, boolean wasVisible) {
+ BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
+ if (LIVE_TILE.get() && activityInterface.isInLiveTileMode()
+ && activityInterface.getCreatedActivity() != null) {
+ RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
+ recentsView.launchSideTaskInLiveTileModeForRestartedApp(task.taskId);
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
+ mLiveTileRestartListener);
+ }
+ }
+ };
+
TaskAnimationManager(Context ctx) {
mCtx = ctx;
}
@@ -114,9 +129,14 @@
@Override
public void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
- if (mLaunchOtherTaskHandler != null
- && mLastGestureState.getEndTarget() == RECENTS) {
- mLaunchOtherTaskHandler.accept(appearedTaskTarget);
+ BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
+ if (LIVE_TILE.get() && activityInterface.isInLiveTileMode()
+ && activityInterface.getCreatedActivity() != null) {
+ RecentsView recentsView =
+ activityInterface.getCreatedActivity().getOverviewPanel();
+ RemoteAnimationTargetCompat[] apps = new RemoteAnimationTargetCompat[1];
+ apps[0] = appearedTaskTarget;
+ recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId, apps);
return;
}
if (mController != null) {
@@ -161,17 +181,12 @@
return mCallbacks;
}
- /**
- * The passed-in handler is used to render side task launch animation in recents in live tile
- * mode.
- */
- public void setLaunchOtherTaskInLiveTileModeHandler(
- Consumer<RemoteAnimationTargetCompat> handler) {
- mLaunchOtherTaskHandler = handler;
+ public void setLiveTileCleanUpHandler(Runnable cleanUpHandler) {
+ mLiveTileCleanUpHandler = cleanUpHandler;
}
- public void setLiveTileCleanUpHandler(Runnable runnable) {
- mLiveTileCleanUpHandler = runnable;
+ public void enableLiveTileRestartListener() {
+ ActivityManagerWrapper.getInstance().registerTaskStackListener(mLiveTileRestartListener);
}
/**
@@ -215,6 +230,7 @@
mLiveTileCleanUpHandler.run();
mLiveTileCleanUpHandler = null;
}
+ ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mLiveTileRestartListener);
// Release all the target leashes
if (mTargets != null) {
@@ -231,7 +247,6 @@
mTargets = null;
mLastGestureState = null;
mLastAppearedTaskTarget = null;
- mLaunchOtherTaskHandler = null;
}
public void dump() {
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index cd13200..1ad5f2c 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -176,7 +176,7 @@
if (thumbnail != null) {
getActionsView().updateDisabledFlags(DISABLED_ROTATED, rotated);
- boolean isAllowedByPolicy = thumbnail.isRealSnapshot;
+ boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot();
getActionsView().setCallbacks(new OverlayUICallbacksImpl(isAllowedByPolicy, task));
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 7a428ce..79db842 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
+import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
@@ -200,8 +201,7 @@
tsv.setPreview(targets.apps[targets.apps.length - 1]);
tsv.fullScreenProgress.value = 0;
tsv.recentsViewScale.value = 1;
- tsv.gridProgress.value = gridProgress;
- tsv.gridTranslationSecondary.value = gridTranslationSecondary;
+ tsv.taskSecondaryTranslation.value = gridTranslationSecondary;
tsv.setScroll(startScroll);
// Fade in the task during the initial 20% of the animation
@@ -214,7 +214,8 @@
AnimatedFloat.VALUE, 1, TOUCH_RESPONSE_INTERPOLATOR);
out.setFloat(tsv.recentsViewScale,
AnimatedFloat.VALUE, tsv.getFullScreenScale(), TOUCH_RESPONSE_INTERPOLATOR);
- out.setFloat(tsv.gridProgress, AnimatedFloat.VALUE, 0, TOUCH_RESPONSE_INTERPOLATOR);
+ out.setFloat(tsv.taskSecondaryTranslation, AnimatedFloat.VALUE, 0,
+ TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL);
out.setInt(tsv, TaskViewSimulator.SCROLL, 0, TOUCH_RESPONSE_INTERPOLATOR);
TaskViewSimulator finalTsv = tsv;
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 161e015..a1b7e01 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -36,9 +36,8 @@
Integer getTitleStringId() {
switch (mTutorialType) {
case RIGHT_EDGE_BACK_NAVIGATION:
- return R.string.back_gesture_tutorial_playground_title_swipe_inward_right_edge;
case LEFT_EDGE_BACK_NAVIGATION:
- return R.string.back_gesture_tutorial_playground_title_swipe_inward_left_edge;
+ return R.string.back_gesture_intro_title;
case BACK_NAVIGATION_COMPLETE:
return R.string.gesture_tutorial_confirm_title;
}
@@ -49,9 +48,8 @@
Integer getSubtitleStringId() {
switch (mTutorialType) {
case RIGHT_EDGE_BACK_NAVIGATION:
- return R.string.back_gesture_tutorial_engaged_subtitle_swipe_inward_right_edge;
case LEFT_EDGE_BACK_NAVIGATION:
- return R.string.back_gesture_tutorial_engaged_subtitle_swipe_inward_left_edge;
+ return R.string.back_gesture_intro_subtitle;
case BACK_NAVIGATION_COMPLETE:
return R.string.back_gesture_tutorial_confirm_subtitle;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 95352d1..fbf3a0a 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -38,7 +38,7 @@
Integer getTitleStringId() {
switch (mTutorialType) {
case HOME_NAVIGATION:
- return R.string.home_gesture_tutorial_playground_title;
+ return R.string.home_gesture_intro_title;
case HOME_NAVIGATION_COMPLETE:
return R.string.gesture_tutorial_confirm_title;
}
@@ -48,7 +48,7 @@
@Override
Integer getSubtitleStringId() {
if (mTutorialType == TutorialType.HOME_NAVIGATION) {
- return R.string.home_gesture_tutorial_playground_subtitle;
+ return R.string.home_gesture_intro_subtitle;
}
return null;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 45cbd0b..31f26d1 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -39,7 +39,7 @@
Integer getTitleStringId() {
switch (mTutorialType) {
case OVERVIEW_NAVIGATION:
- return R.string.overview_gesture_tutorial_playground_title;
+ return R.string.overview_gesture_intro_title;
case OVERVIEW_NAVIGATION_COMPLETE:
return R.string.gesture_tutorial_confirm_title;
}
@@ -49,7 +49,7 @@
@Override
Integer getSubtitleStringId() {
if (mTutorialType == TutorialType.OVERVIEW_NAVIGATION) {
- return R.string.overview_gesture_tutorial_playground_subtitle;
+ return R.string.overview_gesture_intro_subtitle;
}
return null;
}
diff --git a/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java b/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java
index 3e87f48..2e5b33a 100644
--- a/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java
+++ b/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java
@@ -38,7 +38,8 @@
private static final String TAG = "InputConsumerProxy";
private final InputConsumerController mInputConsumerController;
- private final Supplier<InputConsumer> mConsumerSupplier;
+ private Runnable mCallback;
+ private Supplier<InputConsumer> mConsumerSupplier;
// The consumer is created lazily on demand.
private InputConsumer mInputConsumer;
@@ -48,8 +49,9 @@
private boolean mDestroyPending = false;
public InputConsumerProxy(InputConsumerController inputConsumerController,
- Supplier<InputConsumer> consumerSupplier) {
+ Runnable callback, Supplier<InputConsumer> consumerSupplier) {
mInputConsumerController = inputConsumerController;
+ mCallback = callback;
mConsumerSupplier = consumerSupplier;
}
@@ -64,9 +66,7 @@
if (ev instanceof MotionEvent) {
onInputConsumerMotionEvent((MotionEvent) ev);
} else if (ev instanceof KeyEvent) {
- if (mInputConsumer == null) {
- mInputConsumer = mConsumerSupplier.get();
- }
+ initInputConsumerIfNeeded();
mInputConsumer.onKeyEvent((KeyEvent) ev);
return true;
}
@@ -89,9 +89,7 @@
if (action == ACTION_DOWN) {
mTouchInProgress = true;
- if (mInputConsumer == null) {
- mInputConsumer = mConsumerSupplier.get();
- }
+ initInputConsumerIfNeeded();
} else if (action == ACTION_CANCEL || action == ACTION_UP) {
// Finish any pending actions
mTouchInProgress = false;
@@ -115,4 +113,18 @@
mDestroyed = true;
mInputConsumerController.setInputListener(null);
}
+
+ public void unregisterCallback() {
+ mCallback = null;
+ }
+
+ private void initInputConsumerIfNeeded() {
+ if (mInputConsumer == null) {
+ if (mCallback != null) {
+ mCallback.run();
+ }
+ mInputConsumer = mConsumerSupplier.get();
+ mConsumerSupplier = null;
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/InputProxyHandlerFactory.java b/quickstep/src/com/android/quickstep/util/InputProxyHandlerFactory.java
new file mode 100644
index 0000000..8209c09
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/InputProxyHandlerFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.util;
+
+import androidx.annotation.UiThread;
+
+import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.GestureState;
+import com.android.quickstep.InputConsumer;
+import com.android.quickstep.inputconsumers.OverviewInputConsumer;
+
+import java.util.function.Supplier;
+
+/**
+ * A factory that creates a input consumer for
+ * {@link com.android.quickstep.util.InputConsumerProxy}.
+ */
+public class InputProxyHandlerFactory implements Supplier<InputConsumer> {
+
+ private final BaseActivityInterface mActivityInterface;
+ private final GestureState mGestureState;
+
+ @UiThread
+ public InputProxyHandlerFactory(BaseActivityInterface activityInterface,
+ GestureState gestureState) {
+ mActivityInterface = activityInterface;
+ mGestureState = gestureState;
+ }
+
+ /**
+ * Called to create a input proxy for the running task
+ */
+ @Override
+ public InputConsumer get() {
+ StatefulActivity activity = mActivityInterface.getCreatedActivity();
+ return activity == null ? InputConsumer.NO_OP
+ : new OverviewInputConsumer(mGestureState, activity, null, true);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index 3faf72a..f68e936 100644
--- a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -24,7 +24,6 @@
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 static com.android.launcher3.states.StateAnimationConfig.SKIP_TASKBAR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -61,7 +60,10 @@
public class StaggeredWorkspaceAnim {
private static final int APP_CLOSE_ROW_START_DELAY_MS = 10;
+ // How long it takes to fade in each staggered row.
private static final int ALPHA_DURATION_MS = 250;
+ // Should be used for animations running alongside this StaggeredWorkspaceAnim.
+ public static final int DURATION_MS = 250;
private static final float MAX_VELOCITY_PX_PER_S = 22f;
@@ -83,34 +85,25 @@
DeviceProfile grid = launcher.getDeviceProfile();
Workspace workspace = launcher.getWorkspace();
- CellLayout cellLayout = (CellLayout) workspace.getChildAt(workspace.getCurrentPage());
- ShortcutAndWidgetContainer currentPage = cellLayout.getShortcutsAndWidgets();
Hotseat hotseat = launcher.getHotseat();
+ // Hotseat and QSB takes up two additional rows.
+ int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2);
+
+ // Add animation for all the visible workspace pages
+ workspace.getVisiblePages()
+ .forEach(page -> addAnimationForPage((CellLayout) page, totalRows));
+
boolean workspaceClipChildren = workspace.getClipChildren();
boolean workspaceClipToPadding = workspace.getClipToPadding();
- boolean cellLayoutClipChildren = cellLayout.getClipChildren();
- boolean cellLayoutClipToPadding = cellLayout.getClipToPadding();
boolean hotseatClipChildren = hotseat.getClipChildren();
boolean hotseatClipToPadding = hotseat.getClipToPadding();
workspace.setClipChildren(false);
workspace.setClipToPadding(false);
- cellLayout.setClipChildren(false);
- cellLayout.setClipToPadding(false);
hotseat.setClipChildren(false);
hotseat.setClipToPadding(false);
- // Hotseat and QSB takes up two additional rows.
- int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2);
-
- // Set up springs on workspace items.
- for (int i = currentPage.getChildCount() - 1; i >= 0; i--) {
- View child = currentPage.getChildAt(i);
- CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams());
- addStaggeredAnimationForView(child, lp.cellY + lp.cellVSpan, totalRows);
- }
-
// Set up springs for the hotseat and qsb.
ViewGroup hotseatIcons = hotseat.getShortcutsAndWidgets();
if (grid.isVerticalBarLayout()) {
@@ -141,35 +134,57 @@
}
if (animateOverviewScrim) {
- PendingAnimation pendingAnimation = new PendingAnimation(ALPHA_DURATION_MS);
+ PendingAnimation pendingAnimation = new PendingAnimation(DURATION_MS);
addScrimAnimationForState(launcher, NORMAL, pendingAnimation);
mAnimators.play(pendingAnimation.buildAnim());
}
- addDepthAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
+ addDepthAnimationForState(launcher, NORMAL, DURATION_MS);
mAnimators.play(launcher.getDragLayer().getSysUiScrim().createSysuiMultiplierAnim(0f, 1f)
- .setDuration(ALPHA_DURATION_MS));
+ .setDuration(DURATION_MS));
mAnimators.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
workspace.setClipChildren(workspaceClipChildren);
workspace.setClipToPadding(workspaceClipToPadding);
- cellLayout.setClipChildren(cellLayoutClipChildren);
- cellLayout.setClipToPadding(cellLayoutClipToPadding);
hotseat.setClipChildren(hotseatClipChildren);
hotseat.setClipToPadding(hotseatClipToPadding);
}
});
}
+ private void addAnimationForPage(CellLayout page, int totalRows) {
+ ShortcutAndWidgetContainer itemsContainer = page.getShortcutsAndWidgets();
+
+ boolean pageClipChildren = page.getClipChildren();
+ boolean pageClipToPadding = page.getClipToPadding();
+
+ page.setClipChildren(false);
+ page.setClipToPadding(false);
+
+ // Set up springs on workspace items.
+ for (int i = itemsContainer.getChildCount() - 1; i >= 0; i--) {
+ View child = itemsContainer.getChildAt(i);
+ CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams());
+ addStaggeredAnimationForView(child, lp.cellY + lp.cellVSpan, totalRows);
+ }
+
+ mAnimators.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ page.setClipChildren(pageClipChildren);
+ page.setClipToPadding(pageClipToPadding);
+ }
+ });
+ }
+
/**
* Setup workspace with 0 duration to prepare for our staggered animation.
*/
private void prepareToAnimate(Launcher launcher, boolean animateOverviewScrim) {
StateAnimationConfig config = new StateAnimationConfig();
- config.animFlags = ANIM_ALL_COMPONENTS | SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER
- | SKIP_TASKBAR;
+ 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/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 8b5d498..6cfe302 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -15,7 +15,6 @@
*/
package com.android.quickstep.util;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.states.RotationHelper.deltaRotation;
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
import static com.android.quickstep.util.NavigationModeFeatureFlag.LIVE_TILE;
@@ -36,7 +35,6 @@
import androidx.annotation.NonNull;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.touch.PagedOrientationHandler;
@@ -79,7 +77,6 @@
private final boolean mIsRecentsRtl;
private final Rect mTaskRect = new Rect();
- private final Rect mGridRect = new Rect();
private boolean mDrawsBelowRecents;
private final PointF mPivot = new PointF();
private DeviceProfile mDp;
@@ -98,22 +95,18 @@
private final FullscreenDrawParams mCurrentFullscreenParams;
public final AnimatedFloat taskPrimaryTranslation = new AnimatedFloat();
public final AnimatedFloat taskSecondaryTranslation = new AnimatedFloat();
- public final AnimatedFloat gridTranslationSecondary = new AnimatedFloat();
// RecentsView properties
public final AnimatedFloat recentsViewScale = new AnimatedFloat();
public final AnimatedFloat fullScreenProgress = new AnimatedFloat();
public final AnimatedFloat recentsViewSecondaryTranslation = new AnimatedFloat();
public final AnimatedFloat recentsViewPrimaryTranslation = new AnimatedFloat();
- public final AnimatedFloat gridProgress = new AnimatedFloat();
private final ScrollState mScrollState = new ScrollState();
// Cached calculations
private boolean mLayoutValid = false;
private boolean mScrollValid = false;
private int mOrientationStateId;
- private final int mTaskThumbnailPadding;
- private final int mRowSpacing;
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
mContext = context;
@@ -125,8 +118,6 @@
mOrientationStateId = mOrientationState.getStateId();
Resources resources = context.getResources();
mIsRecentsRtl = mOrientationState.getOrientationHandler().getRecentsRtlSetting(resources);
- mTaskThumbnailPadding = (int) resources.getDimension(R.dimen.task_thumbnail_top_margin);
- mRowSpacing = (int) resources.getDimension(R.dimen.overview_grid_row_spacing);
}
/**
@@ -268,7 +259,6 @@
mOrientationStateId = mOrientationState.getStateId();
getFullScreenScale();
- mSizeStrategy.calculateGridSize(mContext, mDp, mGridRect);
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
// mIsRecentsRtl is the inverse of TaskView RTL.
@@ -309,34 +299,6 @@
mMatrix.postTranslate(insets.left, insets.top);
mMatrix.postScale(scale, scale);
- // Apply TaskView matrix: gridProgress related properties
- float interpolatedGridProgress = ACCEL_DEACCEL.getInterpolation(gridProgress.value);
- final int boxLength = (int) Math.max(taskWidth, taskHeight);
- float availableHeight = mGridRect.height();
- float rowHeight = (availableHeight - mRowSpacing) / 2;
- float gridScale = rowHeight / (boxLength + mTaskThumbnailPadding);
- scale = Utilities.mapRange(interpolatedGridProgress, 1f, gridScale);
- mMatrix.postScale(scale, scale, mIsRecentsRtl ? 0 : taskWidth, 0);
- mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
- Utilities.mapRange(interpolatedGridProgress, 0, gridTranslationSecondary.value));
-
- // Apply TaskView matrix: task rect and grid rect difference
- float scaledWidth = taskWidth * gridScale;
- float taskGridHorizontalDiff;
- if (mIsRecentsRtl) {
- float taskRight = mTaskRect.left + scaledWidth;
- taskGridHorizontalDiff = mGridRect.right - taskRight;
- } else {
- float taskLeft = mTaskRect.right - scaledWidth;
- taskGridHorizontalDiff = mGridRect.left - taskLeft;
- }
- float taskGridVerticalDiff =
- mGridRect.top + mTaskThumbnailPadding * gridScale - mTaskRect.top;
- mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
- Utilities.mapRange(interpolatedGridProgress, 0, taskGridHorizontalDiff));
- mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
- Utilities.mapRange(interpolatedGridProgress, 0, taskGridVerticalDiff));
-
// Apply TaskView matrix: translate, scroll
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index e7101cc..12b59d0 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -21,6 +21,7 @@
import android.util.FloatProperty;
import android.widget.Button;
+import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.views.RecentsView.PageCallbacks;
import com.android.quickstep.views.RecentsView.ScrollState;
@@ -40,30 +41,32 @@
}
};
+ private final StatefulActivity mActivity;
private float mScrollAlpha = 1;
private float mContentAlpha = 1;
private float mVisibilityAlpha = 1;
private float mGridProgress = 1;
private boolean mIsRtl;
- private final float mOriginalTranslationX, mOriginalTranslationY;
private float mNormalTranslationPrimary;
private float mGridTranslationPrimary;
+ private float mGridTranslationSecondary;
+ private float mGridScrollOffset;
+ private float mOffsetTranslationPrimary;
- private int mScrollOffset;
+ private int mSidePadding;
public ClearAllButton(Context context, AttributeSet attrs) {
super(context, attrs);
mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
- mOriginalTranslationX = getTranslationX();
- mOriginalTranslationY = getTranslationY();
+ mActivity = StatefulActivity.fromContext(context);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
PagedOrientationHandler orientationHandler = getRecentsView().getPagedOrientationHandler();
- mScrollOffset = orientationHandler.getClearAllScrollOffset(getRecentsView(), mIsRtl);
+ mSidePadding = orientationHandler.getClearAllSidePadding(getRecentsView(), mIsRtl);
}
private RecentsView getRecentsView() {
@@ -96,25 +99,27 @@
}
@Override
- public void onPageScroll(ScrollState scrollState) {
- PagedOrientationHandler orientationHandler = getRecentsView().getPagedOrientationHandler();
+ public void onPageScroll(ScrollState scrollState, boolean gridEnabled) {
+ RecentsView recentsView = getRecentsView();
+ if (recentsView == null) {
+ return;
+ }
+
+ PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
float orientationSize = orientationHandler.getPrimaryValue(getWidth(), getHeight());
if (orientationSize == 0) {
return;
}
- float shift;
- if (mIsRtl) {
- shift = Math.min(scrollState.scrollFromEdge, orientationSize);
- } else {
- shift = Math.min(scrollState.scrollFromEdge,
- orientationSize + getGridTrans(mGridTranslationPrimary))
- - getGridTrans(mGridTranslationPrimary);
+ int leftEdgeScroll = recentsView.getLeftMostChildScroll();
+ float adjustedScrollFromEdge = scrollState.scrollFromEdge - leftEdgeScroll;
+ float shift = Math.min(adjustedScrollFromEdge, orientationSize);
+ mNormalTranslationPrimary = mIsRtl ? -shift : shift;
+ if (!gridEnabled) {
+ mNormalTranslationPrimary += mSidePadding;
}
- mNormalTranslationPrimary = mIsRtl ? (mScrollOffset - shift) : (mScrollOffset + shift);
applyPrimaryTranslation();
- orientationHandler.getSecondaryViewTranslate().set(this,
- orientationHandler.getSecondaryValue(mOriginalTranslationX, mOriginalTranslationY));
+ applySecondaryTranslation();
mScrollAlpha = 1 - shift / orientationSize;
updateAlpha();
}
@@ -130,11 +135,26 @@
applyPrimaryTranslation();
}
+ public void setGridTranslationSecondary(float gridTranslationSecondary) {
+ mGridTranslationSecondary = gridTranslationSecondary;
+ applyPrimaryTranslation();
+ }
+
+ public void setGridScrollOffset(float gridScrollOffset) {
+ mGridScrollOffset = gridScrollOffset;
+ }
+
+ public void setOffsetTranslationPrimary(float offsetTranslationPrimary) {
+ mOffsetTranslationPrimary = offsetTranslationPrimary;
+ applyPrimaryTranslation();
+ }
+
public float getScrollAdjustment(boolean gridEnabled) {
float scrollAdjustment = 0;
if (gridEnabled) {
- scrollAdjustment += mGridTranslationPrimary;
+ scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset;
}
+ scrollAdjustment += mOffsetTranslationPrimary;
return scrollAdjustment;
}
@@ -160,10 +180,31 @@
PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
orientationHandler.getPrimaryViewTranslate().set(this,
- mNormalTranslationPrimary + getGridTrans(mGridTranslationPrimary));
+ orientationHandler.getPrimaryValue(0f, getOriginalTranslationY())
+ + mNormalTranslationPrimary + mOffsetTranslationPrimary + getGridTrans(
+ mGridTranslationPrimary));
+ }
+
+ private void applySecondaryTranslation() {
+ RecentsView recentsView = getRecentsView();
+ if (recentsView == null) {
+ return;
+ }
+
+ PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
+ orientationHandler.getSecondaryViewTranslate().set(this,
+ orientationHandler.getSecondaryValue(0f, getOriginalTranslationY())
+ + getGridTrans(mGridTranslationSecondary));
}
private float getGridTrans(float endTranslation) {
return mGridProgress > 0 ? endTranslation : 0;
}
+
+ /**
+ * Get the Y translation that is set in the original layout position, before scrolling.
+ */
+ private float getOriginalTranslationY() {
+ return mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx / 2.0f;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 1241982..6fcd54c 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -29,6 +29,7 @@
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.util.MultiValueAlpha;
@@ -144,6 +145,7 @@
public void setInsets(Rect insets) {
mInsets.set(insets);
updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
+ updateHorizontalPadding();
}
public void updateHiddenFlags(@ActionsHiddenFlags int visibilityFlags, boolean enable) {
@@ -187,6 +189,10 @@
return mMultiValueAlpha.getProperty(INDEX_FULLSCREEN_ALPHA);
}
+ private void updateHorizontalPadding() {
+ setPadding(mInsets.left, 0, mInsets.right, 0);
+ }
+
/** Updates vertical margins for different navigation mode or configuration changes. */
public void updateVerticalMargin(Mode mode) {
LayoutParams actionParams = (LayoutParams) findViewById(
@@ -196,6 +202,13 @@
getBottomVerticalMargin(mode));
}
+ /**
+ * Set the device profile for this view to draw with.
+ */
+ public void setDp(DeviceProfile dp) {
+ requestLayout();
+ }
+
protected int getBottomVerticalMargin(Mode mode) {
int bottomMargin;
int orientation = getResources().getConfiguration().orientation;
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 4d8176c..7693440 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -27,6 +27,7 @@
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
+import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.Utilities.squaredHypot;
@@ -34,6 +35,7 @@
import static com.android.launcher3.anim.Interpolators.ACCEL;
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.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
@@ -50,6 +52,7 @@
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
import android.animation.LayoutTransition.TransitionListener;
@@ -61,6 +64,7 @@
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -129,8 +133,11 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskThumbnailCache;
+import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.ViewUtils;
+import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.LayoutUtils;
+import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitScreenBounds;
import com.android.quickstep.util.SurfaceTransactionApplier;
@@ -142,6 +149,8 @@
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.PackageManagerWrapper;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.wm.shell.pip.IPipAnimationListener;
@@ -301,6 +310,7 @@
protected final Rect mTempRect = new Rect();
protected final RectF mTempRectF = new RectF();
private final PointF mTempPointF = new PointF();
+ private float mFullscreenScale;
private static final int DISMISS_TASK_DURATION = 300;
private static final int ADDITION_TASK_DURATION = 200;
@@ -310,7 +320,6 @@
protected final T mActivity;
private final float mFastFlingVelocity;
private final RecentsModel mModel;
- private final int mTaskTopMargin;
private final int mRowSpacing;
private final ClearAllButton mClearAllButton;
private final Rect mClearAllButtonDeadZoneRect = new Rect();
@@ -529,8 +538,6 @@
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
- mTaskTopMargin = getResources()
- .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
mRowSpacing = getResources().getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
mSquaredTouchSlop = squaredTouchSlop(context);
@@ -717,6 +724,72 @@
super.draw(canvas);
}
+ public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
+ if (mRunningTaskId != -1 && mRunningTaskId == taskId &&
+ getLiveTileParams().getTargetSet().findTask(taskId) != null) {
+ launchSideTaskInLiveTileMode(taskId, getLiveTileParams().getTargetSet().apps);
+ }
+ }
+
+ public void launchSideTaskInLiveTileMode(int taskId, RemoteAnimationTargetCompat[] apps) {
+ AnimatorSet anim = new AnimatorSet();
+ TaskView taskView = getTaskView(taskId);
+ if (taskView == null || !isTaskViewVisible(taskView)) {
+ // TODO: Refine this animation.
+ SurfaceTransactionApplier surfaceApplier =
+ new SurfaceTransactionApplier(mActivity.getDragLayer());
+ ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
+ appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
+ appAnimator.setInterpolator(ACCEL_DEACCEL);
+ appAnimator.addUpdateListener(new MultiValueUpdateListener() {
+ @Override
+ public void onUpdate(float percent) {
+ SurfaceParams.Builder builder = new SurfaceParams.Builder(
+ apps[apps.length - 1].leash);
+ Matrix matrix = new Matrix();
+ matrix.postScale(percent, percent);
+ matrix.postTranslate(mActivity.getDeviceProfile().widthPx * (1 - percent) / 2,
+ mActivity.getDeviceProfile().heightPx * (1 - percent) / 2);
+ builder.withAlpha(percent).withMatrix(matrix);
+ surfaceApplier.scheduleApply(builder.build());
+ }
+ });
+ anim.play(appAnimator);
+ } else {
+ TaskViewUtils.composeRecentsLaunchAnimator(
+ anim, taskView, apps,
+ mLiveTileParams.getTargetSet().wallpapers, true /* launcherClosing */,
+ mActivity.getStateManager(), this,
+ getDepthController());
+ }
+ anim.addListener(new AnimatorListenerAdapter(){
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ cleanUp(false);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animator) {
+ cleanUp(true);
+ }
+
+ private void cleanUp(boolean canceled) {
+ if (mRecentsAnimationController != null) {
+ mRecentsAnimationController.finish(false /* toRecents */,
+ null /* onFinishComplete */);
+ if (canceled) {
+ mRecentsAnimationController = null;
+ } else {
+ mSizeStrategy.onLaunchTaskSuccess();
+ }
+ ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
+ }
+ }
+ });
+ anim.start();
+ }
+
private void updateTaskStartIndex(View affectingView) {
if (!(affectingView instanceof TaskView) && !(affectingView instanceof ClearAllButton)) {
int childCount = getChildCount();
@@ -744,7 +817,7 @@
int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment(
mOverviewFullscreenEnabled, showAsGrid());
int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment(
- mOverviewFullscreenEnabled, showAsGrid()));
+ mOverviewFullscreenEnabled));
int taskEnd = taskStart + taskSize;
return (taskStart >= start && taskStart <= end) || (taskEnd >= start
&& taskEnd <= end);
@@ -1022,7 +1095,6 @@
mLiveTileTaskViewSimulator.taskSecondaryTranslation.value = 0;
mLiveTileTaskViewSimulator.fullScreenProgress.value = 0;
mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
- mLiveTileTaskViewSimulator.gridProgress.value = 0;
}
if (mRunningTaskTileHidden) {
setRunningTaskHidden(mRunningTaskTileHidden);
@@ -1066,7 +1138,9 @@
public void setInsets(Rect insets) {
mInsets.set(insets);
resetPaddingFromTaskSize();
- mLiveTileTaskViewSimulator.setDp(mActivity.getDeviceProfile());
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ mLiveTileTaskViewSimulator.setDp(dp);
+ mActionsView.setDp(dp);
}
private void resetPaddingFromTaskSize() {
@@ -1075,7 +1149,7 @@
mTaskWidth = mTempRect.width();
mTaskHeight = mTempRect.height();
- mTempRect.top -= mTaskTopMargin;
+ mTempRect.top -= dp.overviewTaskThumbnailTopMarginPx;
setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
dp.widthPx - mInsets.right - mTempRect.right,
dp.heightPx - mInsets.bottom - mTempRect.bottom);
@@ -1092,6 +1166,10 @@
*/
private void updateTaskSize() {
final int taskCount = getTaskViewCount();
+ if (taskCount == 0) {
+ return;
+ }
+
float accumulatedTranslationX = 0;
float[] fullscreenTranslations = new float[taskCount];
int firstNonHomeTaskIndex = 0;
@@ -1106,8 +1184,11 @@
taskView.updateTaskSize();
fullscreenTranslations[i] += accumulatedTranslationX;
+ // Compensate space caused by TaskView scaling.
float widthDiff =
taskView.getLayoutParams().width * (1 - taskView.getFullscreenScale());
+ // Compensate page spacing widening caused by RecentsView scaling.
+ widthDiff += mPageSpacing * (1 - 1 / mFullscreenScale);
float fullscreenTranslationX = mIsRtl ? widthDiff : -widthDiff;
fullscreenTranslations[i] += fullscreenTranslationX;
accumulatedTranslationX += fullscreenTranslationX;
@@ -1181,13 +1262,13 @@
View page = getPageAt(i);
mScrollState.updateInterpolation(mActivity.getDeviceProfile(),
mOrientationHandler.getChildStartWithTranslation(page));
- ((PageCallbacks) page).onPageScroll(mScrollState);
+ ((PageCallbacks) page).onPageScroll(mScrollState, mOverviewGridEnabled);
}
}
@Override
protected int getDestinationPage(int scaledScroll) {
- if (mGridProgress == 0) {
+ if (!showAsGrid()) {
return super.getDestinationPage(scaledScroll);
}
@@ -1600,10 +1681,7 @@
}
final int boxLength = Math.max(mTaskWidth, mTaskHeight);
- float availableHeight = mLastComputedGridSize.height();
- float rowHeight = (availableHeight - mRowSpacing) / 2;
- float gridScale = rowHeight / (boxLength + mTaskTopMargin);
-
+ int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
int topRowWidth = 0;
int bottomRowWidth = 0;
float topAccumulatedTranslationX = 0;
@@ -1621,43 +1699,17 @@
continue;
}
- taskView.setGridScale(gridScale);
-
- float scaledWidth = taskView.getLayoutParams().width * gridScale;
- float taskGridHorizontalDiff;
- if (mIsRtl) {
- float taskRight = mLastComputedTaskSize.left + scaledWidth;
- taskGridHorizontalDiff = mLastComputedGridSize.right - taskRight;
- } else {
- float taskLeft = mLastComputedTaskSize.right - scaledWidth;
- taskGridHorizontalDiff = mLastComputedGridSize.left - taskLeft;
- }
- gridTranslations[i] -= taskGridHorizontalDiff;
- taskView.setGridOffsetTranslationX(taskGridHorizontalDiff);
-
- float taskGridVerticalDiff = mLastComputedGridSize.top + mTaskTopMargin * gridScale
- - mLastComputedTaskSize.top;
-
- // Off-set gap due to task scaling.
- float widthDiff = taskView.getLayoutParams().width * (1 - gridScale);
- float gridScaleTranslationX = mIsRtl ? widthDiff : -widthDiff;
- gridTranslations[i] += gridScaleTranslationX;
-
- // Visible offset caused by having scaling pivot on top-right.
- taskView.setNonRtlVisibleOffset(mIsRtl ? 0 : widthDiff);
-
if (topRowWidth <= bottomRowWidth) {
gridTranslations[i] += topAccumulatedTranslationX;
- topRowWidth += taskView.getLayoutParams().width * gridScale + mPageSpacing;
+ topRowWidth += taskView.getLayoutParams().width + mPageSpacing;
topSet.add(i);
- taskView.setGridTranslationY(taskGridVerticalDiff);
+ taskView.setGridTranslationY(0);
// Move horizontally into empty space.
float widthOffset = 0;
for (int j = i - 1; bottomSet.contains(j); j--) {
- widthOffset += getTaskViewAt(j).getLayoutParams().width * gridScale
- + mPageSpacing;
+ widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
@@ -1665,26 +1717,39 @@
topAccumulatedTranslationX += gridTranslationX;
} else {
gridTranslations[i] += bottomAccumulatedTranslationX;
- bottomRowWidth += taskView.getLayoutParams().width * gridScale + mPageSpacing;
+ bottomRowWidth += taskView.getLayoutParams().width + mPageSpacing;
bottomSet.add(i);
// Move into bottom row.
- float heightOffset = (boxLength + mTaskTopMargin) * gridScale + mRowSpacing;
- taskView.setGridTranslationY(heightOffset + taskGridVerticalDiff);
+ float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
+ taskView.setGridTranslationY(heightOffset);
// Move horizontally into empty space.
float widthOffset = 0;
for (int j = i - 1; topSet.contains(j); j--) {
- widthOffset += getTaskViewAt(j).getLayoutParams().width * gridScale
- + mPageSpacing;
+ widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
float gridTranslationX = mIsRtl ? widthOffset : -widthOffset;
gridTranslations[i] += gridTranslationX;
bottomAccumulatedTranslationX += gridTranslationX;
}
- topAccumulatedTranslationX += gridScaleTranslationX;
- bottomAccumulatedTranslationX += gridScaleTranslationX;
+ }
+
+ // If the first non-home task does not take full width of task Rect, shift all tasks
+ // accordingly without affecting scrolls.
+ int firstTaskWidth = getTaskViewAt(firstNonHomeTaskIndex).getLayoutParams().width;
+ float firstNonHomeTaskOffset = firstTaskWidth == ViewGroup.LayoutParams.MATCH_PARENT ? 0
+ : mTaskWidth - firstTaskWidth;
+ float offsetTranslation = mIsRtl ? firstNonHomeTaskOffset : -firstNonHomeTaskOffset;
+
+ // We need to maintain first non-home task's grid translation at 0, now shift translation
+ // of all the TaskViews to achieve that.
+ for (int i = firstNonHomeTaskIndex; i < taskCount; i++) {
+ TaskView taskView = getTaskViewAt(i);
+ taskView.setGridTranslationX(
+ gridTranslations[i] - gridTranslations[firstNonHomeTaskIndex]);
+ taskView.setGridOffsetTranslationX(offsetTranslation);
}
// Use the accumulated translation of the longer row.
@@ -1700,7 +1765,7 @@
shorterRowCompensation = bottomRowWidth - topRowWidth;
}
} else {
- if (!topSet.contains(taskCount - 1)) {
+ if (bottomSet.contains(taskCount - 1)) {
shorterRowCompensation = topRowWidth - bottomRowWidth;
}
}
@@ -1721,14 +1786,14 @@
clearAllAccumulatedTranslation + clearAllShorterRowCompensation
+ clearAllShortTotalCompensation;
- // We need to maintain first non-home task's grid translation at 0, now shift translation
- // of all the TaskViews to achieve that.
- for (int i = firstNonHomeTaskIndex; i < taskCount; i++) {
- getTaskViewAt(i).setGridTranslationX(
- gridTranslations[i] - gridTranslations[firstNonHomeTaskIndex]);
- }
mClearAllButton.setGridTranslationPrimary(
clearAllTotalTranslationX - gridTranslations[firstNonHomeTaskIndex]);
+ mClearAllButton.setGridTranslationSecondary(
+ boxLength - mTaskHeight / 2f + mRowSpacing / 2f);
+ mClearAllButton.setGridScrollOffset(
+ mIsRtl ? mLastComputedTaskSize.left - mLastComputedGridSize.left
+ : mLastComputedTaskSize.right - mLastComputedGridSize.right);
+ mClearAllButton.setOffsetTranslationPrimary(offsetTranslation);
setGridProgress(mGridProgress);
}
@@ -1753,7 +1818,6 @@
for (int i = 0; i < taskCount; i++) {
getTaskViewAt(i).setGridProgress(gridProgress);
}
- mLiveTileTaskViewSimulator.gridProgress.value = gridProgress;
mClearAllButton.setGridProgress(gridProgress);
}
@@ -1801,8 +1865,10 @@
/**
* Updates the page UI based on scroll params.
+ *
+ * @param gridEnabled whether Overveiw is currently showing as 2 rows grid
*/
- default void onPageScroll(ScrollState scrollState) {}
+ default void onPageScroll(ScrollState scrollState, boolean gridEnabled) {}
}
public static class ScrollState extends CurveProperties {
@@ -2297,7 +2363,7 @@
// Update the pivots such that when the task is scaled, it fills the full page
getTaskSize(mTempRect);
- getPagedViewOrientedState().getFullScreenScaleAndPivot(
+ mFullscreenScale = getPagedViewOrientedState().getFullScreenScaleAndPivot(
mTempRect, mActivity.getDeviceProfile(), mTempPointF);
setPivotX(mTempPointF.x);
setPivotY(mTempPointF.y);
@@ -2485,7 +2551,7 @@
if (child == mSplitHiddenTaskView) {
int left = newScroll[i] + getPaddingStart();
- int topMargin = mSplitHiddenTaskView.getThumbnailTopMargin();
+ int topMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
int top = -mSplitHiddenTaskView.getHeight() - locationOnScreen[1];
mSplitHiddenTaskView.layout(left, top,
left + mSplitHiddenTaskView.getWidth(),
@@ -2858,22 +2924,42 @@
@Override
protected int computeMinScroll() {
if (getTaskViewCount() > 0) {
- if (mDisallowScrollToClearAll) {
+ if (mIsRtl && mDisallowScrollToClearAll) {
// We aren't showing the clear all button,
// so use the leftmost task as the min scroll.
- if (mIsRtl) {
- return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
- }
- return getScrollForPage(mTaskViewStartIndex);
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
}
- if (mIsRtl) {
- return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
- }
- return getScrollForPage(mTaskViewStartIndex);
+ return getLeftMostChildScroll();
}
return super.computeMinScroll();
}
+ /**
+ * Returns page scroll of the left most child.
+ */
+ public int getLeftMostChildScroll() {
+ if (mIsRtl) {
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
+ }
+ return getScrollForPage(mTaskViewStartIndex);
+ }
+
+ @Override
+ protected int computeMaxScroll() {
+ if (getTaskViewCount() > 0) {
+ if (!mIsRtl && mDisallowScrollToClearAll) {
+ // We aren't showing the clear all button,
+ // so use the rightmost task as the min scroll.
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
+ }
+ if (mIsRtl) {
+ return getScrollForPage(mTaskViewStartIndex);
+ }
+ return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
+ }
+ return super.computeMaxScroll();
+ }
+
@Override
protected boolean getPageScrolls(int[] outPageScrolls, boolean layoutChildren,
ComputePageScrollsLogic scrollLogic) {
@@ -2919,26 +3005,7 @@
return super.getChildVisibleSize(index);
}
return (int) (super.getChildVisibleSize(index) * taskView.getSizeAdjustment(
- mOverviewFullscreenEnabled, showAsGrid()));
- }
-
- @Override
- protected int computeMaxScroll() {
- if (getTaskViewCount() > 0) {
- if (mDisallowScrollToClearAll) {
- // We aren't showing the clear all button,
- // so use the rightmost task as the min scroll.
- if (mIsRtl) {
- return getScrollForPage(mTaskViewStartIndex);
- }
- return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)));
- }
- if (mIsRtl) {
- return getScrollForPage(mTaskViewStartIndex);
- }
- return getScrollForPage(indexOfChild(getTaskViewAt(getTaskViewCount() - 1)) + 1);
- }
- return super.computeMaxScroll();
+ mOverviewFullscreenEnabled));
}
public ClearAllButton getClearAllButton() {
@@ -3160,7 +3227,9 @@
MAIN_EXECUTOR.execute(() -> {
// Needed for activities that auto-enter PiP, which will not trigger a remote
// animation to be created
- mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
+ if (mActivity != null) {
+ mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
+ }
});
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index a5b7a5b..a46daf3 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -58,7 +58,6 @@
private static final int REVEAL_OPEN_DURATION = 150;
private static final int REVEAL_CLOSE_DURATION = 100;
- private final float mThumbnailTopMargin;
private BaseDraggingActivity mActivity;
private TextView mTaskName;
private AnimatorSet mOpenCloseAnimator;
@@ -73,7 +72,6 @@
super(context, attrs, defStyleAttr);
mActivity = BaseDraggingActivity.fromContext(context);
- mThumbnailTopMargin = getResources().getDimension(R.dimen.task_thumbnail_top_margin);
setClipToOutline(true);
}
@@ -123,14 +121,15 @@
}
public void setPosition(float x, float y, PagedOrientationHandler pagedOrientationHandler) {
- float adjustedY = y + mThumbnailTopMargin;
+ int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
+ float adjustedY = y + taskTopMargin;
// Changing pivot to make computations easier
// NOTE: Changing the pivots means the rotated view gets rotated about the new pivots set,
// which would render the X and Y position set here incorrect
setPivotX(0);
if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
// In tablet, set pivotY to original position without mThumbnailTopMargin adjustment.
- setPivotY(-mThumbnailTopMargin);
+ setPivotY(-taskTopMargin);
} else {
setPivotY(0);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 2b54f95..af62582 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -440,13 +440,14 @@
}
/**
- * Returns whether the snapshot is real.
+ * Returns whether the snapshot is real. If the device is locked for the user of the task,
+ * the snapshot used will be an app-theme generated snapshot instead of a real snapshot.
*/
public boolean isRealSnapshot() {
if (mThumbnailData == null) {
return false;
}
- return mThumbnailData.isRealSnapshot;
+ return mThumbnailData.isRealSnapshot && !mTask.isLocked;
}
/**
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index a2acab8..d497a96 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -279,7 +279,6 @@
private float mFullscreenProgress;
private float mGridProgress;
private float mFullscreenScale = 1;
- private float mGridScale = 1;
private final FullscreenDrawParams mCurrentFullscreenParams;
private final StatefulActivity mActivity;
@@ -298,7 +297,6 @@
private float mGridTranslationY;
// Offset translation does not affect scroll calculation.
private float mGridOffsetTranslationX;
- private float mNonRtlVisibleOffset;
private ObjectAnimator mIconAndDimAnimator;
private float mIconScaleAnimStartProgress = 0;
@@ -376,7 +374,8 @@
mCurrentFullscreenParams = new FullscreenDrawParams(context);
mDigitalWellBeingToast = new DigitalWellBeingToast(mActivity, this);
- mOutlineProvider = new TaskOutlineProvider(getContext(), mCurrentFullscreenParams);
+ mOutlineProvider = new TaskOutlineProvider(getContext(), mCurrentFullscreenParams,
+ mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx);
setOutlineProvider(mOutlineProvider);
}
@@ -673,17 +672,14 @@
}
}
- public int getThumbnailTopMargin() {
- return (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
- }
-
public void setOrientationState(RecentsOrientedState orientationState) {
PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
- int thumbnailPadding = (int) getResources().getDimension(R.dimen.task_thumbnail_top_margin);
- int taskIconMargin = (int) getResources().getDimension(R.dimen.task_icon_top_margin);
- int taskIconHeight = (int) getResources().getDimension(R.dimen.task_thumbnail_icon_size);
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ int taskIconMargin = deviceProfile.overviewTaskMarginPx;
+ int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
switch (orientationHandler.getRotation()) {
case ROTATION_90:
@@ -694,7 +690,7 @@
break;
case ROTATION_180:
iconParams.gravity = BOTTOM | CENTER_HORIZONTAL;
- iconParams.bottomMargin = -thumbnailPadding;
+ iconParams.bottomMargin = -snapshotParams.topMargin;
iconParams.leftMargin = iconParams.rightMargin = 0;
iconParams.topMargin = taskIconMargin;
break;
@@ -711,8 +707,12 @@
iconParams.topMargin = taskIconMargin;
break;
}
+ mSnapshotView.setLayoutParams(snapshotParams);
+ iconParams.width = iconParams.height = taskIconHeight;
mIconView.setLayoutParams(iconParams);
mIconView.setRotation(orientationHandler.getDegreesRotated());
+ snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ mSnapshotView.setLayoutParams(snapshotParams);
if (mMenuView != null) {
mMenuView.onRotationChanged();
@@ -792,8 +792,8 @@
@Override
public void onRecycle() {
- mFullscreenTranslationX = mGridTranslationX = mGridTranslationY =
- mGridOffsetTranslationX = mBoxTranslationY = mNonRtlVisibleOffset = 0f;
+ mFullscreenTranslationX = mGridTranslationX =
+ mGridTranslationY = mGridOffsetTranslationX = mBoxTranslationY = 0f;
resetViewTransforms();
// Clear any references to the thumbnail (it will be re-read either from the cache or the
// system on next bind)
@@ -803,7 +803,7 @@
}
@Override
- public void onPageScroll(ScrollState scrollState) {
+ public void onPageScroll(ScrollState scrollState, boolean gridEnabled) {
// Don't do anything if it's modal.
if (mModalness > 0) {
return;
@@ -906,11 +906,6 @@
return mFullscreenScale;
}
- public void setGridScale(float gridScale) {
- mGridScale = gridScale;
- applyScale();
- }
-
/**
* Moves TaskView between carousel and 2 row grid.
*
@@ -927,8 +922,6 @@
float scale = 1;
float fullScreenProgress = EXAGGERATED_EASE.getInterpolation(mFullscreenProgress);
scale *= Utilities.mapRange(fullScreenProgress, 1f, mFullscreenScale);
- float gridProgress = ACCEL_DEACCEL.getInterpolation(mGridProgress);
- scale *= Utilities.mapRange(gridProgress, 1f, mGridScale);
setScaleX(scale);
setScaleY(scale);
}
@@ -991,10 +984,6 @@
applyTranslationX();
}
- public void setNonRtlVisibleOffset(float nonRtlVisibleOffset) {
- mNonRtlVisibleOffset = nonRtlVisibleOffset;
- }
-
public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
float scrollAdjustment = 0;
if (fullscreenEnabled) {
@@ -1006,22 +995,19 @@
return scrollAdjustment;
}
- public float getOffsetAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
+ public float getOffsetAdjustment(boolean fullscreenEnabled,boolean gridEnabled) {
float offsetAdjustment = getScrollAdjustment(fullscreenEnabled, gridEnabled);
if (gridEnabled) {
- offsetAdjustment += mGridOffsetTranslationX + mNonRtlVisibleOffset;
+ offsetAdjustment += mGridOffsetTranslationX;
}
return offsetAdjustment;
}
- public float getSizeAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
+ public float getSizeAdjustment(boolean fullscreenEnabled) {
float sizeAdjustment = 1;
if (fullscreenEnabled) {
sizeAdjustment *= mFullscreenScale;
}
- if (gridEnabled) {
- sizeAdjustment *= mGridScale;
- }
return sizeAdjustment;
}
@@ -1083,17 +1069,17 @@
private static final class TaskOutlineProvider extends ViewOutlineProvider {
- private final int mMarginTop;
+ private int mMarginTop;
private FullscreenDrawParams mFullscreenParams;
- TaskOutlineProvider(Context context, FullscreenDrawParams fullscreenParams) {
- mMarginTop = context.getResources().getDimensionPixelSize(
- R.dimen.task_thumbnail_top_margin);
+ TaskOutlineProvider(Context context, FullscreenDrawParams fullscreenParams, int topMargin) {
+ mMarginTop = topMargin;
mFullscreenParams = fullscreenParams;
}
- public void setFullscreenParams(FullscreenDrawParams params) {
+ public void updateParams(FullscreenDrawParams params, int topMargin) {
mFullscreenParams = params;
+ mMarginTop = topMargin;
}
@Override
@@ -1216,7 +1202,9 @@
}
thumbnail.setFullscreenParams(mCurrentFullscreenParams);
- mOutlineProvider.setFullscreenParams(mCurrentFullscreenParams);
+ mOutlineProvider.updateParams(
+ mCurrentFullscreenParams,
+ mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx);
invalidateOutline();
}
@@ -1238,8 +1226,8 @@
void updateTaskSize() {
ViewGroup.LayoutParams params = getLayoutParams();
if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
- final int thumbnailPadding = (int) getResources().getDimension(
- R.dimen.task_thumbnail_top_margin);
+ final int thumbnailPadding =
+ mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
int taskWidth = lastComputedTaskSize.width();
diff --git a/res/drawable/gm_edit_24.xml b/res/drawable/gm_edit_24.xml
new file mode 100644
index 0000000..59a0dc2
--- /dev/null
+++ b/res/drawable/gm_edit_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="?attr/colorControlNormal">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0L3,16.82L3,21h4.18L20.41,7.77c0.79,-0.78 0.79,-2.05 0,-2.83zM6.41,19.06L5,19v-1.36l9.82,-9.82 1.41,1.41 -9.82,9.83z"/>
+</vector>
diff --git a/res/drawable/widget_reconfigure_button_frame.xml b/res/drawable/widget_reconfigure_button_frame.xml
new file mode 100644
index 0000000..37d93ad
--- /dev/null
+++ b/res/drawable/widget_reconfigure_button_frame.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:width="@dimen/widget_reconfigure_button_size"
+ android:height="@dimen/widget_reconfigure_button_size">
+ <shape
+ android:shape="rectangle">
+ <solid android:color="?android:attr/colorAccent" />
+ <corners android:radius="@dimen/widget_reconfigure_button_corner_radius" />
+ </shape>
+ </item>
+ <item
+ android:gravity="center"
+ android:padding="@dimen/widget_reconfigure_button_padding"
+ android:drawable="@drawable/gm_edit_24"
+ android:color="?android:attr/colorPrimary" />
+</layer-list>
diff --git a/res/layout/all_apps_tabs.xml b/res/layout/all_apps_tabs.xml
index c684881..2accd2d 100644
--- a/res/layout/all_apps_tabs.xml
+++ b/res/layout/all_apps_tabs.xml
@@ -26,6 +26,7 @@
android:clipChildren="true"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
+ android:paddingTop="@dimen/all_apps_header_top_padding"
launcher:pageIndicator="@+id/tabs" >
<include layout="@layout/all_apps_rv_layout" />
diff --git a/res/layout/app_widget_resize_frame.xml b/res/layout/app_widget_resize_frame.xml
index 671dbc6..53db5ed 100644
--- a/res/layout/app_widget_resize_frame.xml
+++ b/res/layout/app_widget_resize_frame.xml
@@ -73,5 +73,17 @@
android:src="@drawable/ic_widget_resize_handle"
android:tint="?android:attr/colorAccent" />
+ <ImageButton
+ android:id="@+id/widget_reconfigure_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/widget_reconfigure_button_padding"
+ android:layout_gravity="bottom|end"
+ android:layout_marginBottom="@dimen/widget_reconfigure_button_margin"
+ android:layout_marginEnd="@dimen/widget_reconfigure_button_margin"
+ android:src="@drawable/widget_reconfigure_button_frame"
+ android:background="?android:attr/selectableItemBackground"
+ android:visibility="gone" />
+
</FrameLayout>
</com.android.launcher3.AppWidgetResizeFrame>
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 4078ef4..c1c8f01 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -129,11 +129,10 @@
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
<attr name="dbFile" format="string" />
- <!-- numAllAppsColumns defaults to numColumns, if not specified -->
- <attr name="numAllAppsColumns" format="integer" />
<attr name="defaultLayoutId" format="reference" />
<attr name="demoModeLayoutId" format="reference" />
<attr name="isScalable" format="boolean" />
+ <attr name="devicePaddingId" format="reference" />
</declare-styleable>
@@ -170,6 +169,9 @@
<attr name="allAppsIconSize" format="float" />
<!-- allAppsIconTextSize defaults to iconTextSize, if not specified -->
<attr name="allAppsIconTextSize" format="float" />
+
+ <!-- numAllAppsColumns defaults to GridDisplayOption.numColumns, if not specified -->
+ <attr name="numAllAppsColumns" format="integer" />
</declare-styleable>
<declare-styleable name="CellLayout">
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index cf830c7..1fccdf3 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -56,6 +56,12 @@
<dimen name="resize_frame_background_padding">24dp</dimen>
<dimen name="resize_frame_margin">22dp</dimen>
+ <!-- App widget reconfigure button -->
+ <dimen name="widget_reconfigure_button_corner_radius">14dp</dimen>
+ <dimen name="widget_reconfigure_button_padding">6dp</dimen>
+ <dimen name="widget_reconfigure_button_margin">32dp</dimen>
+ <dimen name="widget_reconfigure_button_size">36dp</dimen>
+
<!-- Fast scroll -->
<dimen name="fastscroll_track_min_width">6dp</dimen>
<dimen name="fastscroll_track_max_width">8dp</dimen>
@@ -286,4 +292,9 @@
<!-- Size of the maximum radius for the enforced rounded rectangles. -->
<dimen name="enforced_rounded_corner_max_radius">16dp</dimen>
+<!-- Overview placeholder to compile in Launcer3 without Quickstep -->
+ <dimen name="task_thumbnail_icon_size">0dp</dimen>
+ <dimen name="task_thumbnail_icon_size_grid">0dp</dimen>
+ <dimen name="overview_task_margin">0dp</dimen>
+
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e5e5db3..1371e91 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -380,9 +380,18 @@
<!--- heading shown when user opens work apps tab while work apps are paused -->
<string name="work_apps_paused_title">Work profile is paused</string>
<!--- body shown when user opens work apps tab while work apps are paused -->
- <string name="work_apps_paused_body">Work apps can\'t send you notifications, use your battery, or access your location</string>
+ <string name="work_apps_paused_body">Work apps can’t send you notifications, use your battery, or access your location</string>
<!-- content description for paused work apps list -->
- <string name="work_apps_paused_content_description">Work profile is paused. Work apps can\’t send you notifications, use your battery, or access your location</string>
+ <string name="work_apps_paused_content_description">Work profile is paused. Work apps can’t send you notifications, use your battery, or access your location</string>
+ <!-- string shown in educational banner about work profile -->
+ <string name="work_apps_paused_edu_banner">Work apps are badged and visible to your IT admin</string>
+ <!-- button string shown to dismiss work tab education -->
+ <string name="work_apps_paused_edu_accept">Got it</string>
+
+ <!-- button string shown pause work profile -->
+ <string name="work_apps_pause_btn_text">Pause work apps</string>
+ <!-- button string shown enable work profile -->
+ <string name="work_apps_enable_btn_text">Turn on</string>
<!-- A hint shown in launcher settings develop options filter box -->
<string name="developer_options_filter_hint">Filter</string>
diff --git a/res/xml/size_limits.xml b/res/xml/size_limits_80x104.xml
similarity index 98%
rename from res/xml/size_limits.xml
rename to res/xml/size_limits_80x104.xml
index ba57014..e11bc5e 100644
--- a/res/xml/size_limits.xml
+++ b/res/xml/size_limits_80x104.xml
@@ -38,7 +38,7 @@
<workspaceBottomPadding
launcher:a="0.50"
launcher:b="0"
- launcher:c="-16dp"/>
+ launcher:c="16dp"/>
<hotseatBottomPadding
launcher:a="0.50"
launcher:b="0"
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
index e1214ff..6b5678c 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
@@ -82,7 +82,7 @@
mTestProfile.numColumns = 5;
mUserHandle = Process.myUserHandle();
mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater, mMockWidgetCache,
- mIconCache, null, null);
+ mIconCache, null, null, null);
mAdapter.registerAdapterDataObserver(mListener);
doAnswer(invocation -> ((ComponentWithLabel) invocation.getArgument(0))
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
index 84a03d5..12a092d 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
@@ -105,7 +105,8 @@
mWidgetPreviewLoader,
mIconCache,
/* iconClickListener= */ view -> {},
- /* iconLongClickListener= */ view -> false);
+ /* iconLongClickListener= */ view -> false,
+ /* searchBarUIHelper= */ null);
mViewHolderBinder = new WidgetsListHeaderViewHolderBinder(
LayoutInflater.from(mTestActivity), mOnHeaderClickListener, widgetsListAdapter);
}
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
index 075c58d..e090341 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
@@ -105,7 +105,8 @@
mWidgetPreviewLoader,
mIconCache,
/* iconClickListener= */ view -> {},
- /* iconLongClickListener= */ view -> false);
+ /* iconLongClickListener= */ view -> false,
+ /* searchBarUIHelper= */ null);
mViewHolderBinder = new WidgetsListSearchHeaderViewHolderBinder(
LayoutInflater.from(mTestActivity), mOnHeaderClickListener, widgetsListAdapter);
}
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
index 0c6e717..0935d1c 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
@@ -111,7 +111,8 @@
mWidgetPreviewLoader,
mIconCache,
/* iconClickListener= */ view -> {},
- /* iconLongClickListener= */ view -> false);
+ /* iconLongClickListener= */ view -> false,
+ /* searchBarUIHelper= */ null);
mViewHolderBinder = new WidgetsListTableViewHolderBinder(
mContext,
LayoutInflater.from(mTestActivity),
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index d894bb4..95cdbdd 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -98,13 +98,6 @@
public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
| TYPE_SNACKBAR | TYPE_WIDGET_RESIZE_FRAME | TYPE_LISTENER;
- // When these types of floating views are open, hide the taskbar hotseat and show the real one.
- public static final int TYPE_REPLACE_TASKBAR_WITH_HOTSEAT = TYPE_FOLDER | TYPE_ACTION_POPUP;
-
- // Hide the taskbar when these types of floating views are open.
- public static final int TYPE_HIDE_TASKBAR = TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGETS_FULL_SHEET
- | TYPE_ON_BOARD_POPUP;
-
public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_LISTENER
& ~TYPE_ALL_APPS_EDU;
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index ab91785..5d41bb5 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -22,6 +22,7 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
+import android.widget.ImageButton;
import android.widget.ImageView;
import androidx.annotation.Nullable;
@@ -74,6 +75,7 @@
private LauncherAppWidgetHostView mWidgetView;
private CellLayout mCellLayout;
private DragLayer mDragLayer;
+ private ImageButton mReconfigureButton;
private Rect mWidgetPadding;
@@ -211,6 +213,17 @@
mDragHandles[INDEX_RIGHT].setVisibility(GONE);
}
+ mReconfigureButton = (ImageButton) findViewById(R.id.widget_reconfigure_button);
+ if (info.isReconfigurable()) {
+ mReconfigureButton.setVisibility(VISIBLE);
+ mReconfigureButton.setOnClickListener(view -> mLauncher
+ .getAppWidgetHost()
+ .startConfigActivity(
+ mLauncher,
+ mWidgetView.getAppWidgetId(),
+ Launcher.REQUEST_RECONFIGURE_APPWIDGET));
+ }
+
// When we create the resize frame, we first mark all cells as unoccupied. The appropriate
// cells (same if not resized, or different) will be marked as occupied when the resize
// frame is dismissed.
@@ -582,6 +595,13 @@
return false;
}
+ private boolean isTouchOnReconfigureButton(MotionEvent ev) {
+ int xFrame = (int) ev.getX() - getLeft();
+ int yFrame = (int) ev.getY() - getTop();
+ mReconfigureButton.getHitRect(sTmpRect);
+ return sTmpRect.contains(xFrame, yFrame);
+ }
+
@Override
public boolean onControllerTouchEvent(MotionEvent ev) {
int action = ev.getAction();
@@ -609,6 +629,11 @@
if (ev.getAction() == MotionEvent.ACTION_DOWN && handleTouchDown(ev)) {
return true;
}
+ // Keep the resize frame open but let a click on the reconfigure button fall through to the
+ // button's OnClickListener.
+ if (isTouchOnReconfigureButton(ev)) {
+ return false;
+ }
close(false);
return false;
}
diff --git a/src/com/android/launcher3/DevicePaddings.java b/src/com/android/launcher3/DevicePaddings.java
index 4827f36..7c387b1 100644
--- a/src/com/android/launcher3/DevicePaddings.java
+++ b/src/com/android/launcher3/DevicePaddings.java
@@ -52,8 +52,8 @@
ArrayList<DevicePadding> mDevicePaddings = new ArrayList<>();
- public DevicePaddings(Context context) {
- try (XmlResourceParser parser = context.getResources().getXml(R.xml.size_limits)) {
+ public DevicePaddings(Context context, int devicePaddingId) {
+ try (XmlResourceParser parser = context.getResources().getXml(devicePaddingId)) {
final int depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
@@ -94,16 +94,27 @@
if (workspaceTopPadding == null
|| workspaceBottomPadding == null
|| hotseatBottomPadding == null) {
- throw new RuntimeException("DevicePadding missing padding.");
+ if (Utilities.IS_DEBUG_DEVICE) {
+ throw new RuntimeException("DevicePadding missing padding.");
+ }
}
- mDevicePaddings.add(new DevicePadding(maxWidthPx, workspaceTopPadding,
- workspaceBottomPadding, hotseatBottomPadding));
+ DevicePadding dp = new DevicePadding(maxWidthPx, workspaceTopPadding,
+ workspaceBottomPadding, hotseatBottomPadding);
+ if (dp.isValid()) {
+ mDevicePaddings.add(dp);
+ } else {
+ Log.e(TAG, "Invalid device padding found.");
+ if (Utilities.IS_DEBUG_DEVICE) {
+ throw new RuntimeException("DevicePadding is invalid");
+ }
+ }
}
}
}
}
} catch (IOException | XmlPullParserException e) {
+ Log.e(TAG, "Failure parsing device padding layout.", e);
throw new RuntimeException(e);
}
@@ -128,6 +139,9 @@
*/
public static final class DevicePadding {
+ // One for each padding since they can each be off by 1 due to rounding errors.
+ private static final int ROUNDING_THRESHOLD_PX = 3;
+
private final int maxEmptySpacePx;
private final PaddingFormula workspaceTopPadding;
private final PaddingFormula workspaceBottomPadding;
@@ -143,6 +157,10 @@
this.hotseatBottomPadding = hotseatBottomPadding;
}
+ public int getMaxEmptySpacePx() {
+ return maxEmptySpacePx;
+ }
+
public int getWorkspaceTopPadding(int extraSpacePx) {
return workspaceTopPadding.calculate(extraSpacePx);
}
@@ -154,6 +172,22 @@
public int getHotseatBottomPadding(int extraSpacePx) {
return hotseatBottomPadding.calculate(extraSpacePx);
}
+
+ public boolean isValid() {
+ int workspaceTopPadding = getWorkspaceTopPadding(maxEmptySpacePx);
+ int workspaceBottomPadding = getWorkspaceBottomPadding(maxEmptySpacePx);
+ int hotseatBottomPadding = getHotseatBottomPadding(maxEmptySpacePx);
+ int sum = workspaceTopPadding + workspaceBottomPadding + hotseatBottomPadding;
+ int diff = Math.abs(sum - maxEmptySpacePx);
+ if (DEBUG) {
+ Log.d(TAG, "isValid: workspaceTopPadding=" + workspaceTopPadding
+ + ", workspaceBottomPadding=" + workspaceBottomPadding
+ + ", hotseatBottomPadding=" + hotseatBottomPadding
+ + ", sum=" + sum
+ + ", diff=" + diff);
+ }
+ return diff <= ROUNDING_THRESHOLD_PX;
+ }
}
/**
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index fa19ee6..1ce5f4d 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -104,6 +104,7 @@
private final int mWorkspacePageIndicatorOverlapWorkspace;
// Workspace icons
+ public float iconScale;
public int iconSizePx;
public int iconTextSizePx;
public int iconDrawablePaddingPx;
@@ -151,6 +152,11 @@
public int allAppsIconDrawablePaddingPx;
public float allAppsIconTextSizePx;
+ // Overview
+ public int overviewTaskMarginPx;
+ public int overviewTaskIconSizePx;
+ public int overviewTaskThumbnailTopMarginPx;
+
// Widgets
public final PointF appWidgetScale = new PointF(1.0f, 1.0f);
@@ -297,15 +303,29 @@
: (hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx
+ (isScalableGrid ? 0 : hotseatExtraVerticalSize)));
+ overviewTaskMarginPx = res.getDimensionPixelSize(R.dimen.overview_task_margin);
+ overviewTaskIconSizePx =
+ isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get() ? res.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_size_grid) : res.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_size);
+ overviewTaskThumbnailTopMarginPx = overviewTaskIconSizePx + overviewTaskMarginPx * 2;
+
// Calculate all of the remaining variables.
extraSpace = updateAvailableDimensions(res);
// Now that we have all of the variables calculated, we can tune certain sizes.
- if (isScalableGrid) {
- DevicePadding padding = inv.devicePaddings.getDevicePadding(extraSpace);
- workspaceTopPadding = padding.getWorkspaceTopPadding(extraSpace);
- workspaceBottomPadding = padding.getWorkspaceBottomPadding(extraSpace);
+ if (isScalableGrid && inv.devicePaddings != null) {
+ // Paddings were created assuming no scaling, so we first unscale the extra space.
+ int unscaledExtraSpace = (int) (extraSpace / iconScale);
+ DevicePadding padding = inv.devicePaddings.getDevicePadding(unscaledExtraSpace);
- extraHotseatBottomPadding = padding.getHotseatBottomPadding(extraSpace);
+ int paddingWorkspaceTop = padding.getWorkspaceTopPadding(unscaledExtraSpace);
+ int paddingWorkspaceBottom = padding.getWorkspaceBottomPadding(unscaledExtraSpace);
+ int paddingHotseatBottom = padding.getHotseatBottomPadding(unscaledExtraSpace);
+
+ workspaceTopPadding = Math.round(paddingWorkspaceTop * iconScale);
+ workspaceBottomPadding = Math.round(paddingWorkspaceBottom * iconScale);
+ extraHotseatBottomPadding = Math.round(paddingHotseatBottom * iconScale);
+
hotseatBarSizePx += extraHotseatBottomPadding;
hotseatBarBottomPaddingPx += extraHotseatBottomPadding;
} else if (!isVerticalBarLayout() && isPhone && isTallDevice) {
@@ -478,6 +498,8 @@
* hotseat sizes, workspaceSpringLoadedShrinkFactor, folderIconSizePx, and folderIconOffsetYPx.
*/
public void updateIconSize(float scale, Resources res) {
+ iconScale = scale;
+
// Workspace
final boolean isVerticalLayout = isVerticalBarLayout();
float invIconSizeDp = isVerticalLayout ? inv.landscapeIconSize : inv.iconSize;
@@ -878,7 +900,14 @@
writer.println(prefix + pxToDpStr("workspacePadding.right", workspacePadding.right));
writer.println(prefix + pxToDpStr("workspacePadding.bottom", workspacePadding.bottom));
+ writer.println(prefix + pxToDpStr("scaleToFit", iconScale));
writer.println(prefix + pxToDpStr("extraSpace", extraSpace));
+
+ if (inv.devicePaddings != null) {
+ int unscaledExtraSpace = (int) (extraSpace / iconScale);
+ writer.println(prefix + pxToDpStr("maxEmptySpace",
+ inv.devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx()));
+ }
writer.println(prefix + pxToDpStr("workspaceTopPadding", workspaceTopPadding));
writer.println(prefix + pxToDpStr("workspaceBottomPadding", workspaceBottomPadding));
writer.println(prefix + pxToDpStr("extraHotseatBottomPadding", extraHotseatBottomPadding));
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index b1fe4a2..0027a50 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -28,6 +28,7 @@
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -61,6 +62,8 @@
private boolean mIsPressed;
private boolean mIsDisabled;
private float mDisabledAlpha = 1f;
+ private float mRoundedCornersRadius = 0f;
+ private final Path mClipPath = new Path();
// Animator and properties for the fast bitmap drawable's scale
private static final Property<FastBitmapDrawable, Float> SCALE
@@ -102,6 +105,13 @@
@Override
public final void draw(Canvas canvas) {
+ if (mRoundedCornersRadius > 0) {
+ float radius = mRoundedCornersRadius * mScale;
+ mClipPath.reset();
+ mClipPath.addRoundRect(0, 0, getIntrinsicWidth(), getIntrinsicHeight(),
+ radius, radius, Path.Direction.CCW);
+ canvas.clipPath(mClipPath);
+ }
if (mScale != 1f) {
int count = canvas.save();
Rect bounds = getBounds();
@@ -164,6 +174,14 @@
return mScale;
}
+ public void setRoundedCornersRadius(float radius) {
+ mRoundedCornersRadius = radius;
+ }
+
+ public float getRoundedCornersRadius() {
+ return mRoundedCornersRadius;
+ }
+
@Override
public int getIntrinsicWidth() {
return mBitmap.getWidth();
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 348d9ee..b0c3bb4 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -132,6 +132,7 @@
* Do not query directly. see {@link DeviceProfile#isScalableGrid}.
*/
protected boolean isScalable;
+ public int devicePaddingId;
public String dbFile;
public int defaultLayoutId;
@@ -140,7 +141,7 @@
public DeviceProfile landscapeProfile;
public DeviceProfile portraitProfile;
- public DevicePaddings devicePaddings;
+ @Nullable public DevicePaddings devicePaddings;
public Point defaultWallpaperSize;
public Rect defaultWidgetPadding;
@@ -165,6 +166,7 @@
numHotseatIcons = p.numHotseatIcons;
numAllAppsColumns = p.numAllAppsColumns;
isScalable = p.isScalable;
+ devicePaddingId = p.devicePaddingId;
minCellHeight = p.minCellHeight;
minCellWidth = p.minCellWidth;
borderSpacing = p.borderSpacing;
@@ -225,13 +227,17 @@
.add(myDisplayOption);
result.iconSize = defaultDisplayOption.iconSize;
result.landscapeIconSize = defaultDisplayOption.landscapeIconSize;
- result.allAppsIconSize = Math.min(
- defaultDisplayOption.allAppsIconSize, myDisplayOption.allAppsIconSize);
+ if (defaultDisplayOption.allAppsIconSize < myDisplayOption.allAppsIconSize) {
+ result.allAppsIconSize = defaultDisplayOption.allAppsIconSize;
+ result.numAllAppsColumns = defaultDisplayOption.numAllAppsColumns;
+ } else {
+ result.allAppsIconSize = myDisplayOption.allAppsIconSize;
+ result.numAllAppsColumns = myDisplayOption.numAllAppsColumns;
+ }
result.minCellHeight = defaultDisplayOption.minCellHeight;
result.minCellWidth = defaultDisplayOption.minCellWidth;
result.borderSpacing = defaultDisplayOption.borderSpacing;
- devicePaddings = new DevicePaddings(context);
initGrid(context, myInfo, result);
}
@@ -262,7 +268,6 @@
ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
DisplayOption displayOption = invDistWeightedInterpolate(displayInfo, allOptions);
- devicePaddings = new DevicePaddings(context);
initGrid(context, displayInfo, displayOption);
return displayOption.grid.name;
}
@@ -278,8 +283,8 @@
demoModeLayoutId = closestProfile.demoModeLayoutId;
numFolderRows = closestProfile.numFolderRows;
numFolderColumns = closestProfile.numFolderColumns;
- numAllAppsColumns = closestProfile.numAllAppsColumns;
isScalable = closestProfile.isScalable;
+ devicePaddingId = closestProfile.devicePaddingId;
mExtraAttrs = closestProfile.extraAttrs;
@@ -293,6 +298,7 @@
minCellHeight = displayOption.minCellHeight;
minCellWidth = displayOption.minCellWidth;
borderSpacing = displayOption.borderSpacing;
+ numAllAppsColumns = Math.round(displayOption.numAllAppsColumns);
if (Utilities.isGridOptionsEnabled(context)) {
allAppsIconSize = displayOption.allAppsIconSize;
@@ -302,6 +308,10 @@
allAppsIconTextSize = iconTextSize;
}
+ if (devicePaddingId != 0) {
+ devicePaddings = new DevicePaddings(context, devicePaddingId);
+ }
+
// If the partner customization apk contains any grid overrides, apply them
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, displayInfo.metrics);
@@ -609,12 +619,12 @@
private final int numHotseatIcons;
private final String dbFile;
- private final int numAllAppsColumns;
private final int defaultLayoutId;
private final int demoModeLayoutId;
private final boolean isScalable;
+ private final int devicePaddingId;
private final SparseArray<TypedValue> extraAttrs;
@@ -636,11 +646,11 @@
R.styleable.GridDisplayOption_numFolderRows, numRows);
numFolderColumns = a.getInt(
R.styleable.GridDisplayOption_numFolderColumns, numColumns);
- numAllAppsColumns = a.getInt(
- R.styleable.GridDisplayOption_numAllAppsColumns, numColumns);
isScalable = a.getBoolean(
R.styleable.GridDisplayOption_isScalable, false);
+ devicePaddingId = a.getResourceId(
+ R.styleable.GridDisplayOption_devicePaddingId, 0);
a.recycle();
@@ -656,6 +666,7 @@
private final float minHeightDps;
private final boolean canBeDefault;
+ private float numAllAppsColumns;
private float minCellHeight;
private float minCellWidth;
private float borderSpacing;
@@ -676,6 +687,8 @@
minHeightDps = a.getFloat(R.styleable.ProfileDisplayOption_minHeightDps, 0);
canBeDefault = a.getBoolean(
R.styleable.ProfileDisplayOption_canBeDefault, false);
+ numAllAppsColumns = a.getInt(R.styleable.ProfileDisplayOption_numAllAppsColumns,
+ grid.numColumns);
minCellHeight = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightDps, 0);
minCellWidth = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthDps, 0);
@@ -702,12 +715,14 @@
minWidthDps = 0;
minHeightDps = 0;
canBeDefault = false;
+ numAllAppsColumns = 0;
minCellHeight = 0;
minCellWidth = 0;
borderSpacing = 0;
}
private DisplayOption multiply(float w) {
+ numAllAppsColumns *= w;
iconSize *= w;
landscapeIconSize *= w;
allAppsIconSize *= w;
@@ -720,6 +735,7 @@
}
private DisplayOption add(DisplayOption p) {
+ numAllAppsColumns += p.numAllAppsColumns;
iconSize += p.iconSize;
landscapeIconSize += p.landscapeIconSize;
allAppsIconSize += p.allAppsIconSize;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 89c0f66..8785fbc 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2763,6 +2763,13 @@
return new float[] {NO_SCALE, NO_OFFSET};
}
+ /**
+ * @see LauncherState#getTaskbarScale(Launcher)
+ */
+ public float getNormalTaskbarScale() {
+ return 1f;
+ }
+
public static Launcher getLauncher(Context context) {
return fromContext(context);
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 06bc438..46bce93 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -176,6 +176,10 @@
return launcher.getNormalOverviewScaleAndOffset();
}
+ public float getTaskbarScale(Launcher launcher) {
+ return launcher.getNormalTaskbarScale();
+ }
+
public float getOverviewFullscreenProgress() {
return 0;
}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 72eff62..76885cc 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -307,7 +307,7 @@
/**
* Returns the currently visible pages.
*/
- protected Iterable<View> getVisiblePages() {
+ public Iterable<View> getVisiblePages() {
int panelCount = getPanelCount();
List<View> visiblePages = new ArrayList<>(panelCount);
for (int i = mCurrentPage; i < mCurrentPage + panelCount; i++) {
@@ -1512,17 +1512,16 @@
return getDestinationPage(mOrientationHandler.getPrimaryScroll(this));
}
- protected int getDestinationPage(int scaledScroll) {
- return getPageNearestToCenterOfScreen(scaledScroll);
+ protected int getDestinationPage(int primaryScroll) {
+ return getPageNearestToCenterOfScreen(primaryScroll);
}
public int getPageNearestToCenterOfScreen() {
return getPageNearestToCenterOfScreen(mOrientationHandler.getPrimaryScroll(this));
}
- private int getPageNearestToCenterOfScreen(int scaledScroll) {
- int pageOrientationSize = mOrientationHandler.getMeasuredSize(this);
- int screenCenter = scaledScroll + (pageOrientationSize / 2);
+ private int getPageNearestToCenterOfScreen(int primaryScroll) {
+ int screenCenter = getScreenCenter(primaryScroll);
int minDistanceFromScreenCenter = Integer.MAX_VALUE;
int minDistanceFromScreenCenterIndex = -1;
final int childCount = getChildCount();
@@ -1538,18 +1537,26 @@
}
private int getDisplacementFromScreenCenter(int childIndex, int screenCenter) {
- int childSize = getChildVisibleSize(childIndex);
+ int childSize = Math.round(getChildVisibleSize(childIndex));
int halfChildSize = (childSize / 2);
int childCenter = getChildOffset(childIndex) + halfChildSize;
return childCenter - screenCenter;
}
protected int getDisplacementFromScreenCenter(int childIndex) {
- int pageOrientationSize = mOrientationHandler.getMeasuredSize(this);
- int screenCenter = mOrientationHandler.getPrimaryScroll(this) + (pageOrientationSize / 2);
+ int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
+ int screenCenter = getScreenCenter(primaryScroll);
return getDisplacementFromScreenCenter(childIndex, screenCenter);
}
+ private int getScreenCenter(int primaryScroll) {
+ float primaryScale = mOrientationHandler.getPrimaryScale(this);
+ float primaryPivot = mOrientationHandler.getPrimaryValue(getPivotX(), getPivotY());
+ int pageOrientationSize = mOrientationHandler.getMeasuredSize(this);
+ return Math.round(primaryScroll + (pageOrientationSize / 2f - primaryPivot) / primaryScale
+ + primaryPivot);
+ }
+
protected void snapToDestination() {
snapToPage(getDestinationPage(), getPageSnapDuration());
}
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 6db7a75..16e022c 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -34,7 +34,6 @@
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS;
import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
@@ -133,8 +132,7 @@
}
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
- propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha,
- config.getInterpolator(ANIM_HOTSEAT_FADE, fadeInterpolator));
+ propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, fadeInterpolator);
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
workspacePageIndicatorAlpha, fadeInterpolator);
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 591de04..bf0a88f 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -583,10 +583,6 @@
int padding = mHeader.getMaxTranslation();
for (int i = 0; i < mAH.length; i++) {
mAH[i].padding.top = padding;
- if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && mUsingTabs) {
- //add extra space between tabs and recycler view
- mAH[i].padding.top += mLauncher.getDeviceProfile().edgeMarginPx;
- }
mAH[i].applyPadding();
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsPagedView.java b/src/com/android/launcher3/allapps/AllAppsPagedView.java
index 14e3b51..3cc9ce6 100644
--- a/src/com/android/launcher3/allapps/AllAppsPagedView.java
+++ b/src/com/android/launcher3/allapps/AllAppsPagedView.java
@@ -23,8 +23,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.PagedView;
-import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.workprofile.PersonalWorkPagedView;
/**
@@ -43,10 +41,6 @@
public AllAppsPagedView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- int topPadding = FeatureFlags.ENABLE_DEVICE_SEARCH.get() ? 0
- : context.getResources().getDimensionPixelOffset(
- R.dimen.all_apps_header_top_padding);
- setPadding(0, topPadding, 0, 0);
}
@Override
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 86f330c..733d867 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -106,8 +106,8 @@
public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
- mHeaderTopPadding = FeatureFlags.ENABLE_DEVICE_SEARCH.get() ? 0 :
- context.getResources().getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
+ mHeaderTopPadding = context.getResources()
+ .getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
}
@Override
@@ -125,7 +125,6 @@
}
}
mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]);
- setPadding(0, mHeaderTopPadding, 0, 0);
mAllRows = mFixedRows;
}
@@ -243,9 +242,7 @@
public int getMaxTranslation() {
if (mMaxTranslation == 0 && mTabsHidden) {
- int paddingOffset = getResources().getDimensionPixelSize(
- R.dimen.all_apps_search_bar_bottom_padding);
- return FeatureFlags.ENABLE_DEVICE_SEARCH.get() ? 0 : paddingOffset;
+ return getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_bottom_padding);
} else if (mMaxTranslation > 0 && mTabsHidden) {
return mMaxTranslation + getPaddingTop();
} else {
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 6b9ed09..7980138 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -77,6 +77,9 @@
public static final Interpolator TOUCH_RESPONSE_INTERPOLATOR =
new PathInterpolator(0.3f, 0f, 0.1f, 1f);
+ public static final Interpolator TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL =
+ v -> ACCEL_DEACCEL.getInterpolation(TOUCH_RESPONSE_INTERPOLATOR.getInterpolation(v));
+
/**
* Inversion of ZOOM_OUT, compounded with an ease-out.
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
index 7780894..6f9f0d7 100644
--- a/src/com/android/launcher3/popup/PopupDataProvider.java
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -40,6 +40,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -224,6 +225,7 @@
.map(recommendedWidget -> allWidgetItems.get(
new ComponentKey(recommendedWidget.getTargetComponent(),
recommendedWidget.user)))
+ .filter(Objects::nonNull)
.collect(Collectors.toList());
}
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index e4c67ee..cd74390 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -38,7 +38,6 @@
PLAY_ATOMIC_OVERVIEW_PEEK,
SKIP_OVERVIEW,
SKIP_DEPTH_CONTROLLER,
- SKIP_TASKBAR,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AnimationFlags {}
@@ -47,7 +46,6 @@
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 static final int SKIP_TASKBAR = 1 << 5;
public long duration;
public boolean userControlled;
@@ -74,8 +72,6 @@
ANIM_OVERVIEW_MODAL,
ANIM_DEPTH,
ANIM_OVERVIEW_ACTIONS_FADE,
- ANIM_TASKBAR_FADE,
- ANIM_HOTSEAT_FADE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AnimType {}
@@ -95,10 +91,8 @@
public static final int ANIM_OVERVIEW_MODAL = 13;
public static final int ANIM_DEPTH = 14;
public static final int ANIM_OVERVIEW_ACTIONS_FADE = 15;
- public static final int ANIM_TASKBAR_FADE = 16;
- public static final int ANIM_HOTSEAT_FADE = 17; // if not set, falls back to ANIM_WORKSPACE_FADE
- private static final int ANIM_TYPES_COUNT = 18;
+ private static final int ANIM_TYPES_COUNT = 16;
protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index c1cf0c8..19dfe15 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -136,7 +136,7 @@
}
@Override
- public int getClearAllScrollOffset(View view, boolean isRtl) {
+ public int getClearAllSidePadding(View view, boolean isRtl) {
return (isRtl ? view.getPaddingBottom() : - view.getPaddingTop()) / 2;
}
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index fcfa205..9140a04 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -66,7 +66,7 @@
float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId);
int getMeasuredSize(View view);
float getPrimarySize(RectF rect);
- int getClearAllScrollOffset(View view, boolean isRtl);
+ int getClearAllSidePadding(View view, boolean isRtl);
int getSecondaryDimension(View view);
FloatProperty<View> getPrimaryViewTranslate();
FloatProperty<View> getSecondaryViewTranslate();
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 2bc2dc7..29be627 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -132,7 +132,7 @@
}
@Override
- public int getClearAllScrollOffset(View view, boolean isRtl) {
+ public int getClearAllSidePadding(View view, boolean isRtl) {
return (isRtl ? view.getPaddingRight() : - view.getPaddingLeft()) / 2;
}
diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java
index 0ea0290..5be9529 100644
--- a/src/com/android/launcher3/util/MultiValueAlpha.java
+++ b/src/com/android/launcher3/util/MultiValueAlpha.java
@@ -42,43 +42,16 @@
}
};
- /**
- * Determines how each alpha should factor into the final alpha.
- */
- public enum Mode {
- BLEND() {
- @Override
- public float calculateNewAlpha(float currentAlpha, float otherAlpha) {
- return currentAlpha * otherAlpha;
- }
- },
-
- MAX() {
- @Override
- public float calculateNewAlpha(float currentAlpha, float otherAlpha) {
- return Math.max(currentAlpha, otherAlpha);
- }
- };
-
- protected abstract float calculateNewAlpha(float currentAlpha, float otherAlpha);
- }
-
private final View mView;
private final AlphaProperty[] mMyProperties;
- private final Mode mMode;
private int mValidMask;
// Whether we should change from INVISIBLE to VISIBLE and vice versa at low alpha values.
private boolean mUpdateVisibility;
public MultiValueAlpha(View view, int size) {
- this(view, size, Mode.BLEND);
- }
-
- public MultiValueAlpha(View view, int size, Mode mode) {
mView = view;
mMyProperties = new AlphaProperty[size];
- mMode = mode;
mValidMask = 0;
for (int i = 0; i < size; i++) {
@@ -124,7 +97,7 @@
mOthers = 1;
for (AlphaProperty prop : mMyProperties) {
if (prop != this) {
- mOthers = mMode.calculateNewAlpha(mOthers, prop.mValue);
+ mOthers *= prop.mValue;
}
}
}
@@ -134,7 +107,7 @@
mValidMask = mMyMask;
mValue = value;
- mView.setAlpha(mMode.calculateNewAlpha(mOthers, mValue));
+ mView.setAlpha(mOthers * mValue);
if (mUpdateVisibility) {
AlphaUpdateListener.updateVisibility(mView);
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 2e542ed..687318f 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -497,12 +497,13 @@
@UiThread
private void enforceRoundedCorners() {
- if (mEnforcedCornerRadius <= 0 || !RoundedCornerEnforcement.isRoundedCornerEnabled(this)) {
+ if (mEnforcedCornerRadius <= 0 || !RoundedCornerEnforcement.isRoundedCornerEnabled()) {
resetRoundedCorners();
return;
}
View background = RoundedCornerEnforcement.findBackground(this);
- if (RoundedCornerEnforcement.hasAppWidgetOptedOut(this, background)) {
+ if (background == null
+ || RoundedCornerEnforcement.hasAppWidgetOptedOut(this, background)) {
resetRoundedCorners();
return;
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index 8689fbf..ad61495 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -139,6 +139,10 @@
}
}
+ public boolean isReconfigurable() {
+ return configure != null && (getWidgetFeatures() & WIDGET_FEATURE_RECONFIGURABLE) != 0;
+ }
+
@Override
public final ComponentName getComponent() {
return provider;
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 247a748..08bb662 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -54,10 +54,13 @@
@Nullable private RemoteViews mRemoteViewsPreview;
@Nullable private LauncherAppWidgetHostView mAppWidgetHostViewPreview;
+ private final float mEnforcedRoundedCornersForWidget;
public PendingItemDragHelper(View view) {
super(view);
mAddInfo = (PendingAddItemInfo) view.getTag();
+ mEnforcedRoundedCornersForWidget = RoundedCornerEnforcement.computeEnforcedRadius(
+ view.getContext());
}
/**
@@ -115,10 +118,14 @@
.addDragListener(new AppWidgetHostViewDragListener(launcher));
}
if (preview == null) {
- preview = new FastBitmapDrawable(
+ FastBitmapDrawable p = new FastBitmapDrawable(
app.getWidgetCache().generateWidgetPreview(launcher,
createWidgetInfo.info, maxWidth, null,
previewSizeBeforeScale).first);
+ if (RoundedCornerEnforcement.isRoundedCornerEnabled()) {
+ p.setRoundedCornersRadius(mEnforcedRoundedCornersForWidget);
+ }
+ preview = p;
}
if (previewSizeBeforeScale[0] < previewBitmapWidth) {
diff --git a/src/com/android/launcher3/widget/RoundedCornerEnforcement.java b/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
index 99eccd1..1e46ffd 100644
--- a/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
+++ b/src/com/android/launcher3/widget/RoundedCornerEnforcement.java
@@ -72,12 +72,8 @@
}
/** Check if the app widget is in the deny list. */
- public static boolean isRoundedCornerEnabled(@NonNull View view) {
- if (!Utilities.ATLEAST_S || !FeatureFlags.ENABLE_ENFORCED_ROUNDED_CORNERS.get()) {
- return false;
- }
- // Here we need to test if the view's component is in the (to be created) deny list.
- return true;
+ public static boolean isRoundedCornerEnabled() {
+ return Utilities.ATLEAST_S && FeatureFlags.ENABLE_ENFORCED_ROUNDED_CORNERS.get();
}
/**
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 1b0e1ce..2b4b9ea 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -94,6 +94,7 @@
protected final BaseActivity mActivity;
protected final DeviceProfile mDeviceProfile;
private final CheckLongPressHelper mLongPressHelper;
+ private final float mEnforcedCornerRadius;
private RemoteViews mPreview;
private LauncherAppWidgetHostView mAppWidgetHostViewPreview;
@@ -118,6 +119,7 @@
setWillNotDraw(false);
setClipToPadding(false);
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
+ mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
}
private void setContainerWidth() {
@@ -245,7 +247,9 @@
}
public void applyPreview(Bitmap bitmap) {
- applyPreview(new FastBitmapDrawable(bitmap));
+ FastBitmapDrawable drawable = new FastBitmapDrawable(bitmap);
+ drawable.setRoundedCornersRadius(mEnforcedCornerRadius);
+ applyPreview(drawable);
}
private void applyPreview(Drawable drawable) {
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 2fda86c..bbb0d92 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -26,6 +26,7 @@
import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
@@ -152,6 +153,19 @@
});
}
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mNoIntercept = false;
+ ScrollView scrollView = findViewById(R.id.widgets_table_scroll_view);
+ if (getPopupContainer().isEventOverView(scrollView, ev)
+ && scrollView.getScrollY() > 0) {
+ mNoIntercept = true;
+ }
+ }
+ return super.onControllerInterceptTouchEvent(ev);
+ }
+
protected WidgetCell addItemCell(ViewGroup parent) {
WidgetCell widget = (WidgetCell) LayoutInflater.from(getContext())
.inflate(R.layout.widget_cell, parent, false);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index dc7d341..29c00b2 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -58,6 +58,7 @@
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.picker.search.SearchModeListener;
import com.android.launcher3.widget.picker.search.WidgetsSearchBar;
+import com.android.launcher3.widget.picker.search.WidgetsSearchBarUIHelper;
import com.android.launcher3.widget.util.WidgetsTableUtils;
import com.android.launcher3.workprofile.PersonalWorkPagedView;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
@@ -71,7 +72,8 @@
*/
public class WidgetsFullSheet extends BaseWidgetSheet
implements Insettable, ProviderChangedListener, OnActivePageChangedListener,
- WidgetsRecyclerView.HeaderViewDimensionsProvider, SearchModeListener {
+ WidgetsRecyclerView.HeaderViewDimensionsProvider, SearchModeListener,
+ WidgetsSearchBarUIHelper {
private static final String TAG = WidgetsFullSheet.class.getSimpleName();
private static final long DEFAULT_OPEN_DURATION = 267;
@@ -561,6 +563,11 @@
getWindowInsetsController().hide(WindowInsets.Type.ime());
}
+ @Override
+ public void clearSearchBarFocus() {
+ mSearchAndRecommendationViewHolder.mSearchBar.clearSearchBarFocus();
+ }
+
/** A holder class for holding adapters & their corresponding recycler view. */
private final class AdapterHolder {
static final int PRIMARY = 0;
@@ -583,7 +590,9 @@
apps.getWidgetCache(),
apps.getIconCache(),
/* iconClickListener= */ WidgetsFullSheet.this,
- /* iconLongClickListener= */ WidgetsFullSheet.this);
+ /* iconLongClickListener= */ WidgetsFullSheet.this,
+ /* WidgetsSearchBarUIHelper= */
+ mAdapterType == SEARCH ? WidgetsFullSheet.this : null);
mWidgetsListAdapter.setHasStableIds(true);
switch (mAdapterType) {
case PRIMARY:
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index d841c64..d9c9d4d 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -41,6 +41,7 @@
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
+import com.android.launcher3.widget.picker.search.WidgetsSearchBarUIHelper;
import java.util.ArrayList;
import java.util.Arrays;
@@ -69,6 +70,7 @@
private static final int VIEW_TYPE_WIDGETS_HEADER = R.id.view_type_widgets_header;
private static final int VIEW_TYPE_WIDGETS_SEARCH_HEADER = R.id.view_type_widgets_search_header;
+ @Nullable private final WidgetsSearchBarUIHelper mSearchBarUIHelper;
private final WidgetsDiffReporter mDiffReporter;
private final SparseArray<ViewHolderBinder> mViewHolderBinders = new SparseArray<>();
private final WidgetsListTableViewHolderBinder mWidgetsListTableViewHolderBinder;
@@ -88,7 +90,9 @@
public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
WidgetPreviewLoader widgetPreviewLoader, IconCache iconCache,
- OnClickListener iconClickListener, OnLongClickListener iconLongClickListener) {
+ OnClickListener iconClickListener, OnLongClickListener iconLongClickListener,
+ @Nullable WidgetsSearchBarUIHelper searchBarUIHelper) {
+ mSearchBarUIHelper = searchBarUIHelper;
mDiffReporter = new WidgetsDiffReporter(iconCache, this);
mWidgetsListTableViewHolderBinder = new WidgetsListTableViewHolderBinder(context,
layoutInflater, iconClickListener, iconLongClickListener,
@@ -237,6 +241,9 @@
@Override
public void onHeaderClicked(boolean showWidgets, PackageUserKey packageUserKey) {
+ if (mSearchBarUIHelper != null) {
+ mSearchBarUIHelper.clearSearchBarFocus();
+ }
if (showWidgets) {
mWidgetsContentVisiblePackageUserKey = packageUserKey;
updateVisibleEntries();
diff --git a/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java b/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java
index cc33619..56a08b1 100644
--- a/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java
+++ b/src/com/android/launcher3/widget/picker/search/LauncherWidgetsSearchBar.java
@@ -79,4 +79,9 @@
super.onDetachedFromWindow();
mController.onDestroy();
}
+
+ @Override
+ public void clearSearchBarFocus() {
+ mController.clearFocus();
+ }
}
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java
index ef7bf23..3ac82c0 100644
--- a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java
+++ b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBar.java
@@ -35,6 +35,11 @@
void reset();
/**
+ * Clears focus from search bar.
+ */
+ void clearSearchBarFocus();
+
+ /**
* Sets the vertical location, in pixels, of this search bar relative to its top position.
*/
void setTranslationY(float translationY);
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
index 6011097..d35a75b 100644
--- a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
+++ b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
@@ -103,8 +103,7 @@
public void clearSearchResult() {
mSearchAlgorithm.cancel(/* interruptActiveRequests= */ true);
mInput.getText().clear();
- mInput.clearFocus();
- mInput.hideKeyboard();
+ clearFocus();
mSearchModeListener.exitSearchMode();
}
@@ -117,18 +116,24 @@
@Override
public boolean onBackKey() {
- mInput.clearFocus();
- mInput.hideKeyboard();
+ clearFocus();
return true;
}
@Override
public boolean onKey(View view, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
- mInput.clearFocus();
- mInput.hideKeyboard();
+ clearFocus();
return true;
}
return false;
}
+
+ /**
+ * Clears focus from edit text.
+ */
+ public void clearFocus() {
+ mInput.clearFocus();
+ mInput.hideKeyboard();
+ }
}
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarUIHelper.java b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarUIHelper.java
new file mode 100644
index 0000000..edfdc65
--- /dev/null
+++ b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarUIHelper.java
@@ -0,0 +1,27 @@
+/*
+ * 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.launcher3.widget.picker.search;
+
+/**
+ * UI helper for {@link WidgetsSearchBar}.
+ */
+public interface WidgetsSearchBarUIHelper {
+ /**
+ * Clears focus from the search bar.
+ */
+ void clearSearchBarFocus();
+}