Merge "Fixing TouchInteractionService referring destroyed activity" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/res/layout/arrow_toast.xml b/quickstep/recents_ui_overrides/res/layout/arrow_toast.xml
index b0f2b4b..980bb5a 100644
--- a/quickstep/recents_ui_overrides/res/layout/arrow_toast.xml
+++ b/quickstep/recents_ui_overrides/res/layout/arrow_toast.xml
@@ -34,6 +34,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
+ android:gravity="center"
android:layout_gravity="center_vertical"
android:textColor="@android:color/white"
android:textSize="16sp"/>
diff --git a/quickstep/recents_ui_overrides/res/values/config.xml b/quickstep/recents_ui_overrides/res/values/config.xml
index 527eec6..120e034 100644
--- a/quickstep/recents_ui_overrides/res/values/config.xml
+++ b/quickstep/recents_ui_overrides/res/values/config.xml
@@ -14,8 +14,5 @@
limitations under the License.
-->
<resources>
- <integer name="app_background_blur_radius">150</integer>
- <integer name="allapps_background_blur_radius">90</integer>
- <integer name="overview_background_blur_radius">50</integer>
- <integer name="folder_background_blur_radius_adjustment">20</integer>
+ <integer name="max_depth_blur_radius">150</integer>
</resources>
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/ArrowTipView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/ArrowTipView.java
new file mode 100644
index 0000000..a5ea523
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/ArrowTipView.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+import android.content.Context;
+import android.graphics.CornerPathEffect;
+import android.graphics.Paint;
+import android.graphics.drawable.ShapeDrawable;
+import android.os.Handler;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.core.content.ContextCompat;
+
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.graphics.TriangleShape;
+
+/**
+ * A base class for arrow tip view in launcher
+ */
+public class ArrowTipView extends AbstractFloatingView {
+
+ private static final long AUTO_CLOSE_TIMEOUT_MILLIS = 10 * 1000;
+ private static final long SHOW_DELAY_MS = 200;
+ private static final long SHOW_DURATION_MS = 300;
+ private static final long HIDE_DURATION_MS = 100;
+
+ protected final Launcher mLauncher;
+ private final Handler mHandler = new Handler();
+ private Runnable mOnClosed;
+
+ public ArrowTipView(Context context) {
+ super(context, null, 0);
+ mLauncher = Launcher.getLauncher(context);
+ init(context);
+ }
+
+ @Override
+ public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ close(true);
+ }
+ return false;
+ }
+
+ @Override
+ protected void handleClose(boolean animate) {
+ if (mIsOpen) {
+ if (animate) {
+ animate().alpha(0f)
+ .withLayer()
+ .setStartDelay(0)
+ .setDuration(HIDE_DURATION_MS)
+ .setInterpolator(Interpolators.ACCEL)
+ .withEndAction(() -> mLauncher.getDragLayer().removeView(this))
+ .start();
+ } else {
+ animate().cancel();
+ mLauncher.getDragLayer().removeView(this);
+ }
+ if (mOnClosed != null) mOnClosed.run();
+ mIsOpen = false;
+ }
+ }
+
+ @Override
+ public void logActionCommand(int command) {
+ }
+
+ @Override
+ protected boolean isOfType(int type) {
+ return (type & TYPE_ON_BOARD_POPUP) != 0;
+ }
+
+ private void init(Context context) {
+ inflate(context, R.layout.arrow_toast, this);
+ setOrientation(LinearLayout.VERTICAL);
+ View dismissButton = findViewById(R.id.dismiss);
+ dismissButton.setOnClickListener(view -> {
+ handleClose(true);
+ });
+
+ View arrowView = findViewById(R.id.arrow);
+ ViewGroup.LayoutParams arrowLp = arrowView.getLayoutParams();
+ ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(
+ arrowLp.width, arrowLp.height, false));
+ Paint arrowPaint = arrowDrawable.getPaint();
+ TypedValue typedValue = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
+ arrowPaint.setColor(ContextCompat.getColor(getContext(), typedValue.resourceId));
+ // The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
+ arrowPaint.setPathEffect(new CornerPathEffect(
+ context.getResources().getDimension(R.dimen.arrow_toast_corner_radius)));
+ arrowView.setBackground(arrowDrawable);
+
+ mIsOpen = true;
+
+ mHandler.postDelayed(() -> handleClose(true), AUTO_CLOSE_TIMEOUT_MILLIS);
+ }
+
+ /**
+ * Show Tip with specified string and Y location
+ */
+ public ArrowTipView show(String text, int top) {
+ ((TextView) findViewById(R.id.text)).setText(text);
+ mLauncher.getDragLayer().addView(this);
+
+ DragLayer.LayoutParams params = (DragLayer.LayoutParams) getLayoutParams();
+ params.gravity = Gravity.CENTER_HORIZONTAL;
+ params.leftMargin = mLauncher.getDeviceProfile().workspacePadding.left;
+ params.rightMargin = mLauncher.getDeviceProfile().workspacePadding.right;
+ post(() -> setY(top - getHeight()));
+ setAlpha(0);
+ animate()
+ .alpha(1f)
+ .withLayer()
+ .setStartDelay(SHOW_DELAY_MS)
+ .setDuration(SHOW_DURATION_MS)
+ .setInterpolator(Interpolators.DEACCEL)
+ .start();
+ return this;
+ }
+
+ /**
+ * Register a callback fired when toast is hidden
+ */
+ public ArrowTipView setOnClosedCallback(Runnable runnable) {
+ mOnClosed = runnable;
+ return this;
+ }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 9afa862..0019ecb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -91,7 +91,7 @@
AppWindowAnimationHelper helper =
new AppWindowAnimationHelper(recentsView.getPagedViewOrientedState(), mLauncher);
Animator recentsAnimator = getRecentsWindowAnimator(taskView, skipLauncherChanges,
- appTargets, wallpaperTargets, mLauncher.getBackgroundBlurController(), helper);
+ appTargets, wallpaperTargets, mLauncher.getDepthController(), helper);
anim.play(recentsAnimator.setDuration(RECENTS_LAUNCH_DURATION));
Animator childStateAnimation = null;
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java
index 0ae7435..b3bb850 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/AllAppsTipView.java
@@ -16,133 +16,30 @@
package com.android.launcher3.appprediction;
+import static com.android.launcher3.AbstractFloatingView.TYPE_DISCOVERY_BOUNCE;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ON_BOARD_POPUP;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.quickstep.logging.UserEventDispatcherExtension.ALL_APPS_PREDICTION_TIPS;
-import android.content.Context;
-import android.graphics.CornerPathEffect;
-import android.graphics.Paint;
-import android.graphics.drawable.ShapeDrawable;
-import android.os.Handler;
import android.os.UserManager;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.core.content.ContextCompat;
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.ArrowTipView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.FloatingHeaderView;
-import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.graphics.TriangleShape;
import com.android.systemui.shared.system.LauncherEventUtil;
/**
- * All apps tip view aligned just above prediction apps, shown to users that enter all apps for the
+ * ArrowTip helper aligned just above prediction apps, shown to users that enter all apps for the
* first time.
*/
-public class AllAppsTipView extends AbstractFloatingView {
+public class AllAppsTipView {
private static final String ALL_APPS_TIP_SEEN = "launcher.all_apps_tip_seen";
- private static final long AUTO_CLOSE_TIMEOUT_MILLIS = 10 * 1000;
- private static final long SHOW_DELAY_MS = 200;
- private static final long SHOW_DURATION_MS = 300;
- private static final long HIDE_DURATION_MS = 100;
-
- private final Launcher mLauncher;
- private final Handler mHandler = new Handler();
-
- private AllAppsTipView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- private AllAppsTipView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- setOrientation(LinearLayout.VERTICAL);
-
- mLauncher = Launcher.getLauncher(context);
-
- init(context);
- }
-
- @Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- close(true);
- }
- return false;
- }
-
- @Override
- protected void handleClose(boolean animate) {
- if (mIsOpen) {
- if (animate) {
- animate().alpha(0f)
- .withLayer()
- .setStartDelay(0)
- .setDuration(HIDE_DURATION_MS)
- .setInterpolator(Interpolators.ACCEL)
- .withEndAction(() -> mLauncher.getDragLayer().removeView(this))
- .start();
- } else {
- animate().cancel();
- mLauncher.getDragLayer().removeView(this);
- }
- mLauncher.getSharedPrefs().edit().putBoolean(ALL_APPS_TIP_SEEN, true).apply();
- mIsOpen = false;
- }
- }
-
- @Override
- public void logActionCommand(int command) {
- }
-
- @Override
- protected boolean isOfType(int type) {
- return (type & TYPE_ON_BOARD_POPUP) != 0;
- }
-
- private void init(Context context) {
- inflate(context, R.layout.arrow_toast, this);
-
- TextView textView = findViewById(R.id.text);
- textView.setText(R.string.all_apps_prediction_tip);
-
- View dismissButton = findViewById(R.id.dismiss);
- dismissButton.setOnClickListener(view -> {
- mLauncher.getUserEventDispatcher().logActionTip(
- LauncherEventUtil.DISMISS, ALL_APPS_PREDICTION_TIPS);
- handleClose(true);
- });
-
- View arrowView = findViewById(R.id.arrow);
- ViewGroup.LayoutParams arrowLp = arrowView.getLayoutParams();
- ShapeDrawable arrowDrawable = new ShapeDrawable(TriangleShape.create(
- arrowLp.width, arrowLp.height, false));
- Paint arrowPaint = arrowDrawable.getPaint();
- TypedValue typedValue = new TypedValue();
- context.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
- arrowPaint.setColor(ContextCompat.getColor(getContext(), typedValue.resourceId));
- // The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
- arrowPaint.setPathEffect(new CornerPathEffect(
- context.getResources().getDimension(R.dimen.arrow_toast_corner_radius)));
- arrowView.setBackground(arrowDrawable);
-
- mIsOpen = true;
-
- mHandler.postDelayed(() -> handleClose(true), AUTO_CLOSE_TIMEOUT_MILLIS);
- }
private static boolean showAllAppsTipIfNecessary(Launcher launcher) {
FloatingHeaderView floatingHeaderView = launcher.getAppsView().getFloatingHeaderView();
@@ -156,28 +53,15 @@
return false;
}
- AllAppsTipView allAppsTipView = new AllAppsTipView(launcher.getAppsView().getContext(),
- null);
- launcher.getDragLayer().addView(allAppsTipView);
+ int[] coords = new int[2];
+ floatingHeaderView.findFixedRowByType(PredictionRowView.class).getLocationOnScreen(coords);
+ ArrowTipView arrowTipView = new ArrowTipView(launcher).setOnClosedCallback(() -> {
+ launcher.getSharedPrefs().edit().putBoolean(ALL_APPS_TIP_SEEN, true).apply();
+ launcher.getUserEventDispatcher().logActionTip(LauncherEventUtil.DISMISS,
+ ALL_APPS_PREDICTION_TIPS);
+ });
+ arrowTipView.show(launcher.getString(R.string.all_apps_prediction_tip), coords[1]);
- DragLayer.LayoutParams params = (DragLayer.LayoutParams) allAppsTipView.getLayoutParams();
- params.gravity = Gravity.CENTER_HORIZONTAL;
-
- int top = floatingHeaderView.findFixedRowByType(PredictionRowView.class).getTop();
- allAppsTipView.setY(top - launcher.getResources().getDimensionPixelSize(
- R.dimen.all_apps_tip_bottom_margin));
-
- allAppsTipView.setAlpha(0);
- allAppsTipView.animate()
- .alpha(1f)
- .withLayer()
- .setStartDelay(SHOW_DELAY_MS)
- .setDuration(SHOW_DURATION_MS)
- .setInterpolator(Interpolators.DEACCEL)
- .start();
-
- launcher.getUserEventDispatcher().logActionTip(
- LauncherEventUtil.VISIBLE, ALL_APPS_PREDICTION_TIPS);
return true;
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index a07cd1d..da58817 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -23,23 +23,28 @@
import android.content.res.Configuration;
import android.os.Build;
import android.view.View;
-import android.view.ViewGroup;
import androidx.core.app.NotificationCompat;
import com.android.launcher3.CellLayout;
+import com.android.launcher3.FolderInfo;
+import com.android.launcher3.Hotseat;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.WorkspaceLayoutManager;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ActivityTracker;
+import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.Themes;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -52,48 +57,179 @@
private static final int ONBOARDING_NOTIFICATION_ID = 7641;
private final Launcher mLauncher;
+ private final NotificationManager mNotificationManager;
+ private final Notification mNotification;
private List<WorkspaceItemInfo> mPredictedApps;
private HotseatEduDialog mActiveDialog;
- private final NotificationManager mNotificationManager;
- private final Notification mNotification;
+ private ArrayList<ItemInfo> mNewItems = new ArrayList<>();
+ private IntArray mNewScreens = null;
+ private Runnable mOnOnboardingComplete;
- HotseatEduController(Launcher launcher) {
+ HotseatEduController(Launcher launcher, Runnable runnable) {
mLauncher = launcher;
+ mOnOnboardingComplete = runnable;
mNotificationManager = mLauncher.getSystemService(NotificationManager.class);
createNotificationChannel();
mNotification = createNotification();
}
- boolean migrate() {
- Workspace workspace = mLauncher.getWorkspace();
- CellLayout firstScreen = workspace.getScreenWithId(WorkspaceLayoutManager.FIRST_SCREEN_ID);
- int toPage = Workspace.FIRST_SCREEN_ID;
- int toRow = mLauncher.getDeviceProfile().inv.numRows - 1;
- if (FeatureFlags.HOTSEAT_MIGRATE_NEW_PAGE.get()) {
- toPage = workspace.getScreenIdForPageIndex(workspace.getPageCount());
- toRow = 0;
- } else if (!firstScreen.makeSpaceForHotseatMigration(true)) {
- return false;
+ /**
+ * Checks what type of migration should be used and migrates hotseat
+ */
+ void migrate() {
+ if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) {
+ migrateToFolder();
+ } else {
+ migrateHotseatWhole();
}
- ViewGroup hotseatVG = mLauncher.getHotseat().getShortcutsAndWidgets();
- for (int i = 0; i < hotseatVG.getChildCount(); i++) {
- View child = hotseatVG.getChildAt(i);
+ }
+
+ /**
+ * This migration places all non folder items in the hotseat into a folder and then moves
+ * all folders in the hotseat to a workspace page that has enough empty spots.
+ *
+ * @return pageId that has accepted the items.
+ */
+ private int migrateToFolder() {
+ ArrayDeque<FolderInfo> folders = new ArrayDeque<>();
+
+ ArrayList<WorkspaceItemInfo> putIntoFolder = new ArrayList<>();
+
+ //separate folders and items that can get in folders
+ for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
+ View view = mLauncher.getHotseat().getChildAt(i, 0);
+ if (view == null) continue;
+ ItemInfo info = (ItemInfo) view.getTag();
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
+ folders.add((FolderInfo) info);
+ } else if (info instanceof WorkspaceItemInfo) {
+ putIntoFolder.add((WorkspaceItemInfo) info);
+ }
+ }
+
+ // create a temp folder and add non folder items to it
+ if (!putIntoFolder.isEmpty()) {
+ ItemInfo firstItem = putIntoFolder.get(0);
+ FolderInfo folderInfo = new FolderInfo();
+ folderInfo.title = "";
+ mLauncher.getModelWriter().addItemToDatabase(folderInfo, firstItem.container,
+ firstItem.screenId, firstItem.cellX, firstItem.cellY);
+ folderInfo.contents.addAll(putIntoFolder);
+ for (int i = 0; i < folderInfo.contents.size(); i++) {
+ ItemInfo item = folderInfo.contents.get(i);
+ item.rank = i;
+ mLauncher.getModelWriter().moveItemInDatabase(item, folderInfo.id, 0,
+ item.cellX, item.cellY);
+ }
+ folders.add(folderInfo);
+ }
+ mNewItems.addAll(folders);
+
+ return placeFoldersInWorkspace(folders);
+ }
+
+ private int placeFoldersInWorkspace(ArrayDeque<FolderInfo> folders) {
+ if (folders.isEmpty()) return 0;
+
+ Workspace workspace = mLauncher.getWorkspace();
+ InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
+
+ GridOccupancy[] occupancyList = new GridOccupancy[workspace.getChildCount()];
+ for (int i = 0; i < occupancyList.length; i++) {
+ occupancyList[i] = ((CellLayout) workspace.getChildAt(i)).cloneGridOccupancy();
+ }
+ //scan every screen to find available spots to place folders
+ int occupancyIndex = 0;
+ int[] itemXY = new int[2];
+ while (occupancyIndex < occupancyList.length && !folders.isEmpty()) {
+ GridOccupancy occupancy = occupancyList[occupancyIndex];
+ if (occupancy.findVacantCell(itemXY, 1, 1)) {
+ FolderInfo info = folders.poll();
+ mLauncher.getModelWriter().moveItemInDatabase(info,
+ LauncherSettings.Favorites.CONTAINER_DESKTOP,
+ workspace.getScreenIdForPageIndex(occupancyIndex), itemXY[0], itemXY[1]);
+ occupancy.markCells(info, true);
+ } else {
+ occupancyIndex++;
+ }
+ }
+ if (folders.isEmpty()) return workspace.getScreenIdForPageIndex(occupancyIndex);
+ int screenId = LauncherSettings.Settings.call(mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+ .getInt(LauncherSettings.Settings.EXTRA_VALUE);
+ // if all screens are full and we still have folders left, put those on a new page
+ FolderInfo folderInfo;
+ int col = 0;
+ while ((folderInfo = folders.poll()) != null) {
+ mLauncher.getModelWriter().moveItemInDatabase(folderInfo,
+ LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, col++,
+ idp.numRows - 1);
+ }
+ mNewScreens = IntArray.wrap(screenId);
+ return workspace.getPageCount();
+ }
+
+ /**
+ * This migration option attempts to move the entire hotseat up to the first workspace that
+ * has space to host items. If no such page is found, it moves items to a new page.
+ *
+ * @return pageId where items are migrated
+ */
+ private int migrateHotseatWhole() {
+ Workspace workspace = mLauncher.getWorkspace();
+ Hotseat hotseatVG = mLauncher.getHotseat();
+
+ int pageId = -1;
+ int toRow = 0;
+ for (int i = 0; i < workspace.getPageCount(); i++) {
+ CellLayout target = workspace.getScreenWithId(workspace.getScreenIdForPageIndex(i));
+ if (target.makeSpaceForHotseatMigration(true)) {
+ toRow = mLauncher.getDeviceProfile().inv.numRows - 1;
+ pageId = i;
+ break;
+ }
+ }
+ if (pageId == -1) {
+ pageId = LauncherSettings.Settings.call(mLauncher.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+ .getInt(LauncherSettings.Settings.EXTRA_VALUE);
+ }
+ for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
+ View child = hotseatVG.getChildAt(i, 0);
+ if (child == null || child.getTag() == null) continue;
ItemInfo tag = (ItemInfo) child.getTag();
mLauncher.getModelWriter().moveItemInDatabase(tag,
- LauncherSettings.Favorites.CONTAINER_DESKTOP, toPage, tag.screenId, toRow);
+ LauncherSettings.Favorites.CONTAINER_DESKTOP, pageId, i, toRow);
+ mNewItems.add(tag);
}
- return true;
+ return pageId;
}
+
void removeNotification() {
mNotificationManager.cancel(ONBOARDING_NOTIFICATION_ID);
}
void finishOnboarding() {
- mLauncher.getModel().rebindCallbacks();
+ mLauncher.getHotseat().removeAllViewsInLayout();
+ if (!mNewItems.isEmpty()) {
+ int lastPage = mNewItems.get(mNewItems.size() - 1).screenId;
+ ArrayList<ItemInfo> animated = new ArrayList<>();
+ ArrayList<ItemInfo> nonAnimated = new ArrayList<>();
+
+ for (ItemInfo info : mNewItems) {
+ if (info.screenId == lastPage) {
+ animated.add(info);
+ } else {
+ nonAnimated.add(info);
+ }
+ }
+ mLauncher.bindAppsAdded(mNewScreens, nonAnimated, animated);
+ }
+ mOnOnboardingComplete.run();
+ destroy();
mLauncher.getSharedPrefs().edit().putBoolean(KEY_HOTSEAT_EDU_SEEN, true).apply();
- removeNotification();
}
void setPredictedApps(List<WorkspaceItemInfo> predictedApps) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index 538b7f3..bcce168 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -29,13 +29,13 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.android.launcher3.ArrowTipView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.WorkspaceItemInfo;
-import com.android.launcher3.WorkspaceLayoutManager;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.UserEventDispatcher;
@@ -54,23 +54,15 @@
private static final int DEFAULT_CLOSE_DURATION = 200;
protected static final int FINAL_SCRIM_BG_COLOR = 0x88000000;
- // We don't migrate if user has more than SAME_PAGE_MAX_ROWS rows of item in their screen
- private static final int SAME_PAGE_MAX_ROWS = 2;
- private static final int MIGRATE_SAME_PAGE = 0;
- private static final int MIGRATE_NEW_PAGE = 1;
- private static final int MIGRATE_NO_MIGRATE = 2;
-
+ // we use this value to keep track of migration logs as we experiment with different migrations
+ private static final int MIGRATION_EXPERIMENT_IDENTIFIER = 1;
private final Rect mInsets = new Rect();
private View mHotseatWrapper;
private CellLayout mSampleHotseat;
- private TextView mEduHeading;
- private TextView mEduContent;
private Button mDismissBtn;
- private int mMigrationMode = MIGRATE_SAME_PAGE;
-
public void setHotseatEduController(HotseatEduController hotseatEduController) {
mHotseatEduController = hotseatEduController;
}
@@ -93,8 +85,6 @@
super.onFinishInflate();
mHotseatWrapper = findViewById(R.id.hotseat_wrapper);
mSampleHotseat = findViewById(R.id.sample_prediction);
- mEduHeading = findViewById(R.id.hotseat_edu_heading);
- mEduContent = findViewById(R.id.hotseat_edu_content);
DeviceProfile grid = mLauncher.getDeviceProfile();
Rect padding = grid.getHotseatLayoutPadding();
@@ -109,25 +99,30 @@
mDismissBtn = findViewById(R.id.no_thanks);
mDismissBtn.setOnClickListener(this::onDismiss);
+ // update ui to reflect which migration method is going to be used
+ if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) {
+ ((TextView) findViewById(R.id.hotseat_edu_content)).setText(
+ R.string.hotseat_edu_message_migrate_alt);
+ }
}
private void onAccept(View v) {
- if (mMigrationMode == MIGRATE_NO_MIGRATE || !mHotseatEduController.migrate()) {
- onDismiss(v);
- return;
- }
+ mHotseatEduController.migrate();
handleClose(true);
mHotseatEduController.finishOnboarding();
- logUserAction(true);
- int toastStringRes = mMigrationMode == MIGRATE_SAME_PAGE
+ //TODO: pass actual page index here.
+ // Temporarily we're passing 1 for folder migration and 2 for page migration
+ logUserAction(true, FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get() ? 1 : 2);
+ int toastStringRes = !FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()
? R.string.hotseat_items_migrated : R.string.hotseat_items_migrated_alt;
Toast.makeText(mLauncher, toastStringRes, Toast.LENGTH_LONG).show();
}
private void onDismiss(View v) {
- Toast.makeText(getContext(), R.string.hotseat_no_migration, Toast.LENGTH_LONG).show();
+ int top = mLauncher.getHotseat().getTop();
+ new ArrowTipView(mLauncher).show(mLauncher.getString(R.string.hotseat_no_migration), top);
mHotseatEduController.finishOnboarding();
- logUserAction(false);
+ logUserAction(false, -1);
handleClose(true);
}
@@ -159,7 +154,7 @@
mLauncher.getDeviceProfile().hotseatBarSizePx + insets.bottom;
}
- private void logUserAction(boolean migrated) {
+ private void logUserAction(boolean migrated, int pageIndex) {
LauncherLogProto.Action action = new LauncherLogProto.Action();
LauncherLogProto.Target target = new LauncherLogProto.Target();
action.type = LauncherLogProto.Action.Type.TOUCH;
@@ -168,8 +163,9 @@
target.tipType = LauncherLogProto.TipType.HYBRID_HOTSEAT;
target.controlType = migrated ? LauncherLogProto.ControlType.HYBRID_HOTSEAT_ACCEPTED
: HYBRID_HOTSEAT_CANCELED;
+ target.rank = MIGRATION_EXPERIMENT_IDENTIFIER;
// encoding migration type on pageIndex
- target.pageIndex = mMigrationMode;
+ target.pageIndex = pageIndex;
LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
UserEventDispatcher.newInstance(getContext()).dispatchUserEvent(event, null);
}
@@ -222,28 +218,6 @@
}
}
- @Override
- protected void attachToContainer() {
- super.attachToContainer();
- if (FeatureFlags.HOTSEAT_MIGRATE_NEW_PAGE.get()) {
- mEduContent.setText(R.string.hotseat_edu_message_migrate_alt);
- mMigrationMode = MIGRATE_NEW_PAGE;
- return;
- }
- CellLayout page = mLauncher.getWorkspace().getScreenWithId(
- WorkspaceLayoutManager.FIRST_SCREEN_ID);
-
- int maxItemsOnPage = SAME_PAGE_MAX_ROWS * mLauncher.getDeviceProfile().inv.numColumns
- + (FeatureFlags.QSB_ON_FIRST_SCREEN ? 1 : 0);
- if (page.getShortcutsAndWidgets().getChildCount() > maxItemsOnPage
- || !page.makeSpaceForHotseatMigration(false)) {
- mMigrationMode = MIGRATE_NO_MIGRATE;
- mEduContent.setText(R.string.hotseat_edu_message_no_migrate);
- mEduHeading.setText(R.string.hotseat_edu_title_no_migrate);
- mDismissBtn.setVisibility(GONE);
- }
- }
-
/**
* Opens User education dialog with a list of suggested apps
*/
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 2cdcd20..d82e9f0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -94,7 +94,6 @@
private static final String BUNDLE_KEY_WORKSPACE = "workspace_apps";
private static final String PREDICTION_CLIENT = "hotseat";
-
private DropTarget.DragObject mDragObject;
private int mHotSeatItemsCount;
private int mPredictedSpotsCount = 0;
@@ -115,6 +114,7 @@
private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>();
+
private final View.OnLongClickListener mPredictionLongClickListener = v -> {
if (!ItemLongClickListener.canStartDrag(mLauncher)) return false;
if (mLauncher.getWorkspace().isSwitchingState()) return false;
@@ -276,12 +276,10 @@
.build());
mAppPredictor.registerPredictionUpdates(mLauncher.getMainExecutor(),
this::setPredictedApps);
+ setPauseUIUpdate(false);
if (!isReady()) {
- if (mHotseatEduController != null) {
- mHotseatEduController.destroy();
- }
- mHotseatEduController = new HotseatEduController(mLauncher);
+ mHotseatEduController = new HotseatEduController(mLauncher, this::createPredictor);
}
mAppPredictor.requestPredictionUpdate();
}
@@ -327,7 +325,7 @@
mComponentKeyMappers.add(new ComponentKeyMapper(key, mDynamicItemCache));
}
predictionLog.append("]");
- FileLog.d(TAG, predictionLog.toString());
+ if (false) FileLog.d(TAG, predictionLog.toString());
updateDependencies();
if (isReady()) {
fillGapsWithPrediction();
@@ -488,7 +486,6 @@
}
}
-
@Override
public void onDragEnd() {
if (mDragObject == null) {
@@ -564,7 +561,8 @@
}
@Override
- public void reapplyItemInfo(ItemInfoWithIcon info) {}
+ public void reapplyItemInfo(ItemInfoWithIcon info) {
+ }
@Override
public void onDropCompleted(View target, DropTarget.DragObject d, boolean success) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 5bac964..de3fce1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -19,7 +19,6 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.LayoutUtils;
@@ -107,7 +106,7 @@
}
@Override
- public int getBackgroundBlurRadius(Context context) {
- return context.getResources().getInteger(R.integer.app_background_blur_radius);
+ public float getDepth(Context context) {
+ return 1f;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 6a34917..024872f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -207,8 +207,8 @@
}
@Override
- public int getBackgroundBlurRadius(Context context) {
- return context.getResources().getInteger(R.integer.overview_background_blur_radius);
+ public float getDepth(Context context) {
+ return 1f;
}
@Override
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index aaf7619..ce7fa0d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
-import static com.android.launcher3.uioverrides.BackgroundBlurController.BACKGROUND_BLUR;
+import static com.android.launcher3.uioverrides.DepthController.DEPTH;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -34,7 +34,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.anim.AnimationSuccessListener;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
+import com.android.launcher3.uioverrides.DepthController;
import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
import com.android.quickstep.util.RemoteAnimationProvider;
@@ -105,10 +105,10 @@
mRecentsView.setRunningTaskIconScaledDown(true);
}
- BackgroundBlurController blurController = mActivityInterface.getBackgroundBlurController();
- if (blurController != null) {
+ DepthController depthController = mActivityInterface.getDepthController();
+ if (depthController != null) {
// Update the surface to be the lowest closing app surface
- blurController.setSurfaceToLauncher(mRecentsView);
+ depthController.setSurfaceToLauncher(mRecentsView);
}
AnimatorSet anim = new AnimatorSet();
@@ -124,7 +124,7 @@
if (mActivity == null) {
Log.e(TAG, "Animation created, before activity");
anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION))
- .with(createBackgroundBlurAnimator(blurController));
+ .with(createDepthAnimator(depthController));
return anim;
}
@@ -136,7 +136,7 @@
if (runningTaskTarget == null) {
Log.e(TAG, "No closing app");
anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION))
- .with(createBackgroundBlurAnimator(blurController));
+ .with(createDepthAnimator(depthController));
return anim;
}
@@ -184,7 +184,7 @@
});
}
anim.play(valueAnimator)
- .with(createBackgroundBlurAnimator(blurController));
+ .with(createDepthAnimator(depthController));
return anim;
}
@@ -197,14 +197,14 @@
return RECENTS_LAUNCH_DURATION;
}
- private Animator createBackgroundBlurAnimator(BackgroundBlurController blurController) {
- if (blurController == null) {
+ private Animator createDepthAnimator(DepthController depthController) {
+ if (depthController == null) {
// Dummy animation
return ValueAnimator.ofInt(0);
}
- return ObjectAnimator.ofInt(blurController, BACKGROUND_BLUR,
- BACKGROUND_APP.getBackgroundBlurRadius(mActivity),
- OVERVIEW.getBackgroundBlurRadius(mActivity))
+ return ObjectAnimator.ofFloat(depthController, DEPTH,
+ BACKGROUND_APP.getDepth(mActivity),
+ OVERVIEW.getDepth(mActivity))
.setDuration(RECENTS_LAUNCH_DURATION);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
index d402a75..55e6ba2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
@@ -56,8 +56,8 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.appprediction.PredictionUiStateManager;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
-import com.android.launcher3.uioverrides.BackgroundBlurController.ClampedBlurProperty;
+import com.android.launcher3.uioverrides.DepthController;
+import com.android.launcher3.uioverrides.DepthController.ClampedDepthProperty;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.SysUINavigationMode.Mode;
@@ -330,18 +330,17 @@
endState.getVerticalProgress(activity)));
}
- // Animate the blur
- BackgroundBlurController blurController = getBackgroundBlurController();
- int fromBlurRadius = fromState.getBackgroundBlurRadius(activity);
- int toBlurRadius = endState.getBackgroundBlurRadius(activity);
- Animator backgroundBlur = ObjectAnimator.ofInt(blurController,
- new ClampedBlurProperty(toBlurRadius, fromBlurRadius),
- fromBlurRadius, toBlurRadius);
- anim.play(backgroundBlur);
+ // Animate the blur and wallpaper zoom
+ DepthController depthController = getDepthController();
+ float fromDepthRatio = fromState.getDepth(activity);
+ float toDepthRatio = endState.getDepth(activity);
+ Animator depthAnimator = ObjectAnimator.ofFloat(depthController,
+ new ClampedDepthProperty(fromDepthRatio, toDepthRatio),
+ fromDepthRatio, toDepthRatio);
+ anim.play(depthAnimator);
playScaleDownAnim(anim, activity, fromState, endState);
-
anim.setDuration(transitionLength * 2);
anim.setInterpolator(LINEAR);
AnimatorPlaybackController controller =
@@ -558,11 +557,11 @@
@Nullable
@Override
- public BackgroundBlurController getBackgroundBlurController() {
+ public DepthController getDepthController() {
BaseQuickstepLauncher launcher = getCreatedActivity();
if (launcher == null) {
return null;
}
- return launcher.getBackgroundBlurController();
+ return launcher.getDepthController();
}
}
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
index 3328abc..cafdb62 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
@@ -294,7 +294,7 @@
}
setupRecentsViewUi();
- mActivityInterface.getBackgroundBlurController().setSurfaceToLauncher(mRecentsView);
+ mActivityInterface.getDepthController().setSurfaceToLauncher(mRecentsView);
if (mDeviceState.getNavMode() == TWO_BUTTONS) {
// If the device is in two button mode, swiping up will show overview with predictions
@@ -588,7 +588,7 @@
// We will handle the sysui flags based on the centermost task view.
if (mRecentsAnimationController != null) {
mRecentsAnimationController.setWindowThresholdCrossed(centermostTaskFlags != 0
- || useHomeScreenFlags);
+ && useHomeScreenFlags);
}
int sysuiFlags = useHomeScreenFlags ? 0 : centermostTaskFlags;
mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW, sysuiFlags);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
index 3ab0f19..42d944f 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java
@@ -186,7 +186,7 @@
AppWindowAnimationHelper helper = new AppWindowAnimationHelper(
mFallbackRecentsView.getPagedViewOrientedState(), this);
Animator recentsAnimator = getRecentsWindowAnimator(taskView, !activityClosing, appTargets,
- wallpaperTargets, null /* backgroundBlurController */,
+ wallpaperTargets, null /* depthController */,
helper);
target.play(recentsAnimator.setDuration(RECENTS_LAUNCH_DURATION));
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index 38b86ce..7ec083e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.uioverrides.BackgroundBlurController.BACKGROUND_BLUR;
+import static com.android.launcher3.uioverrides.DepthController.DEPTH;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.Animator;
@@ -35,7 +35,7 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Utilities;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
+import com.android.launcher3.uioverrides.DepthController;
import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.views.RecentsView;
@@ -123,7 +123,7 @@
public static Animator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
- BackgroundBlurController backgroundBlurController,
+ DepthController depthController,
final AppWindowAnimationHelper inOutHelper) {
SyncRtSurfaceTransactionApplierCompat applier =
new SyncRtSurfaceTransactionApplierCompat(v);
@@ -215,9 +215,9 @@
}
});
- if (backgroundBlurController != null) {
- ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofInt(backgroundBlurController,
- BACKGROUND_BLUR, BACKGROUND_APP.getBackgroundBlurRadius(v.getContext()));
+ if (depthController != null) {
+ ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController,
+ DEPTH, BACKGROUND_APP.getDepth(v.getContext()));
animatorSet.playTogether(appAnimator, backgroundRadiusAnim);
} else {
animatorSet.play(appAnimator);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
index 2c5d631..7f5ec9b 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
@@ -81,7 +81,8 @@
if (!insets.equals(mInsets)) {
super.setInsets(insets);
}
- setBackground(insets.top == 0 ? null
+ setBackground(insets.top == 0 || !mAllowSysuiScrims
+ ? null
: Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 3ed7530..a027fea 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -46,9 +46,9 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.appprediction.PredictionUiStateManager;
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
-import com.android.launcher3.states.RotationHelper;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.states.RotationHelper;
+import com.android.launcher3.uioverrides.DepthController;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.views.ScrimView;
@@ -409,7 +409,7 @@
}
@Override
- protected BackgroundBlurController getBackgroundBlurController() {
- return mActivity.getBackgroundBlurController();
+ protected DepthController getDepthController() {
+ return mActivity.getDepthController();
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index e15ac46..68c51a0 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -19,6 +19,7 @@
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.Utilities.squaredHypot;
@@ -29,7 +30,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.uioverrides.BackgroundBlurController.BACKGROUND_BLUR;
+import static com.android.launcher3.uioverrides.DepthController.DEPTH;
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON;
@@ -97,7 +98,7 @@
import com.android.launcher3.graphics.RotationMode;
import com.android.launcher3.states.RotationHelper;
import com.android.launcher3.touch.PagedOrientationHandler.CurveProperties;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
+import com.android.launcher3.uioverrides.DepthController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
@@ -717,6 +718,9 @@
for (int i = 0; i < taskCount; i++) {
getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
}
+ if (mActionsView != null) {
+ mActionsView.setVisibility(fullscreenProgress == 0 ? VISIBLE : INVISIBLE);
+ }
}
private void updateTaskStackListenerState() {
@@ -1162,7 +1166,9 @@
}
private void addDismissedTaskAnimations(View taskView, long duration, PendingAnimation anim) {
- anim.setViewAlpha(taskView, 0, ACCEL_2);
+ // Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
+ // alpha is set to 0 so that it can be recycled in the view pool properly
+ anim.setFloat(taskView, VIEW_ALPHA, 0, ACCEL_2);
FloatProperty<View> secondaryViewTranslate =
mOrientationHandler.getSecondaryViewTranslate();
int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
@@ -1702,11 +1708,11 @@
appWindowAnimationHelper.prepareAnimation(mActivity.getDeviceProfile(), true /* isOpening */);
AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv, appWindowAnimationHelper);
- BackgroundBlurController blurController = getBackgroundBlurController();
- if (blurController != null) {
- ObjectAnimator backgroundBlur = ObjectAnimator.ofInt(blurController, BACKGROUND_BLUR,
- BACKGROUND_APP.getBackgroundBlurRadius(mActivity));
- anim.play(backgroundBlur);
+ DepthController depthController = getDepthController();
+ if (depthController != null) {
+ ObjectAnimator depthAnimator = ObjectAnimator.ofFloat(depthController, DEPTH,
+ BACKGROUND_APP.getDepth(mActivity));
+ anim.play(depthAnimator);
}
anim.play(progressAnim);
anim.setDuration(duration).setInterpolator(interpolator);
@@ -2009,7 +2015,7 @@
}
@Nullable
- protected BackgroundBlurController getBackgroundBlurController() {
+ protected DepthController getDepthController() {
return null;
}
@@ -2029,7 +2035,6 @@
void onEmptyMessageUpdated(boolean isEmpty);
}
-
private static class PinnedStackAnimationListener<T extends BaseActivity> extends
IPinnedStackAnimationListener.Stub {
private T mActivity;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index c94b56c..56e3632 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -247,8 +247,17 @@
/** Updates UI based on whether the task is modal. */
public void updateUiForModalTask() {
+ boolean isOverlayModal = isTaskOverlayModal();
if (getRecentsView() != null) {
- getRecentsView().updateUiForModalTask(this, isTaskOverlayModal());
+ getRecentsView().updateUiForModalTask(this, isOverlayModal);
+ }
+ // Hide footers when overlay is modal.
+ if (isOverlayModal) {
+ for (FooterWrapper footer : mFooters) {
+ if (footer != null) {
+ footer.animateHide();
+ }
+ }
}
}
@@ -780,6 +789,22 @@
animator.setDuration(100);
animator.start();
}
+
+ void animateHide() {
+ ValueAnimator animator = ValueAnimator.ofFloat(0.0f, 1.0f);
+ animator.addUpdateListener(anim -> {
+ mFooterVerticalOffset = anim.getAnimatedFraction();
+ updateFooterOffset();
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ removeView(mView);
+ }
+ });
+ animator.setDuration(100);
+ animator.start();
+ }
}
@Override
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 90d4245..b55b042 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -68,30 +68,25 @@
<!-- Hotseat migration notification title -->
- <string translatable="false" name="hotseat_edu_prompt_title">Get app suggestions based on your routines</string>
+ <string name="hotseat_edu_prompt_title">Easily access your most-used apps</string>
<!-- Hotseat migration notification content -->
- <string translatable="false" name="hotseat_edu_prompt_content">Tap to set up</string>
-
+ <string name="hotseat_edu_prompt_content">Pixel predicts apps you\’ll need next, right on your Home screen. Tap to set up.</string>
<!-- Hotseat educational strings for users who don't qualify for migration -->
- <string translatable="false" name="hotseat_edu_title_migrate">Suggested apps replace the bottom row of apps</string>
- <string translatable="false" name="hotseat_edu_message_migrate">Your hotseat items will be moved up on the homescreen</string>
- <string translatable="false" name="hotseat_edu_message_migrate_alt">Your hotseat items will be moved to the last page of your workspace</string>
+ <string name="hotseat_edu_title_migrate">Get app suggestions on the bottom row of your Home screen</string>
-
- <!-- Hotseat educational strings for users who don't qualify -->
- <string translatable="false" name="hotseat_edu_title_no_migrate">Suggested apps will be found at the bottom row of your home screen</string>
- <string translatable="false" name="hotseat_edu_message_no_migrate">Drag one or many apps off the bottom row of home screen to see app suggestions</string>
+ <string name="hotseat_edu_message_migrate">Easily access your most-used apps right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your Home screen. </string>
+ <string name="hotseat_edu_message_migrate_alt">Easily access your most-used apps, right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move to a new folder.</string>
<!-- Toast message user sees after opting into fully predicted hybrid hotseat -->
- <string translatable="false" name="hotseat_items_migrated">Bottom row of apps moved up.</string>
- <string translatable="false" name="hotseat_items_migrated_alt">Bottom row of apps moved to last page.</string>
+ <string name="hotseat_items_migrated">Your hotseat items have been moved up to your homescreen</string>
+ <string name="hotseat_items_migrated_alt">Your hotseat items have been moved to a folder</string>
<!-- Toast message user sees after opting into fully predicted hybrid hotseat -->
- <string translatable="false" name="hotseat_no_migration">Bottom row won\'t be replaced. Manually drag apps for predictions.</string>
+ <string name="hotseat_no_migration">Drag apps off the bottom row to see app suggestions</string>
<!-- Button text to opt in for fully predicted hotseat -->
- <string translatable="false" name="hotseat_edu_accept">Got it</string>
+ <string name="hotseat_edu_accept">Get app suggestions</string>
<!-- Button text to dismiss opt in for fully predicted hotseat -->
- <string translatable="false" name="hotseat_edu_dismiss">No thanks</string>
+ <string name="hotseat_edu_dismiss">No thanks</string>
<!-- Title shown during interactive part of Back gesture tutorial for right edge. [CHAR LIMIT=30] -->
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index a7d00c5..ec66f11 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -244,7 +244,7 @@
return new StateHandler[] {
getAllAppsController(),
getWorkspace(),
- getBackgroundBlurController(),
+ getDepthController(),
new RecentsViewStateController(this),
new BackButtonAlphaHandler(this)};
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index 1b39242..c93a4ba 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -33,7 +33,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
-import static com.android.launcher3.uioverrides.BackgroundBlurController.BACKGROUND_BLUR;
+import static com.android.launcher3.uioverrides.DepthController.DEPTH;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
@@ -69,11 +69,10 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.shortcuts.DeepShortcutView;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
+import com.android.launcher3.uioverrides.DepthController;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
@@ -387,18 +386,35 @@
alpha.setInterpolator(LINEAR);
launcherAnimator.play(alpha);
- mDragLayer.setTranslationY(trans[0]);
- ObjectAnimator transY = ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y, trans);
- transY.setInterpolator(AGGRESSIVE_EASE);
- transY.setDuration(CONTENT_TRANSLATION_DURATION);
- launcherAnimator.play(transY);
+ Workspace workspace = mLauncher.getWorkspace();
+ View currentPage = ((CellLayout) workspace.getChildAt(workspace.getCurrentPage()))
+ .getShortcutsAndWidgets();
+ View hotseat = mLauncher.getHotseat();
+ View qsb = mLauncher.findViewById(R.id.search_container_all_apps);
- mDragLayer.getScrim().hideSysUiScrim(true);
+ currentPage.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ hotseat.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ qsb.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+ launcherAnimator.play(ObjectAnimator.ofFloat(currentPage, View.TRANSLATION_Y, trans));
+ launcherAnimator.play(ObjectAnimator.ofFloat(hotseat, View.TRANSLATION_Y, trans));
+ launcherAnimator.play(ObjectAnimator.ofFloat(qsb, View.TRANSLATION_Y, trans));
+
// Pause page indicator animations as they lead to layer trashing.
mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
- mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- endListener = this::resetContentView;
+ endListener = () -> {
+ currentPage.setTranslationY(0);
+ hotseat.setTranslationY(0);
+ qsb.setTranslationY(0);
+
+ currentPage.setLayerType(View.LAYER_TYPE_NONE, null);
+ hotseat.setLayerType(View.LAYER_TYPE_NONE, null);
+ qsb.setLayerType(View.LAYER_TYPE_NONE, null);
+
+ mDragLayerAlpha.setValue(1f);
+ mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
+ };
}
return new Pair<>(launcherAnimator, endListener);
}
@@ -596,17 +612,17 @@
// When launching an app from overview that doesn't map to a task, we still want to just
// blur the wallpaper instead of the launcher surface as well
boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW;
- BackgroundBlurController blurController = mLauncher.getBackgroundBlurController();
- ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofInt(blurController, BACKGROUND_BLUR,
- BACKGROUND_APP.getBackgroundBlurRadius(mLauncher))
+ DepthController depthController = mLauncher.getDepthController();
+ ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController, DEPTH,
+ BACKGROUND_APP.getDepth(mLauncher))
.setDuration(APP_LAUNCH_DURATION);
if (allowBlurringLauncher) {
- blurController.setSurfaceToApp(RemoteAnimationProvider.findLowestOpaqueLayerTarget(
+ depthController.setSurfaceToApp(RemoteAnimationProvider.findLowestOpaqueLayerTarget(
appTargets, MODE_OPENING));
backgroundRadiusAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- blurController.setSurfaceToLauncher(mLauncher.getDragLayer());
+ depthController.setSurfaceToLauncher(mLauncher.getDragLayer());
}
});
}
@@ -760,62 +776,6 @@
return closingAnimator;
}
- /**
- * Creates an animator that modifies Launcher as a result from
- * {@link #createWallpaperOpenRunner}.
- */
- private void createLauncherResumeAnimation(AnimatorSet anim) {
- if (mLauncher.isInState(LauncherState.ALL_APPS)) {
- Pair<AnimatorSet, Runnable> contentAnimator =
- getLauncherContentAnimator(false /* isAppOpening */,
- new float[] {-mContentTransY, 0});
- contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY);
- anim.play(contentAnimator.first);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- contentAnimator.second.run();
- }
- });
- } else {
- AnimatorSet workspaceAnimator = new AnimatorSet();
-
- mDragLayer.setTranslationY(-mWorkspaceTransY);;
- workspaceAnimator.play(ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y,
- -mWorkspaceTransY, 0));
-
- mDragLayerAlpha.setValue(0);
- workspaceAnimator.play(ObjectAnimator.ofFloat(
- mDragLayerAlpha, MultiValueAlpha.VALUE, 0, 1f));
-
- workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
- workspaceAnimator.setDuration(333);
- workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7);
-
- mDragLayer.getScrim().hideSysUiScrim(true);
-
- // Pause page indicator animations as they lead to layer trashing.
- mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
- mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-
- workspaceAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- resetContentView();
- }
- });
- anim.play(workspaceAnimator);
- }
- }
-
- private void resetContentView() {
- mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
- mDragLayerAlpha.setValue(1f);
- mDragLayer.setLayerType(View.LAYER_TYPE_NONE, null);
- mDragLayer.setTranslationY(0f);
- mDragLayer.getScrim().hideSysUiScrim(false);
- }
-
private boolean hasControlRemoteAppTransitionPermission() {
return mLauncher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
== PackageManager.PERMISSION_GRANTED;
@@ -888,15 +848,25 @@
// Only register the content animation for cancellation when state changes
mLauncher.getStateManager().setCurrentAnimation(anim);
- if (mFromUnlock) {
+ if (mLauncher.isInState(LauncherState.ALL_APPS)) {
+ Pair<AnimatorSet, Runnable> contentAnimator =
+ getLauncherContentAnimator(false /* isAppOpening */,
+ new float[] {-mContentTransY, 0});
+ contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY);
+ anim.play(contentAnimator.first);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ contentAnimator.second.run();
+ }
+ });
+ } else {
float velocityDpPerS = DynamicResource.provider(mLauncher)
.getDimension(R.dimen.unlock_staggered_velocity_dp_per_s);
float velocityPxPerS = TypedValue.applyDimension(COMPLEX_UNIT_DIP,
velocityDpPerS, mLauncher.getResources().getDisplayMetrics());
anim.play(new StaggeredWorkspaceAnim(mLauncher, velocityPxPerS, false)
.getAnimators());
- } else {
- createLauncherResumeAnimation(anim);
}
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BackgroundBlurController.java b/quickstep/src/com/android/launcher3/uioverrides/BackgroundBlurController.java
deleted file mode 100644
index 513310e..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/BackgroundBlurController.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.uioverrides;
-
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-
-import android.util.IntProperty;
-import android.view.View;
-
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.states.StateAnimationConfig;
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SurfaceControlCompat;
-import com.android.systemui.shared.system.TransactionCompat;
-
-/**
- * Controls the blur, for the Launcher surface only.
- */
-public class BackgroundBlurController implements LauncherStateManager.StateHandler {
-
- public static final IntProperty<BackgroundBlurController> BACKGROUND_BLUR =
- new IntProperty<BackgroundBlurController>("backgroundBlur") {
- @Override
- public void setValue(BackgroundBlurController blurController, int blurRadius) {
- blurController.setBackgroundBlurRadius(blurRadius);
- }
-
- @Override
- public Integer get(BackgroundBlurController blurController) {
- return blurController.mBackgroundBlurRadius;
- }
- };
-
- /**
- * A property that updates the background blur within a given range of values (ie. even if the
- * animator goes beyond 0..1, the interpolated value will still be bounded).
- */
- public static class ClampedBlurProperty extends IntProperty<BackgroundBlurController> {
- private final int mMinValue;
- private final int mMaxValue;
-
- public ClampedBlurProperty(int minValue, int maxValue) {
- super(("backgroundBlurClamped"));
- mMinValue = minValue;
- mMaxValue = maxValue;
- }
-
- @Override
- public void setValue(BackgroundBlurController blurController, int blurRadius) {
- blurController.setBackgroundBlurRadius(Utilities.boundToRange(blurRadius,
- mMinValue, mMaxValue));
- }
-
- @Override
- public Integer get(BackgroundBlurController blurController) {
- return blurController.mBackgroundBlurRadius;
- }
- }
-
- private final Launcher mLauncher;
- private SurfaceControlCompat mSurface;
- private int mBackgroundBlurRadius;
-
- public BackgroundBlurController(Launcher l) {
- mLauncher = l;
- }
-
- /**
- * @return the background blur adjustment for folders
- */
- public int getFolderBackgroundBlurAdjustment() {
- return mLauncher.getResources().getInteger(
- R.integer.folder_background_blur_radius_adjustment);
- }
-
- /**
- * Sets the specified app target surface to apply the blur to.
- */
- public void setSurfaceToApp(RemoteAnimationTargetCompat target) {
- if (target != null) {
- setSurface(target.leash);
- }
- }
-
- /**
- * Sets the surface to apply the blur to as the launcher surface.
- */
- public void setSurfaceToLauncher(View v) {
- setSurface(v != null ? new SurfaceControlCompat(v) : null);
- }
-
- private void setSurface(SurfaceControlCompat surface) {
- if (mSurface != surface) {
- mSurface = surface;
- if (surface != null) {
- setBackgroundBlurRadius(mBackgroundBlurRadius);
- } else {
- // If there is no surface, then reset the blur radius
- setBackgroundBlurRadius(0);
- }
- }
- }
-
- @Override
- public void setState(LauncherState toState) {
- if (mSurface == null) {
- return;
- }
-
- int toBackgroundBlurRadius = toState.getBackgroundBlurRadius(mLauncher);
- if (mBackgroundBlurRadius != toBackgroundBlurRadius) {
- setBackgroundBlurRadius(toBackgroundBlurRadius);
- }
- }
-
- @Override
- public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
- PendingAnimation animation) {
- if (mSurface == null || config.onlyPlayAtomicComponent()) {
- return;
- }
-
- int toBackgroundBlurRadius = toState.getBackgroundBlurRadius(mLauncher);
- if (mBackgroundBlurRadius != toBackgroundBlurRadius) {
- animation.setInt(this, BACKGROUND_BLUR, toBackgroundBlurRadius, LINEAR);
- }
- }
-
- private void setBackgroundBlurRadius(int blurRadius) {
- // TODO: Do nothing if the shadows are not enabled
- // Always update the background blur as it will be reapplied when a surface is next
- // available
- mBackgroundBlurRadius = blurRadius;
- if (mSurface == null || !mSurface.isValid()) {
- return;
- }
- new TransactionCompat()
- .setBackgroundBlurRadius(mSurface, blurRadius)
- .apply();
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DepthController.java b/quickstep/src/com/android/launcher3/uioverrides/DepthController.java
new file mode 100644
index 0000000..8995a7e
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/DepthController.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+
+import android.os.IBinder;
+import android.util.FloatProperty;
+import android.view.View;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.states.StateAnimationConfig;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
+import com.android.systemui.shared.system.SurfaceControlCompat;
+import com.android.systemui.shared.system.TransactionCompat;
+import com.android.systemui.shared.system.WallpaperManagerCompat;
+
+/**
+ * Controls blur and wallpaper zoom, for the Launcher surface only.
+ */
+public class DepthController implements LauncherStateManager.StateHandler {
+
+ public static final FloatProperty<DepthController> DEPTH =
+ new FloatProperty<DepthController>("depth") {
+ @Override
+ public void setValue(DepthController depthController, float depth) {
+ depthController.setDepth(depth);
+ }
+
+ @Override
+ public Float get(DepthController depthController) {
+ return depthController.mDepth;
+ }
+ };
+
+ /**
+ * A property that updates the background blur within a given range of values (ie. even if the
+ * animator goes beyond 0..1, the interpolated value will still be bounded).
+ */
+ public static class ClampedDepthProperty extends FloatProperty<DepthController> {
+ private final float mMinValue;
+ private final float mMaxValue;
+
+ public ClampedDepthProperty(float minValue, float maxValue) {
+ super("depthClamped");
+ mMinValue = minValue;
+ mMaxValue = maxValue;
+ }
+
+ @Override
+ public void setValue(DepthController depthController, float depth) {
+ depthController.setDepth(Utilities.boundToRange(depth, mMinValue, mMaxValue));
+ }
+
+ @Override
+ public Float get(DepthController depthController) {
+ return depthController.mDepth;
+ }
+ }
+
+ private final Launcher mLauncher;
+ /**
+ * Blur radius when completely zoomed out, in pixels.
+ */
+ private int mMaxBlurRadius;
+ private WallpaperManagerCompat mWallpaperManager;
+ private SurfaceControlCompat mSurface;
+ /**
+ * Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in.
+ * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)
+ */
+ private float mDepth;
+
+ public DepthController(Launcher l) {
+ mLauncher = l;
+ }
+
+ private void ensureDependencies() {
+ if (mWallpaperManager != null) {
+ return;
+ }
+ mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
+ mWallpaperManager = new WallpaperManagerCompat(mLauncher);
+ }
+
+ /**
+ * Sets the specified app target surface to apply the blur to.
+ */
+ public void setSurfaceToApp(RemoteAnimationTargetCompat target) {
+ if (target != null) {
+ setSurface(target.leash);
+ }
+ }
+
+ /**
+ * Sets the surface to apply the blur to as the launcher surface.
+ */
+ public void setSurfaceToLauncher(View v) {
+ setSurface(v != null ? new SurfaceControlCompat(v) : null);
+ }
+
+ private void setSurface(SurfaceControlCompat surface) {
+ if (mSurface != surface) {
+ mSurface = surface;
+ if (surface != null) {
+ setDepth(mDepth);
+ } else {
+ // If there is no surface, then reset the ratio
+ setDepth(0f);
+ }
+ }
+ }
+
+ @Override
+ public void setState(LauncherState toState) {
+ if (mSurface == null) {
+ return;
+ }
+
+ float toDepth = toState.getDepth(mLauncher);
+ if (Float.compare(mDepth, toDepth) != 0) {
+ setDepth(toDepth);
+ }
+ }
+
+ @Override
+ public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
+ PendingAnimation animation) {
+ if (mSurface == null || config.onlyPlayAtomicComponent()) {
+ return;
+ }
+
+ float toDepth = toState.getDepth(mLauncher);
+ if (Float.compare(mDepth, toDepth) != 0) {
+ animation.setFloat(this, DEPTH, toDepth, LINEAR);
+ }
+ }
+
+ private void setDepth(float depth) {
+ mDepth = depth;
+ if (mSurface == null || !mSurface.isValid()) {
+ return;
+ }
+ ensureDependencies();
+ IBinder windowToken = mLauncher.getRootView().getWindowToken();
+ if (windowToken != null) {
+ mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
+ }
+ new TransactionCompat()
+ .setBackgroundBlurRadius(mSurface, (int) (mDepth * mMaxBlurRadius))
+ .apply();
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PreviewSurfaceRenderer.java b/quickstep/src/com/android/launcher3/uioverrides/PreviewSurfaceRenderer.java
index 548223a..c7cce0b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PreviewSurfaceRenderer.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PreviewSurfaceRenderer.java
@@ -32,8 +32,11 @@
/** Handle a received surface view request. */
public static void render(Context context, Bundle bundle) {
- final String gridName = bundle.getString("name");
+ String gridName = bundle.getString("name");
bundle.remove("name");
+ if (gridName == null) {
+ gridName = InvariantDeviceProfile.getCurrentGridName(context);
+ }
final InvariantDeviceProfile idp = new InvariantDeviceProfile(context, gridName);
MAIN_EXECUTOR.execute(() -> {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 971d917..93e02a1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -22,7 +22,6 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.SysUINavigationMode;
@@ -88,8 +87,8 @@
}
@Override
- public int getBackgroundBlurRadius(Context context) {
- return context.getResources().getInteger(R.integer.allapps_background_blur_radius);
+ public float getDepth(Context context) {
+ return 1f;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index be0bdd8..2a569f5 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -33,7 +33,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
+import com.android.launcher3.uioverrides.DepthController;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.ShelfPeekAnim;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -81,7 +81,8 @@
@Nullable
T getCreatedActivity();
- default @Nullable BackgroundBlurController getBackgroundBlurController() {
+ @Nullable
+ default DepthController getDepthController() {
return null;
}
diff --git a/res/layout/work_tab_footer.xml b/res/layout/work_tab_footer.xml
index dbcdbdb..264e273 100644
--- a/res/layout/work_tab_footer.xml
+++ b/res/layout/work_tab_footer.xml
@@ -41,6 +41,7 @@
android:lines="1"
android:minHeight="24dp"
android:paddingEnd="12dp"
+ android:text="@string/work_profile_toggle_label"
android:textSize="16sp"/>
<com.android.launcher3.allapps.WorkModeSwitch
android:id="@+id/work_mode_toggle"
diff --git a/res/values/config.xml b/res/values/config.xml
index 6c239bd..1675a98 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -176,4 +176,7 @@
<item>@dimen/swipe_up_fling_min_visible_change</item>
<item>@dimen/swipe_up_y_overshoot</item>
</array>
+
+ <string-array name="live_wallpapers_remove_sysui_scrims">
+ </string-array>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7748b3a..b1077be 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -328,22 +328,21 @@
<!-- This string is in the work profile tab when a user has All Apps open on their phone. This is a label for a toggle to turn the work profile on and off. "Work profile" means a separate profile on a user's phone that's specifically for their work apps and managed by their company. "Work" is used as an adjective.-->
<string name="work_profile_toggle_label">Work profile</string>
<!--- User onboarding title for personal apps -->
- <string name="work_profile_edu_personal_apps">Personal apps are private & can\'t be seen by IT</string>
+ <string name="work_profile_edu_personal_apps">Personal data is separate & hidden from work apps</string>
<!--- User onboarding title for work profile apps -->
- <string name="work_profile_edu_work_apps">Work apps are badged & visible to IT</string>
+ <string name="work_profile_edu_work_apps">Work apps & data are visible to your IT admin</string>
<!-- Action label to proceed to the next work profile edu section-->
<string name="work_profile_edu_next">Next</string>
<!-- Action label to finish work profile edu-->
<string name="work_profile_edu_accept">Got it</string>
- <!-- This string is in the work profile tab when a user has All Apps open on their phone. It describes the label of a toggle, "Work profile," as being managed by the user's employer.
- "Organization" is used to represent a variety of businesses, non-profits, and educational institutions).-->
- <string name="work_mode_on_label">Work apps: On</string>
- <!-- This string appears under a the label of a toggle in the work profile tab on a user's phone. It describes the status of the toggle, "Work profile," when it's turned off. "Work profile" means a separate profile on a user's phone that's speficially for their work apps and is managed by their company.-->
- <string name="work_mode_off_label">Work apps: Paused</string>
+ <!--- 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_title">Work apps are paused</string>
- <string name="work_apps_paused_body">You won\'t get any work notifications, and your IT admin can\'t see your location</string>
+ <!-- A tip shown pointing at work toggle -->
+ <string name="work_switch_tip">Pause work apps and notifications</string>
<!-- Failed action error message: e.g. Failed: Pause -->
<string name="remote_action_failed">Failed: <xliff:g id="what" example="Pause">%1$s</xliff:g></string>
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 12b5fc1..bed8278 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -180,7 +180,10 @@
return null;
}
- protected static <T extends AbstractFloatingView> T getOpenView(
+ /**
+ * Returns a view matching FloatingViewType
+ */
+ public static <T extends AbstractFloatingView> T getOpenView(
ActivityContext activity, @FloatingViewType int type) {
BaseDragLayer dragLayer = activity.getDragLayer();
if (dragLayer == null) return null;
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 2b0da43..34d7067 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -155,7 +155,7 @@
@Override
public final void onDragEnter(DragObject d) {
- if (!d.accessibleDrag && !mTextVisible) {
+ if (!mAccessibleDrag && !mTextVisible) {
// Show tooltip
hideTooltip();
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index e3eb387..f2d07f2 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -53,8 +53,6 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
-import com.android.launcher3.accessibility.FolderAccessibilityHelper;
-import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.config.FeatureFlags;
@@ -79,9 +77,6 @@
import java.util.Stack;
public class CellLayout extends ViewGroup implements Transposable {
- public static final int WORKSPACE_ACCESSIBILITY_DRAG = 2;
- public static final int FOLDER_ACCESSIBILITY_DRAG = 1;
-
private static final String TAG = "CellLayout";
private static final boolean LOGD = false;
@@ -182,7 +177,6 @@
private static final Paint sPaint = new Paint();
// Related to accessible drag and drop
- private DragAndDropAccessibilityDelegate mTouchHelper;
private boolean mUseTouchHelper = false;
private RotationMode mRotationMode = RotationMode.NORMAL;
@@ -292,26 +286,20 @@
addView(mShortcutsAndWidgets);
}
- public void enableAccessibleDrag(boolean enable, int dragType) {
- mUseTouchHelper = enable;
- if (!enable) {
- ViewCompat.setAccessibilityDelegate(this, null);
- setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
- getShortcutsAndWidgets().setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
- setOnClickListener(null);
- } else {
- if (dragType == WORKSPACE_ACCESSIBILITY_DRAG &&
- !(mTouchHelper instanceof WorkspaceAccessibilityHelper)) {
- mTouchHelper = new WorkspaceAccessibilityHelper(this);
- } else if (dragType == FOLDER_ACCESSIBILITY_DRAG &&
- !(mTouchHelper instanceof FolderAccessibilityHelper)) {
- mTouchHelper = new FolderAccessibilityHelper(this);
- }
- ViewCompat.setAccessibilityDelegate(this, mTouchHelper);
- setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
- getShortcutsAndWidgets().setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
- setOnClickListener(mTouchHelper);
- }
+
+ /**
+ * Sets or clears a delegate used for accessible drag and drop
+ */
+ public void setDragAndDropAccessibilityDelegate(DragAndDropAccessibilityDelegate delegate) {
+ setOnClickListener(delegate);
+ setOnHoverListener(delegate);
+ ViewCompat.setAccessibilityDelegate(this, delegate);
+
+ mUseTouchHelper = delegate != null;
+ int accessibilityFlag = mUseTouchHelper
+ ? IMPORTANT_FOR_ACCESSIBILITY_YES : IMPORTANT_FOR_ACCESSIBILITY_NO;
+ setImportantForAccessibility(accessibilityFlag);
+ getShortcutsAndWidgets().setImportantForAccessibility(accessibilityFlag);
// Invalidate the accessibility hierarchy
if (getParent() != null) {
@@ -339,15 +327,6 @@
}
@Override
- public boolean dispatchHoverEvent(MotionEvent event) {
- // Always attempt to dispatch hover events to accessibility first.
- if (mUseTouchHelper && mTouchHelper.dispatchHoverEvent(event)) {
- return true;
- }
- return super.dispatchHoverEvent(event);
- }
-
- @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (mUseTouchHelper ||
(mInterceptTouchListener != null && mInterceptTouchListener.onTouch(this, ev))) {
@@ -2787,7 +2766,6 @@
* Finds solution to accept hotseat migration to cell layout. commits solution if commitConfig
*/
public boolean makeSpaceForHotseatMigration(boolean commitConfig) {
- if (FeatureFlags.HOTSEAT_MIGRATE_NEW_PAGE.get()) return false;
int[] cellPoint = new int[2];
int[] directionVector = new int[]{0, -1};
cellToPoint(0, mCountY, cellPoint);
@@ -2797,12 +2775,23 @@
if (commitConfig) {
copySolutionToTempState(configuration, null);
commitTempPlacement();
+ // undo marking cells occupied since there is actually nothing being placed yet.
+ mOccupied.markCells(0, mCountY - 1, mCountX, 1, false);
}
return true;
}
return false;
}
+ /**
+ * returns a copy of cell layout's grid occupancy
+ */
+ public GridOccupancy cloneGridOccupancy() {
+ GridOccupancy occupancy = new GridOccupancy(mCountX, mCountY);
+ mOccupied.copyTo(occupancy);
+ return occupancy;
+ }
+
public boolean isRegionVacant(int x, int y, int spanX, int spanY) {
return mOccupied.isRegionVacant(x, y, spanX, spanY);
}
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index a32fd12..c03011b 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -59,9 +59,6 @@
/** Where the drag originated */
public DragSource dragSource = null;
- /** The object is part of an accessible drag operation */
- public boolean accessibleDrag;
-
/** Indicates that the drag operation was cancelled */
public boolean cancelled = false;
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 2ad84b9..7414a88 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -162,9 +162,7 @@
"PreviewContext is passed into this IDP constructor");
}
- String gridName = Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)
- ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null)
- : null;
+ String gridName = getCurrentGridName(context);
initGrid(context, gridName);
mConfigMonitor = new ConfigMonitor(context,
APPLY_CONFIG_AT_RUNTIME.get() ? this::onConfigChanged : this::killProcess);
@@ -188,6 +186,12 @@
initGrid(context, null, new Info(display));
}
+ public static String getCurrentGridName(Context context) {
+ return Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)
+ ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null)
+ : null;
+ }
+
/**
* Retrieve system defined or RRO overriden icon shape.
*/
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1413a5c..a83a694 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -124,7 +124,7 @@
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
+import com.android.launcher3.uioverrides.DepthController;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -326,19 +326,21 @@
private boolean mDeferOverlayCallbacks;
private final Runnable mDeferredOverlayCallbacks = this::checkIfOverlayStillDeferred;
- private BackgroundBlurController mBackgroundBlurController =
- new BackgroundBlurController(this);
+ private DepthController mDepthController =
+ new DepthController(this);
private final ViewTreeObserver.OnDrawListener mOnDrawListener =
new ViewTreeObserver.OnDrawListener() {
@Override
public void onDraw() {
- getBackgroundBlurController().setSurfaceToLauncher(mDragLayer);
+ getDepthController().setSurfaceToLauncher(mDragLayer);
mDragLayer.post(() -> mDragLayer.getViewTreeObserver().removeOnDrawListener(
this));
}
};
+ private long mLastTouchUpTime = -1;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
Object traceToken = TraceHelper.INSTANCE.beginSection(ON_CREATE_EVT,
@@ -954,7 +956,7 @@
NotificationListener.removeNotificationsChangedListener();
getStateManager().moveToRestState();
- getBackgroundBlurController().setSurfaceToLauncher(null);
+ getDepthController().setSurfaceToLauncher(null);
// Workaround for b/78520668, explicitly trim memory once UI is hidden
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
@@ -1115,7 +1117,7 @@
super.onPause();
mDragController.cancelDrag();
- mDragController.resetLastGestureUpTime();
+ mLastTouchUpTime = -1;
mDropTargetBar.animateToVisibility(false);
if (!mDeferOverlayCallbacks) {
@@ -1838,6 +1840,9 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_UP) {
+ mLastTouchUpTime = System.currentTimeMillis();
+ }
TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
return super.dispatchTouchEvent(ev);
}
@@ -2465,8 +2470,12 @@
}
private boolean canRunNewAppsAnimation() {
- long diff = System.currentTimeMillis() - mDragController.getLastGestureUpTime();
- return diff > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);
+ if (mDragController.isDragging()) {
+ return false;
+ } else {
+ return (System.currentTimeMillis() - mLastTouchUpTime)
+ > (NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS * 1000);
+ }
}
private ValueAnimator createNewAppBounceAnimation(View v, int i) {
@@ -2708,7 +2717,7 @@
protected StateHandler[] createStateHandlers() {
return new StateHandler[] { getAllAppsController(), getWorkspace(),
- getBackgroundBlurController() };
+ getDepthController() };
}
public TouchController[] createTouchControllers() {
@@ -2745,8 +2754,8 @@
return Stream.of(APP_INFO, WIDGETS, INSTALL);
}
- public BackgroundBlurController getBackgroundBlurController() {
- return mBackgroundBlurController;
+ public DepthController getDepthController() {
+ return mDepthController;
}
public static Launcher getLauncher(Context context) {
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index df71f16..6ee82cd 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -271,11 +271,13 @@
}
/**
- * The amount of blur to apply to the background of either the app or Launcher surface in this
- * state.
+ * The amount of blur and wallpaper zoom to apply to the background of either the app
+ * or Launcher surface in this state. Should be a number between 0 and 1, inclusive.
+ *
+ * 0 means completely zoomed in, without blurs. 1 is zoomed out, with blurs.
*/
- public int getBackgroundBlurRadius(Context context) {
- return 0;
+ public float getDepth(Context context) {
+ return 0f;
}
public String getDescription(Launcher launcher) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ead6018..46493b7 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -192,10 +192,7 @@
final WallpaperOffsetInterpolator mWallpaperOffset;
private boolean mUnlockWallpaperFromDefaultPageOnLayout;
- // Variables relating to the creation of user folders by hovering shortcuts over shortcuts
- private static final int FOLDER_CREATION_TIMEOUT = 0;
public static final int REORDER_TIMEOUT = 650;
- private final Alarm mFolderCreationAlarm = new Alarm();
private final Alarm mReorderAlarm = new Alarm();
private PreviewBackground mFolderCreateBg;
private FolderIcon mDragOverFolderIcon = null;
@@ -567,11 +564,6 @@
addView(newScreen, insertIndex);
mStateTransitionAnimation.applyChildState(
mLauncher.getStateManager().getState(), newScreen, insertIndex);
-
- if (mLauncher.getAccessibilityDelegate().isInAccessibleDrag()) {
- newScreen.enableAccessibleDrag(true, CellLayout.WORKSPACE_ACCESSIBILITY_DRAG);
- }
-
return newScreen;
}
@@ -818,11 +810,6 @@
if (indexOfChild(cl) < currentPage) {
pageShift++;
}
-
- if (isInAccessibleDrag) {
- cl.enableAccessibleDrag(false, CellLayout.WORKSPACE_ACCESSIBILITY_DRAG);
- }
-
removeView(cl);
} else {
// if this is the last screen, convert it to the empty screen
@@ -1444,14 +1431,14 @@
child.setVisibility(INVISIBLE);
if (options.isAccessibleDrag) {
- mDragController.addDragListener(new AccessibleDragListenerAdapter(
- this, CellLayout.WORKSPACE_ACCESSIBILITY_DRAG) {
- @Override
- protected void enableAccessibleDrag(boolean enable) {
- super.enableAccessibleDrag(enable);
- setEnableForLayout(mLauncher.getHotseat(),enable);
- }
- });
+ mDragController.addDragListener(
+ new AccessibleDragListenerAdapter(this, WorkspaceAccessibilityHelper::new) {
+ @Override
+ protected void enableAccessibleDrag(boolean enable) {
+ super.enableAccessibleDrag(enable);
+ setEnableForLayout(mLauncher.getHotseat(), enable);
+ }
+ });
}
beginDragShared(child, this, options);
@@ -1883,12 +1870,10 @@
final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) cell;
AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
if (pInfo != null && pInfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE
- && !d.accessibleDrag) {
- onCompleteRunnable = new Runnable() {
- public void run() {
- if (!isPageInTransition()) {
- AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
- }
+ && !options.isAccessibleDrag) {
+ onCompleteRunnable = () -> {
+ if (!isPageInTransition()) {
+ AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
}
};
}
@@ -2088,8 +2073,6 @@
if (mFolderCreateBg != null) {
mFolderCreateBg.animateToRest();
}
- mFolderCreationAlarm.setOnAlarmListener(null);
- mFolderCreationAlarm.cancelAlarm();
}
private void cleanupAddToFolder() {
@@ -2196,7 +2179,7 @@
float targetCellDistance = mDragTargetLayout.getDistanceFromCell(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
- manageFolderFeedback(mDragTargetLayout, mTargetCell, targetCellDistance, d);
+ manageFolderFeedback(targetCellDistance, d);
boolean nearestDropOccupied = mDragTargetLayout.isNearestDropLocationOccupied((int)
mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX,
@@ -2294,8 +2277,7 @@
return null;
}
- private void manageFolderFeedback(CellLayout targetLayout,
- int[] targetCell, float distance, DragObject dragObject) {
+ private void manageFolderFeedback(float distance, DragObject dragObject) {
if (distance > mMaxDistanceForFolderCreation) {
if (mDragMode != DRAG_MODE_NONE) {
setDragMode(DRAG_MODE_NONE);
@@ -2306,18 +2288,18 @@
final View dragOverView = mDragTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]);
ItemInfo info = dragObject.dragInfo;
boolean userFolderPending = willCreateUserFolder(info, dragOverView, false);
- if (mDragMode == DRAG_MODE_NONE && userFolderPending &&
- !mFolderCreationAlarm.alarmPending()) {
+ if (mDragMode == DRAG_MODE_NONE && userFolderPending) {
- FolderCreationAlarmListener listener = new
- FolderCreationAlarmListener(targetLayout, targetCell[0], targetCell[1]);
+ mFolderCreateBg = new PreviewBackground();
+ mFolderCreateBg.setup(mLauncher, mLauncher, null,
+ dragOverView.getMeasuredWidth(), dragOverView.getPaddingTop());
- if (!dragObject.accessibleDrag) {
- mFolderCreationAlarm.setOnAlarmListener(listener);
- mFolderCreationAlarm.setAlarm(FOLDER_CREATION_TIMEOUT);
- } else {
- listener.onAlarm(mFolderCreationAlarm);
- }
+ // The full preview background should appear behind the icon
+ mFolderCreateBg.isClipping = false;
+
+ mFolderCreateBg.animateToAccept(mDragTargetLayout, mTargetCell[0], mTargetCell[1]);
+ mDragTargetLayout.clearDragOutlines();
+ setDragMode(DRAG_MODE_CREATE_FOLDER);
if (dragObject.stateAnnouncer != null) {
dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper
@@ -2330,8 +2312,8 @@
if (willAddToFolder && mDragMode == DRAG_MODE_NONE) {
mDragOverFolderIcon = ((FolderIcon) dragOverView);
mDragOverFolderIcon.onDragEnter(info);
- if (targetLayout != null) {
- targetLayout.clearDragOutlines();
+ if (mDragTargetLayout != null) {
+ mDragTargetLayout.clearDragOutlines();
}
setDragMode(DRAG_MODE_ADD_TO_FOLDER);
@@ -2350,33 +2332,6 @@
}
}
- class FolderCreationAlarmListener implements OnAlarmListener {
- final CellLayout layout;
- final int cellX;
- final int cellY;
-
- final PreviewBackground bg = new PreviewBackground();
-
- public FolderCreationAlarmListener(CellLayout layout, int cellX, int cellY) {
- this.layout = layout;
- this.cellX = cellX;
- this.cellY = cellY;
-
- BubbleTextView cell = (BubbleTextView) layout.getChildAt(cellX, cellY);
- bg.setup(mLauncher, mLauncher, null, cell.getMeasuredWidth(), cell.getPaddingTop());
-
- // The full preview background should appear behind the icon
- bg.isClipping = false;
- }
-
- public void onAlarm(Alarm alarm) {
- mFolderCreateBg = bg;
- mFolderCreateBg.animateToAccept(layout, cellX, cellY);
- layout.clearDragOutlines();
- setDragMode(DRAG_MODE_CREATE_FOLDER);
- }
- }
-
class ReorderAlarmListener implements OnAlarmListener {
final float[] dragViewCenter;
final int minSpanX, minSpanY, spanX, spanY;
diff --git a/src/com/android/launcher3/accessibility/AccessibleDragListenerAdapter.java b/src/com/android/launcher3/accessibility/AccessibleDragListenerAdapter.java
index f8df5d7..0d7df2b 100644
--- a/src/com/android/launcher3/accessibility/AccessibleDragListenerAdapter.java
+++ b/src/com/android/launcher3/accessibility/AccessibleDragListenerAdapter.java
@@ -16,7 +16,9 @@
package com.android.launcher3.accessibility;
+import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewGroup.OnHierarchyChangeListener;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DropTarget.DragObject;
@@ -24,36 +26,55 @@
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
+import java.util.function.Function;
+
/**
* Utility listener to enable/disable accessibility drag flags for a ViewGroup
* containing CellLayouts
*/
-public class AccessibleDragListenerAdapter implements DragListener {
+public class AccessibleDragListenerAdapter implements DragListener, OnHierarchyChangeListener {
private final ViewGroup mViewGroup;
- private final int mDragType;
+ private final Function<CellLayout, DragAndDropAccessibilityDelegate> mDelegateFactory;
/**
- * @param parent
- * @param dragType either {@link CellLayout#WORKSPACE_ACCESSIBILITY_DRAG} or
- * {@link CellLayout#FOLDER_ACCESSIBILITY_DRAG}
+ * @param parent the viewgroup containing all the children
+ * @param delegateFactory function to create no delegates
*/
- public AccessibleDragListenerAdapter(ViewGroup parent, int dragType) {
+ public AccessibleDragListenerAdapter(ViewGroup parent,
+ Function<CellLayout, DragAndDropAccessibilityDelegate> delegateFactory) {
mViewGroup = parent;
- mDragType = dragType;
+ mDelegateFactory = delegateFactory;
}
@Override
public void onDragStart(DragObject dragObject, DragOptions options) {
+ mViewGroup.setOnHierarchyChangeListener(this);
enableAccessibleDrag(true);
}
@Override
public void onDragEnd() {
+ mViewGroup.setOnHierarchyChangeListener(null);
enableAccessibleDrag(false);
Launcher.getLauncher(mViewGroup.getContext()).getDragController().removeDragListener(this);
}
+
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ if (parent == mViewGroup) {
+ setEnableForLayout((CellLayout) child, true);
+ }
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ if (parent == mViewGroup) {
+ setEnableForLayout((CellLayout) child, false);
+ }
+ }
+
protected void enableAccessibleDrag(boolean enable) {
for (int i = 0; i < mViewGroup.getChildCount(); i++) {
setEnableForLayout((CellLayout) mViewGroup.getChildAt(i), enable);
@@ -61,6 +82,6 @@
}
protected final void setEnableForLayout(CellLayout layout, boolean enable) {
- layout.enableAccessibleDrag(enable, mDragType);
+ layout.setDragAndDropAccessibilityDelegate(enable ? mDelegateFactory.apply(layout) : null);
}
}
diff --git a/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java
index 117296d..ddb547f 100644
--- a/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/DragAndDropAccessibilityDelegate.java
@@ -19,24 +19,26 @@
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
+import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.View.OnHoverListener;
import android.view.accessibility.AccessibilityEvent;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
+import androidx.customview.widget.ExploreByTouchHelper;
+
import com.android.launcher3.CellLayout;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import java.util.List;
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
-import androidx.customview.widget.ExploreByTouchHelper;
-
/**
* Helper class to make drag-and-drop in a {@link CellLayout} accessible.
*/
public abstract class DragAndDropAccessibilityDelegate extends ExploreByTouchHelper
- implements OnClickListener {
+ implements OnClickListener, OnHoverListener {
protected static final int INVALID_POSITION = -1;
private static final int[] sTempArray = new int[2];
@@ -123,6 +125,11 @@
node.setFocusable(true);
}
+ @Override
+ public boolean onHover(View view, MotionEvent motionEvent) {
+ return dispatchHoverEvent(motionEvent);
+ }
+
protected abstract String getLocationDescriptionForIconDrop(int id);
protected abstract String getConfirmationForIconDrop(int id);
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 0b439ec..6f7f8e6 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -7,6 +7,7 @@
import android.app.AlertDialog;
import android.appwidget.AppWidgetProviderInfo;
import android.content.DialogInterface;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -400,11 +401,11 @@
Rect pos = new Rect();
mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
- mLauncher.getDragController().prepareAccessibleDrag(pos.centerX(), pos.centerY());
mLauncher.getDragController().addDragListener(this);
DragOptions options = new DragOptions();
options.isAccessibleDrag = true;
+ options.simulatedDndStartPoint = new Point(pos.centerX(), pos.centerY());
ItemLongClickListener.beginDrag(item, mLauncher, info, options);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index c4b2f68..a6ef10a 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -18,6 +18,7 @@
import static com.android.launcher3.AppInfo.COMPONENT_KEY_COMPARATOR;
import static com.android.launcher3.AppInfo.EMPTY_ARRAY;
+import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -55,6 +56,8 @@
private int mDeferUpdatesFlags = 0;
private boolean mUpdatePending = false;
+ private boolean mListenerUpdateInProgress = false;
+
public AppInfo[] getApps() {
return mApps;
}
@@ -99,10 +102,12 @@
mUpdatePending = true;
return;
}
+ mListenerUpdateInProgress = true;
int count = mUpdateListeners.size();
for (int i = 0; i < count; i++) {
mUpdateListeners.get(i).onAppsUpdated();
}
+ mListenerUpdateInProgress = false;
}
public void addUpdateListener(OnUpdateListener listener) {
@@ -110,6 +115,9 @@
}
public void removeUpdateListener(OnUpdateListener listener) {
+ if (mListenerUpdateInProgress) {
+ Log.e("AllAppsStore", "Trying to remove listener during update", new Exception());
+ }
mUpdateListeners.remove(listener);
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 0237b50..4df3b0a 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -120,12 +120,11 @@
"ASSISTANT_GIVES_LAUNCHER_FOCUS", false,
"Allow Launcher to handle nav bar gestures while Assistant is running over it");
- public static final BooleanFlag ENABLE_HYBRID_HOTSEAT = getDebugFlag(
+ public static final BooleanFlag ENABLE_HYBRID_HOTSEAT = new DeviceFlag(
"ENABLE_HYBRID_HOTSEAT", false, "Fill gaps in hotseat with predicted apps");
- public static final BooleanFlag HOTSEAT_MIGRATE_NEW_PAGE = getDebugFlag(
- "HOTSEAT_MIGRATE_NEW_PAGE", false,
- "Migrates hotseat to a new workspace page instead of same page");
+ public static final BooleanFlag HOTSEAT_MIGRATE_TO_FOLDER = new DeviceFlag(
+ "HOTSEAT_MIGRATE_TO_FOLDER", false, "Should move hotseat items into a folder");
public static final BooleanFlag ENABLE_DEEP_SHORTCUT_ICON_CACHE = getDebugFlag(
"ENABLE_DEEP_SHORTCUT_ICON_CACHE", true, "R/W deep shortcut in IconCache");
@@ -137,7 +136,7 @@
"ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", true, "Show launcher preview in grid picker");
public static final BooleanFlag USE_SURFACE_VIEW_FOR_GRID_PREVIEW = getDebugFlag(
- "USE_SURFACE_VIEW_FOR_GRID_PREVIEW", false, "Use surface view for grid preview");
+ "USE_SURFACE_VIEW_FOR_GRID_PREVIEW", true, "Use surface view for grid preview");
public static final BooleanFlag ENABLE_OVERVIEW_ACTIONS = getDebugFlag(
"ENABLE_OVERVIEW_ACTIONS", true, "Show app actions instead of the shelf in Overview."
diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
index 75693c6..9b91a1d 100644
--- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java
@@ -26,7 +26,6 @@
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
-import android.os.SystemClock;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
@@ -63,7 +62,6 @@
protected Launcher mLauncher;
private DragController mDragController;
- private long mDragStartTime;
public BaseItemDragListener(Rect previewRect, int previewBitmapWidth, int previewViewWidth) {
mPreviewRect = previewRect;
@@ -102,7 +100,7 @@
return false;
}
}
- return mDragController.onDragEvent(mDragStartTime, event);
+ return mDragController.onDragEvent(event);
}
protected boolean onDragStart(DragEvent event) {
@@ -118,7 +116,7 @@
Point downPos = new Point((int) event.getX(), (int) event.getY());
DragOptions options = new DragOptions();
- options.systemDndStartPoint = downPos;
+ options.simulatedDndStartPoint = downPos;
options.preDragCondition = preDragCondition;
// We use drag event position as the screenPos for the preview image. Since mPreviewRect
@@ -128,7 +126,6 @@
// to source window.
createDragHelper().startDrag(new Rect(mPreviewRect),
mPreviewBitmapWidth, mPreviewViewWidth, downPos, this, options);
- mDragStartTime = SystemClock.uptimeMillis();
return true;
}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index de7bc6d..1539747 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -43,7 +43,6 @@
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.UiThreadHelper;
@@ -61,8 +60,8 @@
*/
private static final int DEEP_PRESS_DISTANCE_FACTOR = 3;
- @Thunk Launcher mLauncher;
- private FlingToDeleteHelper mFlingToDeleteHelper;
+ private final Launcher mLauncher;
+ private final FlingToDeleteHelper mFlingToDeleteHelper;
// temporaries to avoid gc thrash
private Rect mRectTemp = new Rect();
@@ -77,11 +76,12 @@
/** Options controlling the drag behavior. */
private DragOptions mOptions;
- /** X coordinate of the down event. */
- private int mMotionDownX;
+ /** Coordinate for motion down event */
+ private final Point mMotionDown = new Point();
+ /** Coordinate for last touch event **/
+ private final Point mLastTouch = new Point();
- /** Y coordinate of the down event. */
- private int mMotionDownY;
+ private final Point mTmpPoint = new Point();
private DropTarget.DragObject mDragObject;
@@ -96,12 +96,9 @@
private DropTarget mLastDropTarget;
- private final int[] mLastTouch = new int[2];
- private long mLastTouchUpTime = -1;
private int mLastTouchClassification;
private int mDistanceSinceScroll = 0;
- private int mTmpPoint[] = new int[2];
private Rect mDragLayerRect = new Rect();
private boolean mIsInPreDrag;
@@ -159,13 +156,13 @@
AbstractFloatingView.closeOpenViews(mLauncher, false, TYPE_DISCOVERY_BOUNCE);
mOptions = options;
- if (mOptions.systemDndStartPoint != null) {
- mLastTouch[0] = mMotionDownX = mOptions.systemDndStartPoint.x;
- mLastTouch[1] = mMotionDownY = mOptions.systemDndStartPoint.y;
+ if (mOptions.simulatedDndStartPoint != null) {
+ mLastTouch.x = mMotionDown.x = mOptions.simulatedDndStartPoint.x;
+ mLastTouch.y = mMotionDown.y = mOptions.simulatedDndStartPoint.y;
}
- final int registrationX = mMotionDownX - dragLayerX;
- final int registrationY = mMotionDownY - dragLayerY;
+ final int registrationX = mMotionDown.x - dragLayerX;
+ final int registrationY = mMotionDown.y - dragLayerY;
final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
@@ -184,17 +181,13 @@
registrationY, initialDragViewScale, dragViewScaleOnDrop, scaleDps);
dragView.setItemInfo(dragInfo);
mDragObject.dragComplete = false;
- if (mOptions.isAccessibleDrag) {
- // For an accessible drag, we assume the view is being dragged from the center.
- mDragObject.xOffset = b.getWidth() / 2;
- mDragObject.yOffset = b.getHeight() / 2;
- mDragObject.accessibleDrag = true;
- } else {
- mDragObject.xOffset = mMotionDownX - (dragLayerX + dragRegionLeft);
- mDragObject.yOffset = mMotionDownY - (dragLayerY + dragRegionTop);
- mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
- mDragDriver = DragDriver.create(mLauncher, this, mDragObject, mOptions);
+ mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft);
+ mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop);
+
+ mDragDriver = DragDriver.create(this, mOptions, mFlingToDeleteHelper::recordMotionEvent);
+ if (!mOptions.isAccessibleDrag) {
+ mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
}
mDragObject.dragSource = source;
@@ -210,7 +203,7 @@
}
mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
- dragView.show(mLastTouch[0], mLastTouch[1]);
+ dragView.show(mLastTouch.x, mLastTouch.y);
mDistanceSinceScroll = 0;
if (!mIsInPreDrag) {
@@ -219,7 +212,7 @@
mOptions.preDragCondition.onPreDragStart(mDragObject);
}
- handleMoveEvent(mLastTouch[0], mLastTouch[1]);
+ handleMoveEvent(mLastTouch.x, mLastTouch.y);
mLauncher.getUserEventDispatcher().resetActionDurationMillis();
return dragView;
}
@@ -336,7 +329,7 @@
}
}
};
- mDragObject.dragView.animateTo(mMotionDownX, mMotionDownY, onCompleteRunnable, duration);
+ mDragObject.dragView.animateTo(mMotionDown.x, mMotionDown.y, onCompleteRunnable, duration);
}
private void callOnDragEnd() {
@@ -365,30 +358,17 @@
/**
* Clamps the position to the drag layer bounds.
*/
- private int[] getClampedDragLayerPos(float x, float y) {
+ private Point getClampedDragLayerPos(float x, float y) {
mLauncher.getDragLayer().getLocalVisibleRect(mDragLayerRect);
- mTmpPoint[0] = (int) Math.max(mDragLayerRect.left, Math.min(x, mDragLayerRect.right - 1));
- mTmpPoint[1] = (int) Math.max(mDragLayerRect.top, Math.min(y, mDragLayerRect.bottom - 1));
+ mTmpPoint.x = (int) Math.max(mDragLayerRect.left, Math.min(x, mDragLayerRect.right - 1));
+ mTmpPoint.y = (int) Math.max(mDragLayerRect.top, Math.min(y, mDragLayerRect.bottom - 1));
return mTmpPoint;
}
- public long getLastGestureUpTime() {
- if (mDragDriver != null) {
- return System.currentTimeMillis();
- } else {
- return mLastTouchUpTime;
- }
- }
-
- public void resetLastGestureUpTime() {
- mLastTouchUpTime = -1;
- }
-
@Override
public void onDriverDragMove(float x, float y) {
- final int[] dragLayerPos = getClampedDragLayerPos(x, y);
-
- handleMoveEvent(dragLayerPos[0], dragLayerPos[1]);
+ Point dragLayerPos = getClampedDragLayerPos(x, y);
+ handleMoveEvent(dragLayerPos.x, dragLayerPos.y);
}
@Override
@@ -422,53 +402,38 @@
/**
* Call this from a drag source view.
*/
+ @Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (mOptions != null && mOptions.isAccessibleDrag) {
return false;
}
- // Update the velocity tracker
- mFlingToDeleteHelper.recordMotionEvent(ev);
+ Point dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
+ mLastTouch.set(dragLayerPos.x, dragLayerPos.y);
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ // Remember location of down touch
+ mMotionDown.set(dragLayerPos.x, dragLayerPos.y);
+ }
- final int action = ev.getAction();
- final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
- final int dragLayerX = dragLayerPos[0];
- final int dragLayerY = dragLayerPos[1];
- mLastTouch[0] = dragLayerX;
- mLastTouch[1] = dragLayerY;
if (ATLEAST_Q) {
mLastTouchClassification = ev.getClassification();
}
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- // Remember location of down touch
- mMotionDownX = dragLayerX;
- mMotionDownY = dragLayerY;
- break;
- case MotionEvent.ACTION_UP:
- mLastTouchUpTime = System.currentTimeMillis();
- break;
- }
-
return mDragDriver != null && mDragDriver.onInterceptTouchEvent(ev);
}
/**
* Call this from a drag source view.
*/
- public boolean onDragEvent(long dragStartTime, DragEvent event) {
- mFlingToDeleteHelper.recordDragEvent(dragStartTime, event);
- return mDragDriver != null && mDragDriver.onDragEvent(event);
+ @Override
+ public boolean onControllerTouchEvent(MotionEvent ev) {
+ return mDragDriver != null && mDragDriver.onTouchEvent(ev);
}
/**
- * Call this from a drag view.
+ * Call this from a drag source view.
*/
- public void onDragViewAnimationEnd() {
- if (mDragDriver != null) {
- mDragDriver.onDragViewAnimationEnd();
- }
+ public boolean onDragEvent(DragEvent event) {
+ return mDragDriver != null && mDragDriver.onDragEvent(event);
}
/**
@@ -493,9 +458,8 @@
checkTouchMove(dropTarget);
// Check if we are hovering over the scroll areas
- mDistanceSinceScroll += Math.hypot(mLastTouch[0] - x, mLastTouch[1] - y);
- mLastTouch[0] = x;
- mLastTouch[1] = y;
+ mDistanceSinceScroll += Math.hypot(mLastTouch.x - x, mLastTouch.y - y);
+ mLastTouch.set(x, y);
int distanceDragged = mDistanceSinceScroll;
if (ATLEAST_Q && mLastTouchClassification == MotionEvent.CLASSIFICATION_DEEP_PRESS) {
@@ -513,7 +477,7 @@
public void forceTouchMove() {
int[] dummyCoordinates = mCoordinatesTemp;
- DropTarget dropTarget = findDropTarget(mLastTouch[0], mLastTouch[1], dummyCoordinates);
+ DropTarget dropTarget = findDropTarget(mLastTouch.x, mLastTouch.y, dummyCoordinates);
mDragObject.x = dummyCoordinates[0];
mDragObject.y = dummyCoordinates[1];
checkTouchMove(dropTarget);
@@ -537,44 +501,6 @@
}
/**
- * Call this from a drag source view.
- */
- public boolean onControllerTouchEvent(MotionEvent ev) {
- if (mDragDriver == null || mOptions == null || mOptions.isAccessibleDrag) {
- return false;
- }
-
- // Update the velocity tracker
- mFlingToDeleteHelper.recordMotionEvent(ev);
-
- final int action = ev.getAction();
- final int[] dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
- final int dragLayerX = dragLayerPos[0];
- final int dragLayerY = dragLayerPos[1];
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- // Remember where the motion event started
- mMotionDownX = dragLayerX;
- mMotionDownY = dragLayerY;
- break;
- }
-
- return mDragDriver.onTouchEvent(ev);
- }
-
- /**
- * Since accessible drag and drop won't cause the same sequence of touch events, we manually
- * inject the appropriate state which would have been otherwise initiated via touch events.
- */
- public void prepareAccessibleDrag(int x, int y) {
- mMotionDownX = x;
- mMotionDownY = y;
- mLastTouch[0] = x;
- mLastTouch[1] = y;
- }
-
- /**
* As above, since accessible drag and drop won't cause the same sequence of touch events,
* we manually ensure appropriate drag and drop events get emulated for accessible drag.
*/
diff --git a/src/com/android/launcher3/dragndrop/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index 87461d5..d4ce308 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -16,19 +16,19 @@
package com.android.launcher3.dragndrop;
-import android.content.Context;
-import android.util.Log;
+import android.os.SystemClock;
import android.view.DragEvent;
import android.view.MotionEvent;
-import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.testing.TestProtocol;
+import java.util.function.Consumer;
/**
* Base class for driving a drag/drop operation.
*/
public abstract class DragDriver {
+
protected final EventListener mEventListener;
+ protected final Consumer<MotionEvent> mSecondaryEventConsumer;
public interface EventListener {
void onDriverDragMove(float x, float y);
@@ -37,131 +37,175 @@
void onDriverDragCancel();
}
- public DragDriver(EventListener eventListener) {
+ public DragDriver(EventListener eventListener, Consumer<MotionEvent> sec) {
mEventListener = eventListener;
+ mSecondaryEventConsumer = sec;
}
/**
- * Handles ending of the DragView animation.
+ * Called to handle system touch event
*/
- public void onDragViewAnimationEnd() { }
-
public boolean onTouchEvent(MotionEvent ev) {
- final int action = ev.getAction();
-
- switch (action) {
- case MotionEvent.ACTION_MOVE:
- mEventListener.onDriverDragMove(ev.getX(), ev.getY());
- break;
- case MotionEvent.ACTION_UP:
- mEventListener.onDriverDragMove(ev.getX(), ev.getY());
- mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
- break;
- case MotionEvent.ACTION_CANCEL:
- mEventListener.onDriverDragCancel();
- break;
- }
-
- return true;
+ return false;
}
- public abstract boolean onDragEvent (DragEvent event);
-
-
+ /**
+ * Called to handle system touch intercept event
+ */
public boolean onInterceptTouchEvent(MotionEvent ev) {
- final int action = ev.getAction();
-
- switch (action) {
- case MotionEvent.ACTION_UP:
- mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
- break;
- case MotionEvent.ACTION_CANCEL:
- mEventListener.onDriverDragCancel();
- break;
- }
-
- return true;
+ return false;
}
- public static DragDriver create(Context context, DragController dragController,
- DragObject dragObject, DragOptions options) {
- if (options.systemDndStartPoint != null) {
- return new SystemDragDriver(dragController, context, dragObject);
+ /**
+ * Called to handle system drag event
+ */
+ public boolean onDragEvent(DragEvent event) {
+ return false;
+ }
+
+ /**
+ * Created a driver for handing the actual events
+ */
+ public static DragDriver create(DragController dragController, DragOptions options,
+ Consumer<MotionEvent> sec) {
+ if (options.simulatedDndStartPoint != null) {
+ if (options.isAccessibleDrag) {
+ return null;
+ }
+ return new SystemDragDriver(dragController, sec);
} else {
- return new InternalDragDriver(dragController);
+ return new InternalDragDriver(dragController, sec);
+ }
+ }
+
+ /**
+ * Class for driving a system (i.e. framework) drag/drop operation.
+ */
+ static class SystemDragDriver extends DragDriver {
+
+ private final long mDragStartTime;
+ float mLastX = 0;
+ float mLastY = 0;
+
+ SystemDragDriver(DragController dragController, Consumer<MotionEvent> sec) {
+ super(dragController, sec);
+ mDragStartTime = SystemClock.uptimeMillis();
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
+ /**
+ * It creates a temporary {@link MotionEvent} object for secondary consumer
+ */
+ private void simulateSecondaryMotionEvent(DragEvent event) {
+ final int motionAction;
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ motionAction = MotionEvent.ACTION_DOWN;
+ break;
+ case DragEvent.ACTION_DRAG_LOCATION:
+ motionAction = MotionEvent.ACTION_MOVE;
+ break;
+ case DragEvent.ACTION_DRAG_ENDED:
+ motionAction = MotionEvent.ACTION_UP;
+ break;
+ default:
+ return;
+ }
+ MotionEvent emulatedEvent = MotionEvent.obtain(mDragStartTime,
+ SystemClock.uptimeMillis(), motionAction, event.getX(), event.getY(), 0);
+ mSecondaryEventConsumer.accept(emulatedEvent);
+ emulatedEvent.recycle();
+ }
+
+ @Override
+ public boolean onDragEvent(DragEvent event) {
+ simulateSecondaryMotionEvent(event);
+ final int action = event.getAction();
+
+ switch (action) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ mLastX = event.getX();
+ mLastY = event.getY();
+ return true;
+
+ case DragEvent.ACTION_DRAG_ENTERED:
+ return true;
+
+ case DragEvent.ACTION_DRAG_LOCATION:
+ mLastX = event.getX();
+ mLastY = event.getY();
+ mEventListener.onDriverDragMove(event.getX(), event.getY());
+ return true;
+
+ case DragEvent.ACTION_DROP:
+ mLastX = event.getX();
+ mLastY = event.getY();
+ mEventListener.onDriverDragMove(event.getX(), event.getY());
+ mEventListener.onDriverDragEnd(mLastX, mLastY);
+ return true;
+ case DragEvent.ACTION_DRAG_EXITED:
+ mEventListener.onDriverDragExitWindow();
+ return true;
+
+ case DragEvent.ACTION_DRAG_ENDED:
+ mEventListener.onDriverDragCancel();
+ return true;
+
+ default:
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Class for driving an internal (i.e. not using framework) drag/drop operation.
+ */
+ static class InternalDragDriver extends DragDriver {
+ InternalDragDriver(DragController dragController, Consumer<MotionEvent> sec) {
+ super(dragController, sec);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ mSecondaryEventConsumer.accept(ev);
+ final int action = ev.getAction();
+
+ switch (action) {
+ case MotionEvent.ACTION_MOVE:
+ mEventListener.onDriverDragMove(ev.getX(), ev.getY());
+ break;
+ case MotionEvent.ACTION_UP:
+ mEventListener.onDriverDragMove(ev.getX(), ev.getY());
+ mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ mEventListener.onDriverDragCancel();
+ break;
+ }
+
+ return true;
+ }
+
+
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ mSecondaryEventConsumer.accept(ev);
+ final int action = ev.getAction();
+
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ mEventListener.onDriverDragCancel();
+ break;
+ }
+ return true;
}
}
}
-/**
- * Class for driving a system (i.e. framework) drag/drop operation.
- */
-class SystemDragDriver extends DragDriver {
- float mLastX = 0;
- float mLastY = 0;
-
- SystemDragDriver(DragController dragController, Context context, DragObject dragObject) {
- super(dragController);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- return false;
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- return false;
- }
-
- @Override
- public boolean onDragEvent (DragEvent event) {
- final int action = event.getAction();
-
- switch (action) {
- case DragEvent.ACTION_DRAG_STARTED:
- mLastX = event.getX();
- mLastY = event.getY();
- return true;
-
- case DragEvent.ACTION_DRAG_ENTERED:
- return true;
-
- case DragEvent.ACTION_DRAG_LOCATION:
- mLastX = event.getX();
- mLastY = event.getY();
- mEventListener.onDriverDragMove(event.getX(), event.getY());
- return true;
-
- case DragEvent.ACTION_DROP:
- mLastX = event.getX();
- mLastY = event.getY();
- mEventListener.onDriverDragMove(event.getX(), event.getY());
- mEventListener.onDriverDragEnd(mLastX, mLastY);
- return true;
- case DragEvent.ACTION_DRAG_EXITED:
- mEventListener.onDriverDragExitWindow();
- return true;
-
- case DragEvent.ACTION_DRAG_ENDED:
- mEventListener.onDriverDragCancel();
- return true;
-
- default:
- return false;
- }
- }
-}
-
-/**
- * Class for driving an internal (i.e. not using framework) drag/drop operation.
- */
-class InternalDragDriver extends DragDriver {
- InternalDragDriver(DragController dragController) {
- super(dragController);
- }
-
- @Override
- public boolean onDragEvent (DragEvent event) { return false; }
-}
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 369bf28..9d07595 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -559,7 +559,7 @@
@Override
public void setInsets(Rect insets) {
super.setInsets(insets);
- mWorkspaceScrim.onInsetsChanged(insets);
+ mWorkspaceScrim.onInsetsChanged(insets, mAllowSysuiScrims);
mOverviewScrim.onInsetsChanged(insets);
}
diff --git a/src/com/android/launcher3/dragndrop/DragOptions.java b/src/com/android/launcher3/dragndrop/DragOptions.java
index 2d19f36..959602b 100644
--- a/src/com/android/launcher3/dragndrop/DragOptions.java
+++ b/src/com/android/launcher3/dragndrop/DragOptions.java
@@ -28,8 +28,11 @@
/** Whether or not an accessible drag operation is in progress. */
public boolean isAccessibleDrag = false;
- /** Specifies the start location for the system DnD, null when using internal DnD */
- public Point systemDndStartPoint = null;
+ /**
+ * Specifies the start location for a simulated DnD (like system drag or accessibility drag),
+ * null when using internal DnD
+ */
+ public Point simulatedDndStartPoint = null;
/** Determines when a pre-drag should transition to a drag. By default, this is immediate. */
public PreDragCondition preDragCondition = null;
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 145885a..7c76d34 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -19,8 +19,6 @@
import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.FloatArrayEvaluator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
@@ -146,15 +144,6 @@
}
});
- mAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- if (!mAnimationCancelled) {
- mDragController.onDragViewAnimationEnd();
- }
- }
- });
-
mBitmap = bitmap;
setDragRegion(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()));
diff --git a/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java b/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java
index 06b5c40..7788f93 100644
--- a/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java
+++ b/src/com/android/launcher3/dragndrop/FlingToDeleteHelper.java
@@ -17,8 +17,6 @@
package com.android.launcher3.dragndrop;
import android.graphics.PointF;
-import android.os.SystemClock;
-import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
@@ -55,31 +53,6 @@
mVelocityTracker.addMovement(ev);
}
- /**
- * Same as {@link #recordMotionEvent}. It creates a temporary {@link MotionEvent} object
- * using {@param event} for tracking velocity.
- */
- public void recordDragEvent(long dragStartTime, DragEvent event) {
- final int motionAction;
- switch (event.getAction()) {
- case DragEvent.ACTION_DRAG_STARTED:
- motionAction = MotionEvent.ACTION_DOWN;
- break;
- case DragEvent.ACTION_DRAG_LOCATION:
- motionAction = MotionEvent.ACTION_MOVE;
- break;
- case DragEvent.ACTION_DRAG_ENDED:
- motionAction = MotionEvent.ACTION_UP;
- break;
- default:
- return;
- }
- MotionEvent emulatedEvent = MotionEvent.obtain(dragStartTime, SystemClock.uptimeMillis(),
- motionAction, event.getX(), event.getY(), 0);
- recordMotionEvent(emulatedEvent);
- emulatedEvent.recycle();
- }
-
public void releaseVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 5f496f4..14fa1f4 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -85,6 +85,7 @@
import com.android.launcher3.Workspace.ItemOperator;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
+import com.android.launcher3.accessibility.FolderAccessibilityHelper;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragController.DragListener;
@@ -271,16 +272,15 @@
mDragController.addDragListener(this);
if (options.isAccessibleDrag) {
mDragController.addDragListener(new AccessibleDragListenerAdapter(
- mContent, CellLayout.FOLDER_ACCESSIBILITY_DRAG) {
-
- @Override
- protected void enableAccessibleDrag(boolean enable) {
- super.enableAccessibleDrag(enable);
- mFooter.setImportantForAccessibility(enable
- ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
- : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
- }
- });
+ mContent, FolderAccessibilityHelper::new) {
+ @Override
+ protected void enableAccessibleDrag(boolean enable) {
+ super.enableAccessibleDrag(enable);
+ mFooter.setImportantForAccessibility(enable
+ ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+ : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ }
+ });
}
mLauncher.getWorkspace().beginDragShared(v, this, options);
@@ -519,9 +519,6 @@
}
private void startAnimation(final AnimatorSet a) {
- if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
- mCurrentAnimator.cancel();
- }
final Workspace workspace = mLauncher.getWorkspace();
final CellLayout currentCellLayout =
(CellLayout) workspace.getChildAt(workspace.getCurrentPage());
@@ -638,6 +635,9 @@
// dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
mDeleteFolderOnDropCompleted = false;
+ if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
+ mCurrentAnimator.cancel();
+ }
AnimatorSet anim = new FolderAnimationManager(this, true /* isOpening */).getAnimator();
anim.addListener(new AnimatorListenerAdapter() {
@Override
@@ -741,6 +741,9 @@
}
private void animateClosed() {
+ if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
+ mCurrentAnimator.cancel();
+ }
AnimatorSet a = new FolderAnimationManager(this, false /* isOpening */).getAnimator();
a.addListener(new AnimatorListenerAdapter() {
@Override
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index f72e674..b83609e 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.graphics.IconShape.getShape;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
-import static com.android.launcher3.uioverrides.BackgroundBlurController.BACKGROUND_BLUR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -47,7 +46,6 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PropertyResetListener;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.uioverrides.BackgroundBlurController;
import com.android.launcher3.util.Themes;
import java.util.List;
@@ -222,14 +220,6 @@
Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0);
play(a, z, mIsOpening ? midDuration : 0, midDuration);
- BackgroundBlurController blurController = mLauncher.getBackgroundBlurController();
- int stateBackgroundBlur = mLauncher.getStateManager().getState()
- .getBackgroundBlurRadius(mLauncher);
- int folderBackgroundBlurAdjustment = blurController.getFolderBackgroundBlurAdjustment();
- play(a, ObjectAnimator.ofInt(blurController, BACKGROUND_BLUR, mIsOpening
- ? stateBackgroundBlur + folderBackgroundBlurAdjustment
- : stateBackgroundBlur));
-
// Store clip variables
CellLayout cellLayout = mContent.getCurrentCellLayout();
boolean folderClipChildren = mFolder.getClipChildren();
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index 2c7f891..3fb2bf6 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -194,10 +194,13 @@
return anim;
}
- public void onInsetsChanged(Rect insets) {
- mDrawTopScrim = mTopScrim != null && insets.top > 0;
- mDrawBottomScrim = mBottomMask != null &&
- !mLauncher.getDeviceProfile().isVerticalBarLayout();
+ /**
+ * Determines whether to draw the top and/or bottom scrim based on new insets.
+ */
+ public void onInsetsChanged(Rect insets, boolean allowSysuiScrims) {
+ mDrawTopScrim = allowSysuiScrims && mTopScrim != null && insets.top > 0;
+ mDrawBottomScrim = allowSysuiScrims && mBottomMask != null
+ && !mLauncher.getDeviceProfile().isVerticalBarLayout();
}
@Override
@@ -236,14 +239,6 @@
}
}
- public void hideSysUiScrim(boolean hideSysUiScrim) {
- mHideSysUiScrim = hideSysUiScrim || (mTopScrim == null);
- if (!hideSysUiScrim) {
- mAnimateScrimOnNextDraw = true;
- }
- invalidate();
- }
-
private void setSysUiProgress(float progress) {
if (progress != mSysUiProgress) {
mSysUiProgress = progress;
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 25748ae..868c91d 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -23,7 +23,11 @@
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
import android.annotation.TargetApi;
+import android.app.WallpaperInfo;
+import android.app.WallpaperManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -38,11 +42,15 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.launcher3.util.TouchController;
import java.io.PrintWriter;
@@ -98,6 +106,10 @@
protected final T mActivity;
private final MultiValueAlpha mMultiValueAlpha;
+ private final WallpaperManager mWallpaperManager;
+ private final SimpleBroadcastReceiver mWallpaperChangeReceiver =
+ new SimpleBroadcastReceiver(this::onWallpaperChanged);
+ private final String[] mWallpapersWithoutSysuiScrims;
// All the touch controllers for the view
protected TouchController[] mControllers;
@@ -108,10 +120,15 @@
private TouchCompleteListener mTouchCompleteListener;
+ protected boolean mAllowSysuiScrims = true;
+
public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) {
super(context, attrs);
mActivity = (T) ActivityContext.lookupContext(context);
mMultiValueAlpha = new MultiValueAlpha(this, alphaChannelCount);
+ mWallpaperManager = context.getSystemService(WallpaperManager.class);
+ mWallpapersWithoutSysuiScrims = getResources().getStringArray(
+ R.array.live_wallpapers_remove_sysui_scrims);
}
/**
@@ -517,4 +534,46 @@
}
return super.dispatchApplyWindowInsets(insets);
}
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mWallpaperChangeReceiver.register(mActivity, Intent.ACTION_WALLPAPER_CHANGED);
+ onWallpaperChanged(null);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mActivity.unregisterReceiver(mWallpaperChangeReceiver);
+ }
+
+ private void onWallpaperChanged(Intent unusedBroadcastIntent) {
+ WallpaperInfo newWallpaperInfo = mWallpaperManager.getWallpaperInfo();
+ boolean oldAllowSysuiScrims = mAllowSysuiScrims;
+ mAllowSysuiScrims = computeAllowSysuiScrims(newWallpaperInfo);
+ if (mAllowSysuiScrims != oldAllowSysuiScrims) {
+ // Reapply insets so scrim can be removed or re-added if necessary.
+ setInsets(mInsets);
+ }
+ }
+
+ /**
+ * Determines whether we can scrim the status bar and nav bar for the given wallpaper by
+ * checking against a list of live wallpapers that we don't show the scrims on.
+ */
+ private boolean computeAllowSysuiScrims(@Nullable WallpaperInfo newWallpaperInfo) {
+ if (newWallpaperInfo == null) {
+ // New wallpaper is static, not live. Thus, blacklist isn't applicable.
+ return true;
+ }
+ ComponentName newWallpaper = newWallpaperInfo.getComponent();
+ for (String wallpaperWithoutScrim : mWallpapersWithoutSysuiScrims) {
+ if (newWallpaper.equals(ComponentName.unflattenFromString(wallpaperWithoutScrim))) {
+ // New wallpaper is blacklisted from showing a scrim.
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/src/com/android/launcher3/views/WorkFooterContainer.java b/src/com/android/launcher3/views/WorkFooterContainer.java
index 9ac8230..d86d0ff 100644
--- a/src/com/android/launcher3/views/WorkFooterContainer.java
+++ b/src/com/android/launcher3/views/WorkFooterContainer.java
@@ -112,8 +112,6 @@
boolean anyProfileQuietModeEnabled = UserCache.INSTANCE.get(
getContext()).isAnyProfileQuietModeEnabled();
- mWorkModeLabel.setText(anyProfileQuietModeEnabled
- ? R.string.work_mode_off_label : R.string.work_mode_on_label);
mWorkModeLabel.setCompoundDrawablesWithIntrinsicBounds(
anyProfileQuietModeEnabled ? R.drawable.ic_corp_off : R.drawable.ic_corp, 0, 0, 0);
mWorkModeSwitch.refresh();
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/BackgroundBlurController.java b/src_ui_overrides/com/android/launcher3/uioverrides/DepthController.java
similarity index 66%
rename from src_ui_overrides/com/android/launcher3/uioverrides/BackgroundBlurController.java
rename to src_ui_overrides/com/android/launcher3/uioverrides/DepthController.java
index 75f99a9..7ad85e2 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/BackgroundBlurController.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/DepthController.java
@@ -17,7 +17,7 @@
package com.android.launcher3.uioverrides;
-import android.util.IntProperty;
+import android.util.FloatProperty;
import android.view.View;
import com.android.launcher3.Launcher;
@@ -27,26 +27,22 @@
import com.android.launcher3.states.StateAnimationConfig;
/**
- * Controls the blur, for the Launcher surface only.
+ * Controls blur and wallpaper zoom, for the Launcher surface only.
*/
-public class BackgroundBlurController implements LauncherStateManager.StateHandler {
+public class DepthController implements LauncherStateManager.StateHandler {
- public static final IntProperty<BackgroundBlurController> BACKGROUND_BLUR =
- new IntProperty<BackgroundBlurController>("backgroundBlur") {
+ public static final FloatProperty<DepthController> DEPTH =
+ new FloatProperty<DepthController>("depth") {
@Override
- public void setValue(BackgroundBlurController blurController, int blurRadius) {}
+ public void setValue(DepthController depthController, float depth) {}
@Override
- public Integer get(BackgroundBlurController blurController) {
- return 0;
+ public Float get(DepthController depthController) {
+ return 0f;
}
};
- public BackgroundBlurController(Launcher l) {}
-
- public int getFolderBackgroundBlurAdjustment() {
- return 0;
- }
+ public DepthController(Launcher l) {}
public void setSurfaceToLauncher(View v) {}
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 3d12248..f5dd995 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -102,6 +102,7 @@
private static String sDetectedActivityLeak;
private static boolean sActivityLeakReported;
+ private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
protected LooperExecutor mMainThreadExecutor = MAIN_EXECUTOR;
protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
@@ -213,8 +214,20 @@
return mDevice;
}
+ private boolean hasSystemUiObject(String resId) {
+ return mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, resId));
+ }
+
@Before
public void setUp() throws Exception {
+ mDevice.executeShellCommand("settings put global stay_on_while_plugged_in 3");
+ if (hasSystemUiObject("keyguard_status_view")) {
+ Log.d(TAG, "Before unlocking the phone");
+ mDevice.executeShellCommand("input keyevent 82");
+ } else {
+ Log.d(TAG, "Phone isn't locked");
+ }
+
final String launcherPackageName = mDevice.getLauncherPackageName();
try {
final Context context = InstrumentationRegistry.getContext();