Snap for 7960322 from 87f010f3bd to sc-v2-release
Change-Id: I3752df99f203fe9d730bf843a9e7aacf90ec12fa
This commit is contained in:
@@ -60,6 +60,7 @@ public class FallbackTaskbarUIController extends TaskbarUIController {
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mRecentsActivity.setTaskbarUIController(null);
|
||||
mRecentsActivity.getStateManager().removeStateListener(mStateListener);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
onLauncherResumedOrPaused(false);
|
||||
mTaskbarLauncherStateController.onDestroy();
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_I
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
@@ -86,6 +87,7 @@ public class NavbarButtonsViewController {
|
||||
private static final int FLAG_DISABLE_RECENTS = 1 << 8;
|
||||
private static final int FLAG_DISABLE_BACK = 1 << 9;
|
||||
private static final int FLAG_NOTIFICATION_SHADE_EXPANDED = 1 << 10;
|
||||
private static final int FLAG_SCREEN_PINNING_ACTIVE = 1 << 10;
|
||||
|
||||
private static final int MASK_IME_SWITCHER_VISIBLE = FLAG_SWITCHER_SUPPORTED | FLAG_IME_VISIBLE;
|
||||
|
||||
@@ -152,7 +154,9 @@ public class NavbarButtonsViewController {
|
||||
mPropertyHolders.add(new StatePropertyHolder(
|
||||
mControllers.taskbarViewController.getTaskbarIconAlpha()
|
||||
.getProperty(ALPHA_INDEX_KEYGUARD),
|
||||
flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0, MultiValueAlpha.VALUE, 1, 0));
|
||||
flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0
|
||||
&& (flags & FLAG_SCREEN_PINNING_ACTIVE) == 0,
|
||||
MultiValueAlpha.VALUE, 1, 0));
|
||||
|
||||
mPropertyHolders.add(new StatePropertyHolder(mControllers.taskbarDragLayerController
|
||||
.getKeyguardBgTaskbar(),
|
||||
@@ -286,6 +290,7 @@ public class NavbarButtonsViewController {
|
||||
int shadeExpandedFlags = SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
|
||||
| SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
|
||||
boolean isNotificationShadeExpanded = (sysUiStateFlags & shadeExpandedFlags) != 0;
|
||||
boolean isScreenPinningActive = (sysUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
|
||||
|
||||
// TODO(b/202218289) we're getting IME as not visible on lockscreen from system
|
||||
updateStateForFlag(FLAG_IME_VISIBLE, isImeVisible);
|
||||
@@ -295,6 +300,7 @@ public class NavbarButtonsViewController {
|
||||
updateStateForFlag(FLAG_DISABLE_RECENTS, isRecentsDisabled);
|
||||
updateStateForFlag(FLAG_DISABLE_BACK, isBackDisabled);
|
||||
updateStateForFlag(FLAG_NOTIFICATION_SHADE_EXPANDED, isNotificationShadeExpanded);
|
||||
updateStateForFlag(FLAG_SCREEN_PINNING_ACTIVE, isScreenPinningActive);
|
||||
|
||||
if (mA11yButton != null) {
|
||||
// Only used in 3 button
|
||||
|
||||
@@ -361,6 +361,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
mControllers.taskbarStashController.updateStateForSysuiFlags(systemUiStateFlags, fromInit);
|
||||
mControllers.taskbarScrimViewController.updateStateForSysuiFlags(systemUiStateFlags,
|
||||
fromInit);
|
||||
mControllers.navButtonController.updateSysuiFlags(systemUiStateFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,8 +29,8 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -93,7 +93,8 @@ public class TaskbarManager implements DisplayController.DisplayInfoChangeListen
|
||||
Display display =
|
||||
service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
|
||||
mContext = service.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null);
|
||||
mNavButtonController = new TaskbarNavButtonController(service);
|
||||
mNavButtonController = new TaskbarNavButtonController(service,
|
||||
SystemUiProxy.INSTANCE.get(mContext), new Handler());
|
||||
mUserSetupCompleteListener = isUserSetupComplete -> recreateTaskbar();
|
||||
mComponentCallbacks = new ComponentCallbacks() {
|
||||
private Configuration mOldConfig = mContext.getResources().getConfiguration();
|
||||
|
||||
@@ -19,8 +19,10 @@ package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS;
|
||||
import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_KEY;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
@@ -40,6 +42,13 @@ import java.lang.annotation.RetentionPolicy;
|
||||
*/
|
||||
public class TaskbarNavButtonController {
|
||||
|
||||
/** Allow some time in between the long press for back and recents. */
|
||||
static final int SCREEN_PIN_LONG_PRESS_THRESHOLD = 200;
|
||||
static final int SCREEN_PIN_LONG_PRESS_RESET = SCREEN_PIN_LONG_PRESS_THRESHOLD + 100;
|
||||
|
||||
private long mLastScreenPinLongPress;
|
||||
private boolean mScreenPinned;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BUTTON_BACK,
|
||||
@@ -57,10 +66,20 @@ public class TaskbarNavButtonController {
|
||||
static final int BUTTON_IME_SWITCH = BUTTON_RECENTS << 1;
|
||||
static final int BUTTON_A11Y = BUTTON_IME_SWITCH << 1;
|
||||
|
||||
private final TouchInteractionService mService;
|
||||
private static final int SCREEN_UNPIN_COMBO = BUTTON_BACK | BUTTON_RECENTS;
|
||||
private int mLongPressedButtons = 0;
|
||||
|
||||
public TaskbarNavButtonController(TouchInteractionService service) {
|
||||
private final TouchInteractionService mService;
|
||||
private final SystemUiProxy mSystemUiProxy;
|
||||
private final Handler mHandler;
|
||||
|
||||
private final Runnable mResetLongPress = this::resetScreenUnpin;
|
||||
|
||||
public TaskbarNavButtonController(TouchInteractionService service,
|
||||
SystemUiProxy systemUiProxy, Handler handler) {
|
||||
mService = service;
|
||||
mSystemUiProxy = systemUiProxy;
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
public void onButtonClick(@TaskbarButton int buttonType) {
|
||||
@@ -72,13 +91,13 @@ public class TaskbarNavButtonController {
|
||||
navigateHome();
|
||||
break;
|
||||
case BUTTON_RECENTS:
|
||||
navigateToOverview();;
|
||||
navigateToOverview();
|
||||
break;
|
||||
case BUTTON_IME_SWITCH:
|
||||
showIMESwitcher();
|
||||
break;
|
||||
case BUTTON_A11Y:
|
||||
notifyImeClick(false /* longClick */);
|
||||
notifyA11yClick(false /* longClick */);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -89,46 +108,98 @@ public class TaskbarNavButtonController {
|
||||
startAssistant();
|
||||
return true;
|
||||
case BUTTON_A11Y:
|
||||
notifyImeClick(true /* longClick */);
|
||||
notifyA11yClick(true /* longClick */);
|
||||
return true;
|
||||
case BUTTON_BACK:
|
||||
case BUTTON_IME_SWITCH:
|
||||
case BUTTON_RECENTS:
|
||||
mLongPressedButtons |= buttonType;
|
||||
return determineScreenUnpin();
|
||||
case BUTTON_IME_SWITCH:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user has long pressed back and recents buttons
|
||||
* "together" (within {@link #SCREEN_PIN_LONG_PRESS_THRESHOLD})ms
|
||||
* If so, then requests the system to turn off screen pinning.
|
||||
*
|
||||
* @return true if the long press is a valid user action in attempting to unpin an app
|
||||
* Will always return {@code false} when screen pinning is not active.
|
||||
* NOTE: Returning true does not mean that screen pinning has stopped
|
||||
*/
|
||||
private boolean determineScreenUnpin() {
|
||||
long timeNow = System.currentTimeMillis();
|
||||
if (!mScreenPinned) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mLastScreenPinLongPress == 0) {
|
||||
// First button long press registered, just mark time and wait for second button press
|
||||
mLastScreenPinLongPress = System.currentTimeMillis();
|
||||
mHandler.postDelayed(mResetLongPress, SCREEN_PIN_LONG_PRESS_RESET);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((timeNow - mLastScreenPinLongPress) > SCREEN_PIN_LONG_PRESS_THRESHOLD) {
|
||||
// Too long in-between presses, reset the clock
|
||||
resetScreenUnpin();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((mLongPressedButtons & SCREEN_UNPIN_COMBO) == SCREEN_UNPIN_COMBO) {
|
||||
// Hooray! They did it (finally...)
|
||||
mSystemUiProxy.stopScreenPinning();
|
||||
mHandler.removeCallbacks(mResetLongPress);
|
||||
resetScreenUnpin();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void resetScreenUnpin() {
|
||||
mLongPressedButtons = 0;
|
||||
mLastScreenPinLongPress = 0;
|
||||
}
|
||||
|
||||
public void updateSysuiFlags(int sysuiFlags) {
|
||||
mScreenPinned = (sysuiFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
|
||||
}
|
||||
|
||||
private void navigateHome() {
|
||||
mService.getOverviewCommandHelper().addCommand(OverviewCommandHelper.TYPE_HOME);
|
||||
}
|
||||
|
||||
private void navigateToOverview() {
|
||||
if (mScreenPinned) {
|
||||
return;
|
||||
}
|
||||
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onOverviewToggle");
|
||||
mService.getOverviewCommandHelper().addCommand(OverviewCommandHelper.TYPE_TOGGLE);
|
||||
}
|
||||
|
||||
private void executeBack() {
|
||||
SystemUiProxy.INSTANCE.getNoCreate().onBackPressed();
|
||||
mSystemUiProxy.onBackPressed();
|
||||
}
|
||||
|
||||
private void showIMESwitcher() {
|
||||
SystemUiProxy.INSTANCE.getNoCreate().onImeSwitcherPressed();
|
||||
mSystemUiProxy.onImeSwitcherPressed();
|
||||
}
|
||||
|
||||
private void notifyImeClick(boolean longClick) {
|
||||
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
private void notifyA11yClick(boolean longClick) {
|
||||
if (longClick) {
|
||||
systemUiProxy.notifyAccessibilityButtonLongClicked();
|
||||
mSystemUiProxy.notifyAccessibilityButtonLongClicked();
|
||||
} else {
|
||||
systemUiProxy.notifyAccessibilityButtonClicked(mService.getDisplayId());
|
||||
mSystemUiProxy.notifyAccessibilityButtonClicked(mService.getDisplayId());
|
||||
}
|
||||
}
|
||||
|
||||
private void startAssistant() {
|
||||
if (mScreenPinned) {
|
||||
return;
|
||||
}
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
|
||||
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.getNoCreate();
|
||||
systemUiProxy.startAssistant(args);
|
||||
mSystemUiProxy.startAssistant(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.android.launcher3.taskbar;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.CallSuper;
|
||||
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
|
||||
@@ -33,11 +35,15 @@ public class TaskbarUIController {
|
||||
// Initialized in init.
|
||||
protected TaskbarControllers mControllers;
|
||||
|
||||
@CallSuper
|
||||
protected void init(TaskbarControllers taskbarControllers) {
|
||||
mControllers = taskbarControllers;
|
||||
}
|
||||
|
||||
protected void onDestroy() { }
|
||||
@CallSuper
|
||||
protected void onDestroy() {
|
||||
mControllers = null;
|
||||
}
|
||||
|
||||
protected boolean isTaskbarTouchable() {
|
||||
return true;
|
||||
|
||||
@@ -66,6 +66,12 @@ public final class RecentsViewStateController extends
|
||||
// In Overview, we may be layering app surfaces behind Launcher, so we need to notify
|
||||
// DepthController to prevent optimizations which might occlude the layers behind
|
||||
mLauncher.getDepthController().setHasContentBehindLauncher(state.overviewUi);
|
||||
|
||||
if (isSplitSelectionState(state)) {
|
||||
mRecentsView.applySplitPrimaryScrollOffset();
|
||||
} else {
|
||||
mRecentsView.resetSplitPrimaryScrollOffset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,9 +96,10 @@ public final class RecentsViewStateController extends
|
||||
LauncherState currentState = mLauncher.getStateManager().getState();
|
||||
if (isSplitSelectionState(toState) && !isSplitSelectionState(currentState)) {
|
||||
builder.add(mRecentsView.createSplitSelectInitAnimation().buildAnim());
|
||||
}
|
||||
if (isSplitSelectionState(toState)) {
|
||||
mRecentsView.applySplitPrimaryScrollOffset();
|
||||
} else if (!isSplitSelectionState(toState) && isSplitSelectionState(currentState)) {
|
||||
builder.add(mRecentsView.cancelSplitSelect(true).buildAnim());
|
||||
} else {
|
||||
mRecentsView.resetSplitPrimaryScrollOffset();
|
||||
}
|
||||
|
||||
|
||||
@@ -30,11 +30,6 @@ public class SplitScreenSelectState extends OverviewState {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed(Launcher launcher) {
|
||||
launcher.getStateManager().goToState(OVERVIEW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getVisibleElements(Launcher launcher) {
|
||||
return SPLIT_PLACHOLDER_VIEW;
|
||||
|
||||
@@ -599,11 +599,11 @@ public class SystemUiProxy implements ISystemUiProxy,
|
||||
}
|
||||
}
|
||||
|
||||
public void startShortcut(String packageName, String shortcutId, int stage, int position,
|
||||
public void startShortcut(String packageName, String shortcutId, int position,
|
||||
Bundle options, UserHandle user) {
|
||||
if (mSplitScreen != null) {
|
||||
try {
|
||||
mSplitScreen.startShortcut(packageName, shortcutId, stage, position, options,
|
||||
mSplitScreen.startShortcut(packageName, shortcutId, position, options,
|
||||
user);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call startShortcut");
|
||||
@@ -611,11 +611,11 @@ public class SystemUiProxy implements ISystemUiProxy,
|
||||
}
|
||||
}
|
||||
|
||||
public void startIntent(PendingIntent intent, Intent fillInIntent, int stage, int position,
|
||||
public void startIntent(PendingIntent intent, Intent fillInIntent, int position,
|
||||
Bundle options) {
|
||||
if (mSplitScreen != null) {
|
||||
try {
|
||||
mSplitScreen.startIntent(intent, fillInIntent, stage, position, options);
|
||||
mSplitScreen.startIntent(intent, fillInIntent, position, options);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call startIntent");
|
||||
}
|
||||
|
||||
@@ -129,9 +129,7 @@ public class FloatingTaskView extends FrameLayout {
|
||||
public void update(RectF position, float progress, float windowRadius) {
|
||||
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
|
||||
|
||||
float dX = mIsRtl
|
||||
? position.left - (lp.getMarginStart() - lp.width)
|
||||
: position.left - lp.getMarginStart();
|
||||
float dX = position.left - lp.getMarginStart();
|
||||
float dY = position.top - lp.topMargin;
|
||||
|
||||
setTranslationX(dX);
|
||||
@@ -157,16 +155,10 @@ public class FloatingTaskView extends FrameLayout {
|
||||
lp.ignoreInsets = true;
|
||||
// Position the floating view exactly on top of the original
|
||||
lp.topMargin = Math.round(pos.top);
|
||||
if (mIsRtl) {
|
||||
lp.setMarginStart(Math.round(mLauncher.getDeviceProfile().widthPx - pos.right));
|
||||
} else {
|
||||
lp.setMarginStart(Math.round(pos.left));
|
||||
}
|
||||
lp.setMarginStart(Math.round(pos.left));
|
||||
// Set the properties here already to make sure they are available when running the first
|
||||
// animation frame.
|
||||
int left = mIsRtl
|
||||
? mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width
|
||||
: lp.leftMargin;
|
||||
int left = lp.leftMargin;
|
||||
layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height);
|
||||
}
|
||||
|
||||
|
||||
@@ -157,10 +157,20 @@ public class GroupedTaskView extends TaskView {
|
||||
@Nullable
|
||||
@Override
|
||||
public RunnableList launchTaskAnimated() {
|
||||
getRecentsView().getSplitPlaceholder().launchTasks(this /*groupedTaskView*/,
|
||||
null /*callback*/,
|
||||
if (mTask == null || mSecondaryTask == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RunnableList endCallback = new RunnableList();
|
||||
RecentsView recentsView = getRecentsView();
|
||||
// Callbacks run from remote animation when recents animation not currently running
|
||||
recentsView.getSplitPlaceholder().launchTasks(this /*groupedTaskView*/,
|
||||
success -> endCallback.executeAllAndDestroy(),
|
||||
false /* freezeTaskList */);
|
||||
return null;
|
||||
|
||||
// Callbacks get run from recentsView for case when recents animation already running
|
||||
recentsView.addSideTaskLaunchCallback(endCallback);
|
||||
return endCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -107,6 +107,7 @@ import android.widget.ListView;
|
||||
import android.widget.OverScroller;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
@@ -181,6 +182,7 @@ import com.android.wm.shell.pip.IPipAnimationListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
@@ -822,7 +824,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
@Override
|
||||
public void onTaskIconChanged(String pkg, UserHandle user) {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView tv = getTaskViewAt(i);
|
||||
TaskView tv = requireTaskViewAt(i);
|
||||
Task task = tv.getTask();
|
||||
if (task != null && task.key != null && pkg.equals(task.key.getPackageName())
|
||||
&& task.key.userId == user.getIdentifier()) {
|
||||
@@ -1104,7 +1106,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
int[] taskIds = taskView.getTaskIds();
|
||||
if (taskIds[0] == taskId || taskIds[1] == taskId) {
|
||||
return taskView;
|
||||
@@ -1121,9 +1123,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Reset the running task when leaving overview since it can still have a reference to
|
||||
// its thumbnail
|
||||
mTmpRunningTasks = null;
|
||||
if (mSplitSelectStateController.isSplitSelectActive()) {
|
||||
cancelSplitSelect(false);
|
||||
}
|
||||
// Remove grouped tasks and recycle once we exit overview
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
@@ -1181,7 +1180,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (showAsGrid()) {
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (isTaskViewVisible(taskView) && taskView.offerTouchToChildren(ev)) {
|
||||
// Keep consuming events to pass to delegate
|
||||
return true;
|
||||
@@ -1418,7 +1417,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (runningTaskId != -1) {
|
||||
targetPage = indexOfChild(newRunningTaskView);
|
||||
} else if (getTaskViewCount() > 0) {
|
||||
targetPage = indexOfChild(getTaskViewAt(0));
|
||||
targetPage = indexOfChild(requireTaskViewAt(0));
|
||||
}
|
||||
} else if (currentTaskId != -1) {
|
||||
currentTaskView = getTaskViewByTaskId(currentTaskId);
|
||||
@@ -1452,7 +1451,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private void removeTasksViewsAndClearAllButton() {
|
||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||
removeView(getTaskViewAt(i));
|
||||
removeView(requireTaskViewAt(i));
|
||||
}
|
||||
if (indexOfChild(mClearAllButton) != -1) {
|
||||
removeView(mClearAllButton);
|
||||
@@ -1498,7 +1497,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
public void resetTaskVisuals() {
|
||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (mIgnoreResetTaskId != taskView.getTaskIds()[0]) {
|
||||
taskView.resetViewTransforms();
|
||||
taskView.setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
|
||||
@@ -1539,7 +1538,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mFullscreenProgress = fullscreenProgress;
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
|
||||
requireTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
|
||||
}
|
||||
mClearAllButton.setFullscreenProgress(fullscreenProgress);
|
||||
|
||||
@@ -1666,7 +1665,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
float accumulatedTranslationX = 0;
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
taskView.updateTaskSize();
|
||||
taskView.getPrimaryNonGridTranslationProperty().set(taskView, accumulatedTranslationX);
|
||||
taskView.getSecondaryNonGridTranslationProperty().set(taskView, 0f);
|
||||
@@ -1812,7 +1811,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
// Update the task data for the in/visible children
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
Task task = taskView.getTask();
|
||||
int index = indexOfChild(taskView);
|
||||
boolean visible;
|
||||
@@ -1955,7 +1954,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (taskView.getTaskViewId() == taskViewId) {
|
||||
return taskView;
|
||||
}
|
||||
@@ -2053,7 +2052,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
int runningIndex = getCurrentPage();
|
||||
AnimatorSet as = new AnimatorSet();
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
View taskView = getTaskViewAt(i);
|
||||
View taskView = requireTaskViewAt(i);
|
||||
if (runningIndex == i && taskView.getAlpha() != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -2064,7 +2063,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private void updateChildTaskOrientations() {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
getTaskViewAt(i).setOrientationState(mOrientationState);
|
||||
requireTaskViewAt(i).setOrientationState(mOrientationState);
|
||||
}
|
||||
TaskMenuView tv = (TaskMenuView) getTopOpenViewWithType(mActivity, TYPE_TASK_MENU);
|
||||
if (tv != null) {
|
||||
@@ -2269,7 +2268,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mTaskIconScaledDown = isScaledDown;
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
getTaskViewAt(i).setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
|
||||
requireTaskViewAt(i).setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2285,7 +2284,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mTaskIconScaledDown = false;
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
taskView.setIconScaleAnimStartProgress(0f);
|
||||
taskView.animateIconScaleAndDimIntoView();
|
||||
}
|
||||
@@ -2357,7 +2356,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mTopRowIdSet.clear();
|
||||
}
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
int taskWidthAndSpacing = taskView.getLayoutParams().width + mPageSpacing;
|
||||
// Evenly distribute tasks between rows unless rearranging due to task dismissal, in
|
||||
// which case keep tasks in their respective rows. For the running task, don't join
|
||||
@@ -2422,7 +2421,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (j == focusedTaskIndex) {
|
||||
continue;
|
||||
}
|
||||
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
|
||||
widthOffset += requireTaskViewAt(j).getLayoutParams().width + mPageSpacing;
|
||||
}
|
||||
|
||||
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
|
||||
@@ -2441,7 +2440,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (j == focusedTaskIndex) {
|
||||
continue;
|
||||
}
|
||||
widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
|
||||
widthOffset += requireTaskViewAt(j).getLayoutParams().width + mPageSpacing;
|
||||
}
|
||||
|
||||
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
|
||||
@@ -2519,7 +2518,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
taskView.setGridTranslationX(gridTranslations[i] - snappedTaskGridTranslationX
|
||||
+ snappedTaskNonGridScrollAdjustment);
|
||||
}
|
||||
@@ -2560,7 +2559,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mGridProgress = gridProgress;
|
||||
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
getTaskViewAt(i).setGridProgress(gridProgress);
|
||||
requireTaskViewAt(i).setGridProgress(gridProgress);
|
||||
}
|
||||
mClearAllButton.setGridProgress(gridProgress);
|
||||
}
|
||||
@@ -2723,7 +2722,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mTopRowIdSet.size() > 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f;
|
||||
// Pick the next focused task from the preferred row.
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (taskView == dismissedTaskView) {
|
||||
continue;
|
||||
}
|
||||
@@ -2826,7 +2825,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
+ (taskCount - 1) * halfAdditionalDismissTranslationOffset,
|
||||
END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET, 1);
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
anim.setFloat(taskView, TaskView.GRID_END_TRANSLATION_X, longGridRowWidthDiff,
|
||||
clampToProgress(LINEAR, dismissTranslationInterpolationEnd, 1));
|
||||
dismissTranslationInterpolationEnd = Utilities.boundToRange(
|
||||
@@ -3142,7 +3141,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Rebalance tasks in the grid
|
||||
int highestVisibleTaskIndex = getHighestVisibleTaskIndex();
|
||||
if (highestVisibleTaskIndex < Integer.MAX_VALUE) {
|
||||
TaskView taskView = getTaskViewAt(highestVisibleTaskIndex);
|
||||
TaskView taskView = requireTaskViewAt(highestVisibleTaskIndex);
|
||||
|
||||
boolean shouldRebalance;
|
||||
int screenStart = mOrientationHandler.getPrimaryScroll(
|
||||
@@ -3240,7 +3239,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
IntArray topArray = new IntArray(mTopRowIdSet.size());
|
||||
int taskViewCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskViewCount; i++) {
|
||||
int taskViewId = getTaskViewAt(i).getTaskViewId();
|
||||
int taskViewId = requireTaskViewAt(i).getTaskViewId();
|
||||
if (mTopRowIdSet.contains(taskViewId)) {
|
||||
topArray.add(taskViewId);
|
||||
}
|
||||
@@ -3259,7 +3258,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
IntArray bottomArray = new IntArray(bottomRowIdArraySize);
|
||||
int taskViewCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskViewCount; i++) {
|
||||
int taskViewId = getTaskViewAt(i).getTaskViewId();
|
||||
int taskViewId = requireTaskViewAt(i).getTaskViewId();
|
||||
if (!mTopRowIdSet.contains(taskViewId) && taskViewId != mFocusedTaskViewId) {
|
||||
bottomArray.add(taskViewId);
|
||||
}
|
||||
@@ -3329,7 +3328,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
int count = getTaskViewCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
addDismissedTaskAnimations(getTaskViewAt(i), duration, anim);
|
||||
addDismissedTaskAnimations(requireTaskViewAt(i), duration, anim);
|
||||
}
|
||||
|
||||
mPendingAnimation = anim;
|
||||
@@ -3452,7 +3451,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mContentAlpha = alpha;
|
||||
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
||||
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
|
||||
TaskView child = getTaskViewAt(i);
|
||||
TaskView child = requireTaskViewAt(i);
|
||||
int[] childTaskIds = child.getTaskIds();
|
||||
if (!mRunningTaskTileHidden ||
|
||||
(childTaskIds[0] != runningTaskId && childTaskIds[1] != runningTaskId)) {
|
||||
@@ -3553,6 +3552,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return child instanceof TaskView ? (TaskView) child : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A version of {@link #getTaskViewAt} when the caller is sure about the input index.
|
||||
*/
|
||||
@NonNull
|
||||
private TaskView requireTaskViewAt(int index) {
|
||||
return Objects.requireNonNull(getTaskViewAt(index));
|
||||
}
|
||||
|
||||
public void setOnEmptyMessageUpdatedListener(OnEmptyMessageUpdatedListener listener) {
|
||||
mOnEmptyMessageUpdatedListener = listener;
|
||||
}
|
||||
@@ -3769,7 +3776,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
protected void setTaskViewsResistanceTranslation(float translation) {
|
||||
mTaskViewsSecondaryTranslation = translation;
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView task = getTaskViewAt(i);
|
||||
TaskView task = requireTaskViewAt(i);
|
||||
task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY());
|
||||
}
|
||||
runActionOnRemoteHandles(
|
||||
@@ -3779,14 +3786,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private void updateTaskViewsSnapshotRadius() {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
getTaskViewAt(i).updateSnapshotRadius();
|
||||
requireTaskViewAt(i).updateSnapshotRadius();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTaskViewsPrimarySplitTranslation(float translation) {
|
||||
mTaskViewsPrimarySplitTranslation = translation;
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView task = getTaskViewAt(i);
|
||||
TaskView task = requireTaskViewAt(i);
|
||||
task.getPrimarySplitTranslationProperty().set(task, translation);
|
||||
}
|
||||
}
|
||||
@@ -3794,7 +3801,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
protected void setTaskViewsSecondarySplitTranslation(float translation) {
|
||||
mTaskViewsSecondarySplitTranslation = translation;
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (taskView == mSplitHiddenTaskView) {
|
||||
continue;
|
||||
}
|
||||
@@ -3808,7 +3815,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
public void applySplitPrimaryScrollOffset() {
|
||||
if (isSplitPlaceholderFirstInGrid()) {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
getTaskViewAt(i).setSplitScrollOffsetPrimary(mSplitPlaceholderSize);
|
||||
requireTaskViewAt(i).setSplitScrollOffsetPrimary(mSplitPlaceholderSize);
|
||||
}
|
||||
} else if (isSplitPlaceholderLastInGrid()) {
|
||||
mClearAllButton.setSplitSelectScrollOffsetPrimary(-mSplitPlaceholderSize);
|
||||
@@ -3850,7 +3857,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
*/
|
||||
public void resetSplitPrimaryScrollOffset() {
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
getTaskViewAt(i).setSplitScrollOffsetPrimary(0);
|
||||
requireTaskViewAt(i).setSplitScrollOffsetPrimary(0);
|
||||
}
|
||||
mClearAllButton.setSplitSelectScrollOffsetPrimary(0);
|
||||
}
|
||||
@@ -3930,109 +3937,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
pendingAnimation.buildAnim().start();
|
||||
}
|
||||
|
||||
public PendingAnimation cancelSplitSelect(boolean animate) {
|
||||
SplitSelectStateController splitController = mSplitSelectStateController;
|
||||
@StagePosition int stagePosition = splitController.getActiveSplitStagePosition();
|
||||
Rect initialBounds = splitController.getInitialBounds();
|
||||
splitController.resetState();
|
||||
int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
|
||||
PendingAnimation pendingAnim = new PendingAnimation(duration);
|
||||
mSplitToast.cancel();
|
||||
mSplitUnsupportedToast.cancel();
|
||||
if (!animate) {
|
||||
resetFromSplitSelectionState();
|
||||
return pendingAnim;
|
||||
}
|
||||
|
||||
addViewInLayout(mSplitHiddenTaskView, mSplitHiddenTaskViewIndex,
|
||||
mSplitHiddenTaskView.getLayoutParams());
|
||||
mSplitHiddenTaskView.setAlpha(0);
|
||||
int[] oldScroll = new int[getChildCount()];
|
||||
getPageScrolls(oldScroll, false,
|
||||
view -> view.getVisibility() != GONE && view != mSplitHiddenTaskView);
|
||||
|
||||
int[] newScroll = new int[getChildCount()];
|
||||
getPageScrolls(newScroll, false, SIMPLE_SCROLL_LOGIC);
|
||||
|
||||
boolean needsCurveUpdates = false;
|
||||
for (int i = mSplitHiddenTaskViewIndex; i >= 0; i--) {
|
||||
View child = getChildAt(i);
|
||||
if (child == mSplitHiddenTaskView) {
|
||||
TaskView taskView = (TaskView) child;
|
||||
|
||||
int dir = mOrientationHandler.getSplitTaskViewDismissDirection(stagePosition,
|
||||
mActivity.getDeviceProfile());
|
||||
FloatProperty<TaskView> dismissingTaskViewTranslate;
|
||||
Rect hiddenBounds = new Rect(taskView.getLeft(), taskView.getTop(),
|
||||
taskView.getRight(), taskView.getBottom());
|
||||
int distanceDelta = 0;
|
||||
if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE) {
|
||||
dismissingTaskViewTranslate = taskView
|
||||
.getSecondaryDissmissTranslationProperty();
|
||||
distanceDelta = initialBounds.top - hiddenBounds.top;
|
||||
taskView.layout(initialBounds.left, hiddenBounds.top, initialBounds.right,
|
||||
hiddenBounds.bottom);
|
||||
} else {
|
||||
dismissingTaskViewTranslate = taskView
|
||||
.getPrimaryDismissTranslationProperty();
|
||||
distanceDelta = initialBounds.left - hiddenBounds.left;
|
||||
taskView.layout(hiddenBounds.left, initialBounds.top, hiddenBounds.right,
|
||||
initialBounds.bottom);
|
||||
if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE) {
|
||||
distanceDelta *= -1;
|
||||
}
|
||||
}
|
||||
pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView,
|
||||
dismissingTaskViewTranslate,
|
||||
distanceDelta));
|
||||
pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, ALPHA, 1));
|
||||
} else {
|
||||
// If insertion is on last index (furthest from clear all), we directly add the view
|
||||
// else we translate all views to the right of insertion index further right,
|
||||
// ignore views to left
|
||||
if (showAsGrid()) {
|
||||
// TODO(b/186800707) handle more elegantly for grid
|
||||
continue;
|
||||
}
|
||||
int scrollDiff = newScroll[i] - oldScroll[i];
|
||||
if (scrollDiff != 0) {
|
||||
FloatProperty translationProperty = child instanceof TaskView
|
||||
? ((TaskView) child).getPrimaryDismissTranslationProperty()
|
||||
: mOrientationHandler.getPrimaryViewTranslate();
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(mActivity);
|
||||
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_END)
|
||||
.setDampingRatio(
|
||||
rp.getFloat(R.dimen.dismiss_task_trans_x_damping_ratio))
|
||||
.setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_x_stiffness));
|
||||
pendingAnim.add(ObjectAnimator.ofFloat(child, translationProperty, scrollDiff)
|
||||
.setDuration(duration), ACCEL, sp);
|
||||
needsCurveUpdates = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needsCurveUpdates) {
|
||||
pendingAnim.addOnFrameCallback(this::updateCurveProperties);
|
||||
}
|
||||
|
||||
pendingAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
// TODO(b/186800707) Figure out how to undo for grid view
|
||||
// Need to handle cases where dismissed task is
|
||||
// * Top Row
|
||||
// * Bottom Row
|
||||
// * Focused Task
|
||||
updateGridProperties();
|
||||
resetFromSplitSelectionState();
|
||||
updateScrollSynchronously();
|
||||
}
|
||||
});
|
||||
|
||||
return pendingAnim;
|
||||
}
|
||||
|
||||
/** TODO(b/181707736) More gracefully handle exiting split selection state */
|
||||
private void resetFromSplitSelectionState() {
|
||||
if (!mActivity.getDeviceProfile().overviewShowAsGrid) {
|
||||
@@ -4077,8 +3981,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mTaskViewDeadZoneRect.setEmpty();
|
||||
int count = getTaskViewCount();
|
||||
if (count > 0) {
|
||||
final View taskView = getTaskViewAt(0);
|
||||
getTaskViewAt(count - 1).getHitRect(mTaskViewDeadZoneRect);
|
||||
final View taskView = requireTaskViewAt(0);
|
||||
requireTaskViewAt(count - 1).getHitRect(mTaskViewDeadZoneRect);
|
||||
mTaskViewDeadZoneRect.union(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
|
||||
taskView.getBottom());
|
||||
}
|
||||
@@ -4559,7 +4463,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
final int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
TaskView taskView = getTaskViewAt(i);
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
float scrollDiff = taskView.getScrollAdjustment(showAsFullscreen, showAsGrid);
|
||||
int pageScroll = newPageScrolls[i] + (int) scrollDiff;
|
||||
if ((mIsRtl && pageScroll < clearAllScroll + clearAllWidth)
|
||||
@@ -4727,7 +4631,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1;
|
||||
int taskCount = getTaskViewCount();
|
||||
for (int i = 0; i < taskCount; i++) {
|
||||
getTaskViewAt(i).setOverlayEnabled(i == overlayEnabledPage);
|
||||
requireTaskViewAt(i).setOverlayEnabled(i == overlayEnabledPage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4881,7 +4785,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mColorTint = tintAmount;
|
||||
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
getTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
|
||||
requireTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
|
||||
}
|
||||
|
||||
Drawable scrimBg = mActivity.getScrimView().getBackground();
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.quickstep.views;
|
||||
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
|
||||
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
|
||||
|
||||
import static com.android.launcher3.Utilities.comp;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
|
||||
|
||||
@@ -290,8 +291,17 @@ public class TaskThumbnailView extends View {
|
||||
float cornerRadius) {
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
if (mTask != null && getTaskView().isRunningTask() && !getTaskView().showScreenshot()) {
|
||||
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mClearPaint);
|
||||
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius,
|
||||
// TODO(b/189265196): Temporary fix to align the surface with the cutout perfectly.
|
||||
// Round up only when the live tile task is displayed in Overview.
|
||||
float rounding = comp(mFullscreenParams.mFullscreenProgress);
|
||||
float left = x + rounding / 2;
|
||||
float top = y + rounding / 2;
|
||||
float right = width - rounding;
|
||||
float bottom = height - rounding;
|
||||
|
||||
canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius,
|
||||
mClearPaint);
|
||||
canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius,
|
||||
mDimmingPaintAfterClearing);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1531,6 +1531,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
private final float mCornerRadius;
|
||||
private final float mWindowCornerRadius;
|
||||
|
||||
public float mFullscreenProgress;
|
||||
public RectF mCurrentDrawnInsets = new RectF();
|
||||
public float mCurrentDrawnCornerRadius;
|
||||
/** The current scale we apply to the thumbnail to adjust for new left/right insets. */
|
||||
@@ -1548,6 +1549,8 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
*/
|
||||
public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale,
|
||||
int previewWidth, DeviceProfile dp, PreviewPositionHelper pph) {
|
||||
mFullscreenProgress = fullscreenProgress;
|
||||
|
||||
RectF insets = pph.getInsetsToDrawInFullscreen(dp);
|
||||
|
||||
float currentInsetsLeft = insets.left * fullscreenProgress;
|
||||
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y;
|
||||
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
|
||||
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
|
||||
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
|
||||
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
|
||||
import static com.android.launcher3.taskbar.TaskbarNavButtonController.SCREEN_PIN_LONG_PRESS_THRESHOLD;
|
||||
import static com.android.quickstep.OverviewCommandHelper.TYPE_HOME;
|
||||
import static com.android.quickstep.OverviewCommandHelper.TYPE_TOGGLE;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.quickstep.OverviewCommandHelper;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TouchInteractionService;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TaskbarNavButtonControllerTest {
|
||||
|
||||
private final static int DISPLAY_ID = 2;
|
||||
|
||||
@Mock
|
||||
SystemUiProxy mockSystemUiProxy;
|
||||
@Mock
|
||||
TouchInteractionService mockService;
|
||||
@Mock
|
||||
OverviewCommandHelper mockCommandHelper;
|
||||
@Mock
|
||||
Handler mockHandler;
|
||||
|
||||
private TaskbarNavButtonController mNavButtonController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mockService.getDisplayId()).thenReturn(DISPLAY_ID);
|
||||
when(mockService.getOverviewCommandHelper()).thenReturn(mockCommandHelper);
|
||||
mNavButtonController = new TaskbarNavButtonController(mockService,
|
||||
mockSystemUiProxy, mockHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPressBack() {
|
||||
mNavButtonController.onButtonClick(BUTTON_BACK);
|
||||
verify(mockSystemUiProxy, times(1)).onBackPressed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPressImeSwitcher() {
|
||||
mNavButtonController.onButtonClick(BUTTON_IME_SWITCH);
|
||||
verify(mockSystemUiProxy, times(1)).onImeSwitcherPressed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPressA11yShortClick() {
|
||||
mNavButtonController.onButtonClick(BUTTON_A11Y);
|
||||
verify(mockSystemUiProxy, times(1))
|
||||
.notifyAccessibilityButtonClicked(DISPLAY_ID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPressA11yLongClick() {
|
||||
mNavButtonController.onButtonLongClick(BUTTON_A11Y);
|
||||
verify(mockSystemUiProxy, times(1)).notifyAccessibilityButtonLongClicked();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongPressHome() {
|
||||
mNavButtonController.onButtonLongClick(BUTTON_HOME);
|
||||
verify(mockSystemUiProxy, times(1)).startAssistant(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPressHome() {
|
||||
mNavButtonController.onButtonClick(BUTTON_HOME);
|
||||
verify(mockCommandHelper, times(1)).addCommand(TYPE_HOME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPressRecents() {
|
||||
mNavButtonController.onButtonClick(BUTTON_RECENTS);
|
||||
verify(mockCommandHelper, times(1)).addCommand(TYPE_TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPressRecentsWithScreenPinned() {
|
||||
mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
|
||||
mNavButtonController.onButtonClick(BUTTON_RECENTS);
|
||||
verify(mockCommandHelper, times(0)).addCommand(TYPE_TOGGLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongPressBackRecentsNotPinned() {
|
||||
mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
|
||||
mNavButtonController.onButtonLongClick(BUTTON_BACK);
|
||||
verify(mockSystemUiProxy, times(0)).stopScreenPinning();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongPressBackRecentsPinned() {
|
||||
mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
|
||||
mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
|
||||
mNavButtonController.onButtonLongClick(BUTTON_BACK);
|
||||
verify(mockSystemUiProxy, times(1)).stopScreenPinning();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongPressBackRecentsTooLongPinned() {
|
||||
mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
|
||||
mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
|
||||
try {
|
||||
Thread.sleep(SCREEN_PIN_LONG_PRESS_THRESHOLD + 5);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
mNavButtonController.onButtonLongClick(BUTTON_BACK);
|
||||
verify(mockSystemUiProxy, times(0)).stopScreenPinning();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongPressBackRecentsMultipleAttemptPinned() {
|
||||
mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
|
||||
mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
|
||||
try {
|
||||
Thread.sleep(SCREEN_PIN_LONG_PRESS_THRESHOLD + 5);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
mNavButtonController.onButtonLongClick(BUTTON_BACK);
|
||||
verify(mockSystemUiProxy, times(0)).stopScreenPinning();
|
||||
|
||||
// Try again w/in threshold
|
||||
mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
|
||||
mNavButtonController.onButtonLongClick(BUTTON_BACK);
|
||||
verify(mockSystemUiProxy, times(1)).stopScreenPinning();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongPressHomeScreenPinned() {
|
||||
mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
|
||||
mNavButtonController.onButtonLongClick(BUTTON_HOME);
|
||||
verify(mockSystemUiProxy, times(0)).startAssistant(any());
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,9 @@ import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
@@ -44,7 +45,7 @@ public class Snackbar extends AbstractFloatingView {
|
||||
private static final long HIDE_DURATION_MS = 180;
|
||||
private static final int TIMEOUT_DURATION_MS = 4000;
|
||||
|
||||
private final BaseDraggingActivity mActivity;
|
||||
private final ActivityContext mActivity;
|
||||
private Runnable mOnDismissed;
|
||||
|
||||
public Snackbar(Context context, AttributeSet attrs) {
|
||||
@@ -53,12 +54,19 @@ public class Snackbar extends AbstractFloatingView {
|
||||
|
||||
public Snackbar(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mActivity = BaseDraggingActivity.fromContext(context);
|
||||
mActivity = ActivityContext.lookupContext(context);
|
||||
inflate(context, R.layout.snackbar, this);
|
||||
}
|
||||
|
||||
public static void show(BaseDraggingActivity activity, int labelStringResId,
|
||||
int actionStringResId, Runnable onDismissed, Runnable onActionClicked) {
|
||||
/** Show a snackbar with just a label. */
|
||||
public static <T extends Context & ActivityContext> void show(T activity, int labelStringRedId,
|
||||
Runnable onDismissed) {
|
||||
show(activity, labelStringRedId, NO_ID, onDismissed, null);
|
||||
}
|
||||
|
||||
/** Show a snackbar with a label and action. */
|
||||
public static <T extends Context & ActivityContext> void show(T activity, int labelStringResId,
|
||||
int actionStringResId, Runnable onDismissed, @Nullable Runnable onActionClicked) {
|
||||
closeOpenViews(activity, true, TYPE_SNACKBAR);
|
||||
Snackbar snackbar = new Snackbar(activity, null);
|
||||
// Set some properties here since inflated xml only contains the children.
|
||||
@@ -87,13 +95,30 @@ public class Snackbar extends AbstractFloatingView {
|
||||
params.setMargins(0, 0, 0, marginBottom + insets.bottom);
|
||||
|
||||
TextView labelView = snackbar.findViewById(R.id.label);
|
||||
TextView actionView = snackbar.findViewById(R.id.action);
|
||||
String labelText = res.getString(labelStringResId);
|
||||
String actionText = res.getString(actionStringResId);
|
||||
int totalContentWidth = (int) (labelView.getPaint().measureText(labelText)
|
||||
+ actionView.getPaint().measureText(actionText))
|
||||
labelView.setText(labelText);
|
||||
|
||||
TextView actionView = snackbar.findViewById(R.id.action);
|
||||
float actionWidth;
|
||||
if (actionStringResId != NO_ID) {
|
||||
String actionText = res.getString(actionStringResId);
|
||||
actionWidth = actionView.getPaint().measureText(actionText)
|
||||
+ actionView.getPaddingRight() + actionView.getPaddingLeft();
|
||||
actionView.setText(actionText);
|
||||
actionView.setOnClickListener(v -> {
|
||||
if (onActionClicked != null) {
|
||||
onActionClicked.run();
|
||||
}
|
||||
snackbar.mOnDismissed = null;
|
||||
snackbar.close(true);
|
||||
});
|
||||
} else {
|
||||
actionWidth = 0;
|
||||
actionView.setVisibility(GONE);
|
||||
}
|
||||
|
||||
int totalContentWidth = (int) (labelView.getPaint().measureText(labelText) + actionWidth)
|
||||
+ labelView.getPaddingRight() + labelView.getPaddingLeft()
|
||||
+ actionView.getPaddingRight() + actionView.getPaddingLeft()
|
||||
+ padding * 2;
|
||||
if (totalContentWidth > params.width) {
|
||||
// The text doesn't fit in our standard width so update width to accommodate.
|
||||
@@ -113,17 +138,8 @@ public class Snackbar extends AbstractFloatingView {
|
||||
params.width = maxWidth;
|
||||
}
|
||||
}
|
||||
labelView.setText(labelText);
|
||||
actionView.setText(actionText);
|
||||
actionView.setOnClickListener(v -> {
|
||||
if (onActionClicked != null) {
|
||||
onActionClicked.run();
|
||||
}
|
||||
snackbar.mOnDismissed = null;
|
||||
snackbar.close(true);
|
||||
});
|
||||
snackbar.mOnDismissed = onDismissed;
|
||||
|
||||
snackbar.mOnDismissed = onDismissed;
|
||||
snackbar.setAlpha(0);
|
||||
snackbar.setScaleX(0.8f);
|
||||
snackbar.setScaleY(0.8f);
|
||||
|
||||
@@ -77,7 +77,8 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
|
||||
mLauncher.scroll(
|
||||
widgetsContainer,
|
||||
Direction.UP,
|
||||
new Rect(0, 0, mLauncher.getVisibleBounds(widgetsContainer).width(), 0),
|
||||
new Rect(0, 0, mLauncher.getRightGestureMarginInContainer(widgetsContainer) + 1,
|
||||
0),
|
||||
FLING_STEPS, false);
|
||||
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung back")) {
|
||||
verifyActiveContainer();
|
||||
|
||||
Reference in New Issue
Block a user