Snap for 9024801 from afff936235 to tm-qpr1-release
Change-Id: I64b24d1722728fa372b3774106eb1fc658fd6fae
This commit is contained in:
@@ -117,14 +117,15 @@ public class QuickstepModelDelegate extends ModelDelegate {
|
||||
// TODO: Implement caching and preloading
|
||||
super.loadItems(ums, pinnedShortcuts);
|
||||
|
||||
WorkspaceItemFactory allAppsFactory = new WorkspaceItemFactory(
|
||||
mApp, ums, pinnedShortcuts, mIDP.numDatabaseAllAppsColumns);
|
||||
FixedContainerItems allAppsItems = new FixedContainerItems(mAllAppsState.containerId,
|
||||
mAllAppsState.storage.read(mApp.getContext(), allAppsFactory, ums.allUsers::get));
|
||||
mDataModel.extraItems.put(mAllAppsState.containerId, allAppsItems);
|
||||
WorkspaceItemFactory allAppsFactory = new WorkspaceItemFactory(mApp, ums, pinnedShortcuts,
|
||||
mIDP.numDatabaseAllAppsColumns, mAllAppsState.containerId);
|
||||
FixedContainerItems allAppsPredictionItems = new FixedContainerItems(
|
||||
mAllAppsState.containerId, mAllAppsState.storage.read(mApp.getContext(),
|
||||
allAppsFactory, ums.allUsers::get));
|
||||
mDataModel.extraItems.put(mAllAppsState.containerId, allAppsPredictionItems);
|
||||
|
||||
WorkspaceItemFactory hotseatFactory =
|
||||
new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numDatabaseHotseatIcons);
|
||||
WorkspaceItemFactory hotseatFactory = new WorkspaceItemFactory(mApp, ums, pinnedShortcuts,
|
||||
mIDP.numDatabaseHotseatIcons, mHotseatState.containerId);
|
||||
FixedContainerItems hotseatItems = new FixedContainerItems(mHotseatState.containerId,
|
||||
mHotseatState.storage.read(mApp.getContext(), hotseatFactory, ums.allUsers::get));
|
||||
mDataModel.extraItems.put(mHotseatState.containerId, hotseatItems);
|
||||
@@ -432,15 +433,17 @@ public class QuickstepModelDelegate extends ModelDelegate {
|
||||
private final UserManagerState mUMS;
|
||||
private final Map<ShortcutKey, ShortcutInfo> mPinnedShortcuts;
|
||||
private final int mMaxCount;
|
||||
private final int mContainer;
|
||||
|
||||
private int mReadCount = 0;
|
||||
|
||||
protected WorkspaceItemFactory(LauncherAppState appState, UserManagerState ums,
|
||||
Map<ShortcutKey, ShortcutInfo> pinnedShortcuts, int maxCount) {
|
||||
Map<ShortcutKey, ShortcutInfo> pinnedShortcuts, int maxCount, int container) {
|
||||
mAppState = appState;
|
||||
mUMS = ums;
|
||||
mPinnedShortcuts = pinnedShortcuts;
|
||||
mMaxCount = maxCount;
|
||||
mContainer = container;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -458,6 +461,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
|
||||
return null;
|
||||
}
|
||||
AppInfo info = new AppInfo(lai, user, mUMS.isUserQuiet(user));
|
||||
info.container = mContainer;
|
||||
mAppState.getIconCache().getTitleAndIcon(info, lai, false);
|
||||
mReadCount++;
|
||||
return info.makeWorkspaceItem(mAppState.getContext());
|
||||
@@ -472,6 +476,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
|
||||
return null;
|
||||
}
|
||||
WorkspaceItemInfo wii = new WorkspaceItemInfo(si, mAppState.getContext());
|
||||
wii.container = mContainer;
|
||||
mAppState.getIconCache().getShortcutIcon(wii, si);
|
||||
mReadCount++;
|
||||
return wii;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_RESUMED;
|
||||
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
|
||||
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -169,6 +170,13 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
||||
}
|
||||
}
|
||||
|
||||
if (ENABLE_SHELL_TRANSITIONS
|
||||
&& !mLauncher.getStateManager().getState().isTaskbarAlignedWithHotseat(mLauncher)) {
|
||||
// Launcher is resumed, but in a state where taskbar is still independent, so
|
||||
// ignore the state change.
|
||||
return null;
|
||||
}
|
||||
|
||||
mTaskbarLauncherStateController.updateStateForFlag(FLAG_RESUMED, isResumed);
|
||||
return mTaskbarLauncherStateController.applyState(fromInit ? 0 : duration, startAnimation);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
package com.android.launcher3.taskbar.allapps;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
|
||||
import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
|
||||
import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
|
||||
|
||||
import android.animation.PropertyValuesHolder;
|
||||
import android.content.Context;
|
||||
@@ -60,7 +59,7 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllApp
|
||||
if (animate) {
|
||||
mOpenCloseAnimator.setValues(
|
||||
PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
|
||||
mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE);
|
||||
mOpenCloseAnimator.setInterpolator(EMPHASIZED);
|
||||
mOpenCloseAnimator.setDuration(
|
||||
ALL_APPS.getTransitionDuration(mActivityContext, true /* isToState */)).start();
|
||||
} else {
|
||||
@@ -87,7 +86,7 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllApp
|
||||
|
||||
@Override
|
||||
protected Interpolator getIdleInterpolator() {
|
||||
return EMPHASIZED_ACCELERATE;
|
||||
return EMPHASIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -28,11 +28,10 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SP
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
import static com.android.quickstep.views.FloatingTaskView.PRIMARY_TRANSLATE_OFFSCREEN;
|
||||
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
|
||||
import static com.android.quickstep.views.RecentsView.FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.SPLIT_INSTRUCTIONS_FADE;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_THUMBNAIL_SPLASH_ALPHA;
|
||||
|
||||
@@ -112,6 +111,7 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
// TODO (b/238651489): Refactor state management to avoid need for double check
|
||||
FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView();
|
||||
if (floatingTask != null) {
|
||||
// We are in split selection state currently, transitioning to another state
|
||||
DragLayer dragLayer = mLauncher.getDragLayer();
|
||||
RectF onScreenRectF = new RectF();
|
||||
Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), floatingTask,
|
||||
@@ -127,8 +127,8 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
);
|
||||
|
||||
setter.setFloat(
|
||||
mRecentsView,
|
||||
FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN,
|
||||
mRecentsView.getFirstFloatingTaskView(),
|
||||
PRIMARY_TRANSLATE_OFFSCREEN,
|
||||
mRecentsView.getPagedOrientationHandler()
|
||||
.getFloatingTaskOffscreenTranslationTarget(
|
||||
floatingTask,
|
||||
@@ -140,14 +140,14 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
|
||||
LINEAR
|
||||
));
|
||||
setter.setFloat(
|
||||
mRecentsView,
|
||||
SPLIT_INSTRUCTIONS_FADE,
|
||||
1,
|
||||
setter.setViewAlpha(
|
||||
mRecentsView.getSplitInstructionsView(),
|
||||
0,
|
||||
config.getInterpolator(
|
||||
ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
|
||||
LINEAR
|
||||
));
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemProperties;
|
||||
import android.view.Display;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.View;
|
||||
@@ -159,6 +160,9 @@ import java.util.stream.Stream;
|
||||
|
||||
public class QuickstepLauncher extends Launcher {
|
||||
|
||||
public static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
|
||||
SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false);
|
||||
|
||||
public static final boolean GO_LOW_RAM_RECENTS_ENABLED = false;
|
||||
/**
|
||||
* Reusable command for applying the shelf height on the background thread.
|
||||
@@ -349,16 +353,18 @@ public class QuickstepLauncher extends Launcher {
|
||||
*/
|
||||
private void onStateOrResumeChanging(boolean inTransition) {
|
||||
LauncherState state = getStateManager().getState();
|
||||
boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0;
|
||||
if (started) {
|
||||
DeviceProfile profile = getDeviceProfile();
|
||||
boolean willUserBeActive =
|
||||
(getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
|
||||
boolean visible = (state == NORMAL || state == OVERVIEW)
|
||||
&& (willUserBeActive || isUserActive())
|
||||
&& !profile.isVerticalBarLayout();
|
||||
UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0,
|
||||
profile.hotseatBarSizePx);
|
||||
if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
|
||||
boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0;
|
||||
if (started) {
|
||||
DeviceProfile profile = getDeviceProfile();
|
||||
boolean willUserBeActive =
|
||||
(getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
|
||||
boolean visible = (state == NORMAL || state == OVERVIEW)
|
||||
&& (willUserBeActive || isUserActive())
|
||||
&& !profile.isVerticalBarLayout();
|
||||
UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0,
|
||||
profile.hotseatBarSizePx);
|
||||
}
|
||||
}
|
||||
if (state == NORMAL && !inTransition) {
|
||||
((RecentsView) getOverviewPanel()).setSwipeDownShouldLaunchApp(false);
|
||||
|
||||
@@ -16,14 +16,17 @@
|
||||
package com.android.launcher3.uioverrides.states;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
/**
|
||||
@@ -41,9 +44,9 @@ public class AllAppsState extends LauncherState {
|
||||
@Override
|
||||
public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
|
||||
int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
|
||||
return !context.getDeviceProfile().isTablet && isToState
|
||||
? 600
|
||||
: isToState ? 500 : 300;
|
||||
return context.getDeviceProfile().isTablet
|
||||
? 500
|
||||
: isToState ? 600 : 300;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,10 +80,23 @@ public class AllAppsState extends LauncherState {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getDepthUnchecked(Context context) {
|
||||
// The scrim fades in at approximately 50% of the swipe gesture.
|
||||
// This means that the depth should be greater than 1, in order to fully zoom out.
|
||||
return 2f;
|
||||
protected <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
|
||||
float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
|
||||
if (context.getDeviceProfile().isTablet) {
|
||||
// The goal is to set wallpaper to zoom at workspaceContentScale when in AllApps.
|
||||
// When depth is 0, wallpaper zoom is set to maxWallpaperScale.
|
||||
// When depth is 1, wallpaper zoom is set to 1.
|
||||
// For depth to achieve zoom set to maxWallpaperScale * workspaceContentScale:
|
||||
float maxWallpaperScale = context.getResources().getFloat(
|
||||
com.android.internal.R.dimen.config_wallpaperMaxScale);
|
||||
return Utilities.mapToRange(
|
||||
maxWallpaperScale * context.getDeviceProfile().workspaceContentScale,
|
||||
maxWallpaperScale, 1f, 0f, 1f, LINEAR);
|
||||
} else {
|
||||
// The scrim fades in at approximately 50% of the swipe gesture.
|
||||
// This means that the depth should be greater than 1, in order to fully zoom out.
|
||||
return 2f;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.launcher3.uioverrides.states;
|
||||
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||
import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
@@ -101,6 +102,12 @@ public class BackgroundAppState extends OverviewState {
|
||||
return Color.TRANSPARENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
|
||||
if (ENABLE_SHELL_TRANSITIONS) return false;
|
||||
return super.isTaskbarAlignedWithHotseat(launcher);
|
||||
}
|
||||
|
||||
public static float[] getOverviewScaleAndOffsetForBackgroundState(
|
||||
BaseDraggingActivity activity) {
|
||||
return new float[] {
|
||||
|
||||
@@ -33,6 +33,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
|
||||
import static com.android.launcher3.uioverrides.QuickstepLauncher.ENABLE_PIP_KEEP_CLEAR_ALGORITHM;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
|
||||
@@ -1461,12 +1462,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
homeToWindowPositionMap.invert(windowToHomePositionMap);
|
||||
windowToHomePositionMap.mapRect(startRect);
|
||||
|
||||
final Rect hotseatKeepClearArea = getKeepClearAreaForHotseat();
|
||||
final Rect destinationBounds = SystemUiProxy.INSTANCE.get(mContext)
|
||||
.startSwipePipToHome(taskInfo.topActivity,
|
||||
taskInfo.topActivityInfo,
|
||||
runningTaskTarget.taskInfo.pictureInPictureParams,
|
||||
homeRotation,
|
||||
mDp.hotseatBarSizePx);
|
||||
hotseatKeepClearArea);
|
||||
final Rect appBounds = new Rect();
|
||||
final WindowConfiguration winConfig = taskInfo.configuration.windowConfiguration;
|
||||
// Adjust the appBounds for TaskBar by using the calculated window crop Rect
|
||||
@@ -1529,6 +1531,35 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
return swipePipToHomeAnimator;
|
||||
}
|
||||
|
||||
private Rect getKeepClearAreaForHotseat() {
|
||||
Rect keepClearArea;
|
||||
if (!ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
|
||||
// make the height equal to hotseatBarSizePx only
|
||||
keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, 0);
|
||||
return keepClearArea;
|
||||
}
|
||||
// the keep clear area in global screen coordinates, in pixels
|
||||
if (mDp.isPhone) {
|
||||
if (mDp.isSeascape()) {
|
||||
// in seascape the Hotseat is on the left edge of the screen
|
||||
keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, mDp.heightPx);
|
||||
} else if (mDp.isLandscape) {
|
||||
// in landscape the Hotseat is on the right edge of the screen
|
||||
keepClearArea = new Rect(mDp.widthPx - mDp.hotseatBarSizePx, 0,
|
||||
mDp.widthPx, mDp.heightPx);
|
||||
} else {
|
||||
// in portrait mode the Hotseat is at the bottom of the screen
|
||||
keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx,
|
||||
mDp.widthPx, mDp.heightPx);
|
||||
}
|
||||
} else {
|
||||
// large screens have Hotseat always at the bottom of the screen
|
||||
keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx,
|
||||
mDp.widthPx, mDp.heightPx);
|
||||
}
|
||||
return keepClearArea;
|
||||
}
|
||||
|
||||
private void startInterceptingTouchesForGesture() {
|
||||
if (mRecentsAnimationController == null) {
|
||||
return;
|
||||
|
||||
@@ -28,7 +28,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
@@ -509,11 +509,12 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
|
||||
}
|
||||
|
||||
public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
|
||||
PictureInPictureParams pictureInPictureParams, int launcherRotation, int shelfHeight) {
|
||||
PictureInPictureParams pictureInPictureParams, int launcherRotation,
|
||||
Rect hotseatKeepClearArea) {
|
||||
if (mPip != null) {
|
||||
try {
|
||||
return mPip.startSwipePipToHome(componentName, activityInfo,
|
||||
pictureInPictureParams, launcherRotation, shelfHeight);
|
||||
pictureInPictureParams, launcherRotation, hotseatKeepClearArea);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call startSwipePipToHome", e);
|
||||
}
|
||||
@@ -602,7 +603,21 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
|
||||
mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent,
|
||||
taskId, mainOptions, sideOptions, sidePosition, splitRatio, adapter);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call startTasksWithLegacyTransition");
|
||||
Log.w(TAG, "Failed call startIntentAndTaskWithLegacyTransition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, int taskId,
|
||||
Bundle mainOptions, Bundle sideOptions,
|
||||
@SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio,
|
||||
RemoteAnimationAdapter adapter) {
|
||||
if (mSystemUiProxy != null) {
|
||||
try {
|
||||
mSplitScreen.startShortcutAndTaskWithLegacyTransition(shortcutInfo, taskId,
|
||||
mainOptions, sideOptions, sidePosition, splitRatio, adapter);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(TAG, "Failed call startShortcutAndTaskWithLegacyTransition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,8 @@ public final class TaskViewUtils {
|
||||
|
||||
int taskIndex = recentsView.indexOfChild(v);
|
||||
Context context = v.getContext();
|
||||
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
|
||||
BaseActivity baseActivity = BaseActivity.fromContext(context);
|
||||
DeviceProfile dp = baseActivity.getDeviceProfile();
|
||||
boolean showAsGrid = dp.isTablet;
|
||||
boolean parallaxCenterAndAdjacentTask =
|
||||
taskIndex != recentsView.getCurrentPage() && !showAsGrid;
|
||||
@@ -368,7 +369,7 @@ public final class TaskViewUtils {
|
||||
});
|
||||
|
||||
if (depthController != null) {
|
||||
out.setFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(context),
|
||||
out.setFloat(depthController, DEPTH, BACKGROUND_APP.getDepth(baseActivity),
|
||||
TOUCH_RESPONSE_INTERPOLATOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,6 +226,11 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
setFreezeViewVisibility(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionFailed(RecentsState toState) {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(RecentsState finalState) {
|
||||
if (finalState == HOME) {
|
||||
|
||||
@@ -31,16 +31,20 @@ import android.app.ActivityThread;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.RemoteAnimationAdapter;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
@@ -66,6 +70,7 @@ import java.util.function.Consumer;
|
||||
* and is in the process of either a) selecting a second app or b) exiting intention to invoke split
|
||||
*/
|
||||
public class SplitSelectStateController {
|
||||
private static final String TAG = "SplitSelectStateCtor";
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
@@ -196,7 +201,7 @@ public class SplitSelectStateController {
|
||||
null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, splitRatio,
|
||||
new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR,
|
||||
ActivityThread.currentActivityThread().getApplicationThread()));
|
||||
// TODO: handle intent + task with shell transition
|
||||
// TODO(b/237635859): handle intent/shortcut + task with shell transition
|
||||
} else {
|
||||
RemoteSplitLaunchAnimationRunner animationRunner =
|
||||
new RemoteSplitLaunchAnimationRunner(taskId1, taskPendingIntent, taskId2,
|
||||
@@ -215,9 +220,17 @@ public class SplitSelectStateController {
|
||||
taskIds[1], null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
|
||||
splitRatio, adapter);
|
||||
} else {
|
||||
mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent,
|
||||
fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */,
|
||||
stagePosition, splitRatio, adapter);
|
||||
final ShortcutInfo shortcutInfo = getShortcutInfo(mInitialTaskIntent,
|
||||
taskPendingIntent.getCreatorUserHandle());
|
||||
if (shortcutInfo != null) {
|
||||
mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(shortcutInfo, taskId2,
|
||||
mainOpts.toBundle(), null /* sideOptions */, stagePosition, splitRatio,
|
||||
adapter);
|
||||
} else {
|
||||
mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent,
|
||||
fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */,
|
||||
stagePosition, splitRatio, adapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,6 +243,28 @@ public class SplitSelectStateController {
|
||||
this.mRecentsAnimationRunning = running;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ShortcutInfo getShortcutInfo(Intent intent, UserHandle userHandle) {
|
||||
if (intent == null || intent.getPackage() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String shortcutId = intent.getStringExtra(ShortcutKey.EXTRA_SHORTCUT_ID);
|
||||
if (shortcutId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
final Context context = mContext.createPackageContextAsUser(
|
||||
intent.getPackage(), 0 /* flags */, userHandle);
|
||||
return new ShortcutInfo.Builder(context, shortcutId).build();
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "Failed to create a ShortcutInfo for " + intent.getPackage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires Shell Transitions
|
||||
*/
|
||||
|
||||
@@ -102,7 +102,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
private boolean mLayoutValid = false;
|
||||
private int mOrientationStateId;
|
||||
private SplitBounds mSplitBounds;
|
||||
private boolean mDrawsBelowRecents;
|
||||
private Boolean mDrawsBelowRecents = null;
|
||||
private boolean mIsGridTask;
|
||||
private int mTaskRectTranslationX;
|
||||
private int mTaskRectTranslationY;
|
||||
@@ -391,7 +391,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
.withWindowCrop(mTmpCropRect)
|
||||
.withCornerRadius(getCurrentCornerRadius());
|
||||
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
// If mDrawsBelowRecents is unset, no reordering will be enforced.
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mDrawsBelowRecents != null) {
|
||||
// In legacy transitions, the animation leashes remain in same hierarchy in the
|
||||
// TaskDisplayArea, so we don't want to bump the layer too high otherwise it will
|
||||
// conflict with layers that WM core positions (ie. the input consumers). For shell
|
||||
|
||||
@@ -14,6 +14,7 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -49,6 +50,29 @@ import com.android.systemui.shared.system.QuickStepContract;
|
||||
*/
|
||||
public class FloatingTaskView extends FrameLayout {
|
||||
|
||||
public static final FloatProperty<FloatingTaskView> PRIMARY_TRANSLATE_OFFSCREEN =
|
||||
new FloatProperty<FloatingTaskView>("floatingTaskPrimaryTranslateOffscreen") {
|
||||
@Override
|
||||
public void setValue(FloatingTaskView view, float translation) {
|
||||
((RecentsView) view.mActivity.getOverviewPanel()).getPagedOrientationHandler()
|
||||
.setFloatingTaskPrimaryTranslation(
|
||||
view,
|
||||
translation,
|
||||
view.mActivity.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(FloatingTaskView view) {
|
||||
return ((RecentsView) view.mActivity.getOverviewPanel())
|
||||
.getPagedOrientationHandler()
|
||||
.getFloatingTaskPrimaryTranslation(
|
||||
view,
|
||||
view.mActivity.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
private FloatingTaskThumbnailView mThumbnailView;
|
||||
private SplitPlaceholderView mSplitPlaceholderView;
|
||||
private RectF mStartingPosition;
|
||||
|
||||
@@ -319,4 +319,10 @@ public class GroupedTaskView extends TaskView {
|
||||
super.applyThumbnailSplashAlpha();
|
||||
mSnapshotView2.setSplashAlpha(mTaskThumbnailSplashAlpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setThumbnailVisibility(int visibility) {
|
||||
super.setThumbnailVisibility(visibility);
|
||||
mSnapshotView2.setVisibility(visibility);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,11 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
setFreezeViewVisibility(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionFailed(LauncherState toState) {
|
||||
reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
if (finalState == NORMAL || finalState == SPRING_LOADED) {
|
||||
|
||||
@@ -397,39 +397,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
};
|
||||
|
||||
public static final FloatProperty<RecentsView> FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN =
|
||||
new FloatProperty<RecentsView>("firstFloatingTaskTranslateOffscreen") {
|
||||
@Override
|
||||
public void setValue(RecentsView view, float translation) {
|
||||
view.getPagedOrientationHandler().setFloatingTaskPrimaryTranslation(
|
||||
view.mFirstFloatingTaskView,
|
||||
translation,
|
||||
view.mActivity.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(RecentsView view) {
|
||||
return view.getPagedOrientationHandler().getFloatingTaskPrimaryTranslation(
|
||||
view.mFirstFloatingTaskView,
|
||||
view.mActivity.getDeviceProfile()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
public static final FloatProperty<RecentsView> SPLIT_INSTRUCTIONS_FADE =
|
||||
new FloatProperty<RecentsView>("splitInstructionsFade") {
|
||||
@Override
|
||||
public void setValue(RecentsView view, float fade) {
|
||||
view.mSplitInstructionsView.setAlpha(1 - fade);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(RecentsView view) {
|
||||
return 1 - view.mSplitInstructionsView.getAlpha();
|
||||
}
|
||||
};
|
||||
|
||||
// OverScroll constants
|
||||
private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
|
||||
|
||||
@@ -2827,7 +2794,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
RectF startingTaskRect = new RectF();
|
||||
if (mSplitHiddenTaskView != null) {
|
||||
mSplitHiddenTaskView.setVisibility(INVISIBLE);
|
||||
// Split staging is initiated, hide the original TaskView thumbnail.
|
||||
// Toggled back on in resetFromSplitSelectionState().
|
||||
mSplitHiddenTaskView.setThumbnailVisibility(INVISIBLE);
|
||||
anim.addFloat(mSplitHiddenTaskView, TaskView.ICON_ALPHA, 1, 0,
|
||||
clampToProgress(LINEAR, 0, 0.167f));
|
||||
mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
|
||||
mSplitHiddenTaskView.getThumbnail(),
|
||||
mSplitHiddenTaskView.getThumbnail().getThumbnail(),
|
||||
@@ -2855,6 +2826,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
InteractionJankMonitorWrapper.end(
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
|
||||
} else {
|
||||
// If transition to split select was interrupted, clean up to prevent glitches
|
||||
resetFromSplitSelectionState();
|
||||
InteractionJankMonitorWrapper.cancel(
|
||||
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
|
||||
}
|
||||
@@ -4222,7 +4195,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
resetTaskVisuals();
|
||||
mSplitHiddenTaskViewIndex = -1;
|
||||
if (mSplitHiddenTaskView != null) {
|
||||
mSplitHiddenTaskView.setVisibility(VISIBLE);
|
||||
// Toggle thumbnail visibility back on (turned off in
|
||||
// createInitialSplitSelectAnimation()).
|
||||
mSplitHiddenTaskView.setThumbnailVisibility(VISIBLE);
|
||||
mSplitHiddenTaskView = null;
|
||||
}
|
||||
}
|
||||
@@ -5334,6 +5309,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return mFirstFloatingTaskView;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SplitInstructionsView getSplitInstructionsView() {
|
||||
return mSplitInstructionsView;
|
||||
}
|
||||
|
||||
/** Update the current activity locus id to show the enabled state of Overview */
|
||||
public void updateLocusId() {
|
||||
String locusId = "Overview";
|
||||
|
||||
@@ -323,6 +323,19 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
}
|
||||
};
|
||||
|
||||
public static final FloatProperty<TaskView> ICON_ALPHA =
|
||||
new FloatProperty<TaskView>("iconAlpha") {
|
||||
@Override
|
||||
public void setValue(TaskView taskView, float v) {
|
||||
taskView.mIconView.setAlpha(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Float get(TaskView taskView) {
|
||||
return taskView.mIconView.getAlpha();
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
protected Task mTask;
|
||||
protected TaskThumbnailView mSnapshotView;
|
||||
@@ -1488,6 +1501,10 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
return display != null ? display.getDisplayId() : DEFAULT_DISPLAY;
|
||||
}
|
||||
|
||||
void setThumbnailVisibility(int visibility) {
|
||||
mSnapshotView.setVisibility(visibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
|
||||
*/
|
||||
|
||||
@@ -21,4 +21,5 @@
|
||||
android:layout_height="match_parent"
|
||||
android:theme="@style/HomeScreenElementTheme"
|
||||
android:importantForAccessibility="no"
|
||||
android:preferKeepClear="true"
|
||||
launcher:containerType="hotseat" />
|
||||
@@ -106,13 +106,13 @@
|
||||
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Funkcja wyłączona przez administratora"</string>
|
||||
<string name="allow_rotation_title" msgid="7222049633713050106">"Zezwalaj na obrót ekranu głównego"</string>
|
||||
<string name="allow_rotation_desc" msgid="8662546029078692509">"Po obróceniu telefonu"</string>
|
||||
<string name="notification_dots_title" msgid="9062440428204120317">"Plakietki z powiadomieniami"</string>
|
||||
<string name="notification_dots_title" msgid="9062440428204120317">"Kropki powiadomień"</string>
|
||||
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Włączono"</string>
|
||||
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Wyłączono"</string>
|
||||
<string name="title_missing_notification_access" msgid="7503287056163941064">"Wymagany jest dostęp do powiadomień"</string>
|
||||
<string name="msg_missing_notification_access" msgid="281113995110910548">"Aby pokazać plakietki z powiadomieniami, włącz powiadomienia aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
|
||||
<string name="msg_missing_notification_access" msgid="281113995110910548">"Aby pokazywać kropki powiadomień, włącz powiadomienia aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
|
||||
<string name="title_change_settings" msgid="1376365968844349552">"Zmień ustawienia"</string>
|
||||
<string name="notification_dots_service_title" msgid="4284221181793592871">"Pokaż plakietki z powiadomieniami"</string>
|
||||
<string name="notification_dots_service_title" msgid="4284221181793592871">"Pokaż kropki powiadomień"</string>
|
||||
<string name="developer_options_title" msgid="700788437593726194">"Opcje programisty"</string>
|
||||
<string name="auto_add_shortcuts_label" msgid="4926805029653694105">"Dodawaj ikony aplikacji do ekranu głównego"</string>
|
||||
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"W przypadku nowych aplikacji"</string>
|
||||
|
||||
@@ -265,7 +265,8 @@ public abstract class LauncherState implements BaseState<LauncherState> {
|
||||
*
|
||||
* 0 means completely zoomed in, without blurs. 1 is zoomed out, with blurs.
|
||||
*/
|
||||
public final float getDepth(Context context) {
|
||||
public final <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
|
||||
float getDepth(DEVICE_PROFILE_CONTEXT context) {
|
||||
return getDepth(context,
|
||||
BaseDraggingActivity.fromContext(context).getDeviceProfile().isMultiWindowMode);
|
||||
}
|
||||
@@ -275,14 +276,16 @@ public abstract class LauncherState implements BaseState<LauncherState> {
|
||||
*
|
||||
* @see #getDepth(Context).
|
||||
*/
|
||||
public final float getDepth(Context context, boolean isMultiWindowMode) {
|
||||
public final <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
|
||||
float getDepth(DEVICE_PROFILE_CONTEXT context, boolean isMultiWindowMode) {
|
||||
if (isMultiWindowMode) {
|
||||
return 0;
|
||||
}
|
||||
return getDepthUnchecked(context);
|
||||
}
|
||||
|
||||
protected float getDepthUnchecked(Context context) {
|
||||
protected <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfile.DeviceProfileListenable>
|
||||
float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
|
||||
return 0f;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,10 @@ public class Interpolators {
|
||||
public static final Interpolator DECELERATED_EASE = new PathInterpolator(0, 0, .2f, 1f);
|
||||
public static final Interpolator ACCELERATED_EASE = new PathInterpolator(0.4f, 0, 1f, 1f);
|
||||
|
||||
/**
|
||||
* The default emphasized interpolator. Used for hero / emphasized movement of content.
|
||||
*/
|
||||
public static final Interpolator EMPHASIZED = createEmphasizedInterpolator();
|
||||
public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator(
|
||||
0.3f, 0f, 0.8f, 0.15f);
|
||||
public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator(
|
||||
@@ -87,7 +91,6 @@ public class Interpolators {
|
||||
public static final Interpolator TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL =
|
||||
v -> ACCEL_DEACCEL.getInterpolation(TOUCH_RESPONSE_INTERPOLATOR.getInterpolation(v));
|
||||
|
||||
|
||||
/**
|
||||
* Inversion of ZOOM_OUT, compounded with an ease-out.
|
||||
*/
|
||||
@@ -218,4 +221,14 @@ public class Interpolators {
|
||||
public static Interpolator reverse(Interpolator interpolator) {
|
||||
return t -> 1 - interpolator.getInterpolation(1 - t);
|
||||
}
|
||||
|
||||
// Create the default emphasized interpolator
|
||||
private static PathInterpolator createEmphasizedInterpolator() {
|
||||
Path path = new Path();
|
||||
// Doing the same as fast_out_extra_slow_in
|
||||
path.moveTo(0f, 0f);
|
||||
path.cubicTo(0.05f, 0f, 0.133333f, 0.06f, 0.166666f, 0.4f);
|
||||
path.cubicTo(0.208333f, 0.82f, 0.25f, 1f, 1f, 1f);
|
||||
return new PathInterpolator(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,6 +342,11 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
public void onAnimationSuccess(Animator animator) {
|
||||
onStateTransitionEnd(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
onStateTransitionFailed(state);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -354,6 +359,12 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
}
|
||||
}
|
||||
|
||||
private void onStateTransitionFailed(STATE_TYPE state) {
|
||||
for (int i = mListeners.size() - 1; i >= 0; i--) {
|
||||
mListeners.get(i).onStateTransitionFailed(state);
|
||||
}
|
||||
}
|
||||
|
||||
private void onStateTransitionEnd(STATE_TYPE state) {
|
||||
// Only change the stable states after the transitions have finished
|
||||
if (state != mCurrentStableState) {
|
||||
@@ -588,6 +599,11 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
|
||||
|
||||
default void onStateTransitionStart(STATE_TYPE toState) { }
|
||||
|
||||
/**
|
||||
* If the state transition animation fails (e.g. is canceled by the user), this fires.
|
||||
*/
|
||||
default void onStateTransitionFailed(STATE_TYPE toState) { }
|
||||
|
||||
default void onStateTransitionComplete(STATE_TYPE finalState) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.launcher3.touch;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
|
||||
import static com.android.launcher3.anim.Interpolators.EMPHASIZED;
|
||||
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_ACCELERATE;
|
||||
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
@@ -199,8 +200,10 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
Interpolators.reverse(ALL_APPS_SCRIM_RESPONDER));
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME);
|
||||
if (!config.userControlled) {
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_ACCELERATE);
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED);
|
||||
}
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, EMPHASIZED);
|
||||
config.setInterpolator(ANIM_DEPTH, EMPHASIZED);
|
||||
} else {
|
||||
if (config.userControlled) {
|
||||
config.setInterpolator(ANIM_DEPTH, Interpolators.reverse(BLUR_MANUAL));
|
||||
@@ -238,8 +241,10 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
|
||||
config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
|
||||
if (!config.userControlled) {
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_DECELERATE);
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED);
|
||||
}
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, EMPHASIZED);
|
||||
config.setInterpolator(ANIM_DEPTH, EMPHASIZED);
|
||||
} else {
|
||||
config.setInterpolator(ANIM_DEPTH, config.userControlled ? BLUR_MANUAL : BLUR_ATOMIC);
|
||||
config.setInterpolator(ANIM_WORKSPACE_FADE,
|
||||
|
||||
@@ -43,13 +43,14 @@ public class OnboardingPrefs<T extends ActivityContext> {
|
||||
public static final String SEARCH_ONBOARDING_COUNT = "launcher.search_onboarding_count";
|
||||
public static final String TASKBAR_EDU_SEEN = "launcher.taskbar_edu_seen";
|
||||
public static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
|
||||
public static final String QSB_SEARCH_ONBOARDING_CARD_DISMISSED = "launcher.qsb_edu_dismiss";
|
||||
// When adding a new key, add it here as well, to be able to reset it from Developer Options.
|
||||
public static final Map<String, String[]> ALL_PREF_KEYS = Map.of(
|
||||
"All Apps Bounce", new String[] { HOME_BOUNCE_SEEN, HOME_BOUNCE_COUNT },
|
||||
"Hybrid Hotseat Education", new String[] { HOTSEAT_DISCOVERY_TIP_COUNT,
|
||||
HOTSEAT_LONGPRESS_TIP_SEEN },
|
||||
"Search Education", new String[] { SEARCH_KEYBOARD_EDU_SEEN, SEARCH_SNACKBAR_COUNT,
|
||||
SEARCH_ONBOARDING_COUNT},
|
||||
SEARCH_ONBOARDING_COUNT, QSB_SEARCH_ONBOARDING_CARD_DISMISSED},
|
||||
"Taskbar Education", new String[] { TASKBAR_EDU_SEEN },
|
||||
"All Apps Visited Count", new String[] {ALL_APPS_VISITED_COUNT}
|
||||
);
|
||||
@@ -61,7 +62,8 @@ public class OnboardingPrefs<T extends ActivityContext> {
|
||||
HOME_BOUNCE_SEEN,
|
||||
HOTSEAT_LONGPRESS_TIP_SEEN,
|
||||
SEARCH_KEYBOARD_EDU_SEEN,
|
||||
TASKBAR_EDU_SEEN
|
||||
TASKBAR_EDU_SEEN,
|
||||
QSB_SEARCH_ONBOARDING_CARD_DISMISSED
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface EventBoolKey {}
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.android.launcher3.util.Themes;
|
||||
public class AllAppsState extends LauncherState {
|
||||
|
||||
private static final float PARALLAX_COEFFICIENT = .125f;
|
||||
private static final float WORKSPACE_SCALE_FACTOR = 0.97f;
|
||||
|
||||
private static final int STATE_FLAGS = FLAG_WORKSPACE_INACCESSIBLE;
|
||||
|
||||
@@ -60,7 +59,8 @@ public class AllAppsState extends LauncherState {
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
|
||||
return new ScaleAndTranslation(WORKSPACE_SCALE_FACTOR, NO_OFFSET, NO_OFFSET);
|
||||
return new ScaleAndTranslation(launcher.getDeviceProfile().workspaceContentScale, NO_OFFSET,
|
||||
NO_OFFSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,7 +71,7 @@ public class AllAppsState extends LauncherState {
|
||||
ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
|
||||
.getWorkspaceScaleAndTranslation(launcher);
|
||||
return new ScaleAndTranslation(
|
||||
WORKSPACE_SCALE_FACTOR,
|
||||
launcher.getDeviceProfile().workspaceContentScale,
|
||||
overviewScaleAndTranslation.translationX,
|
||||
overviewScaleAndTranslation.translationY);
|
||||
}
|
||||
|
||||
@@ -30,39 +30,117 @@ import java.util.Set;
|
||||
|
||||
public class CellLayoutBoard {
|
||||
|
||||
public static class CellType {
|
||||
// The cells marked by this will be filled by 1x1 widgets and will be ignored when
|
||||
// validating
|
||||
public static final char IGNORE = 'x';
|
||||
// The cells marked by this will be filled by app icons
|
||||
public static final char ICON = 'i';
|
||||
// Empty space
|
||||
public static final char EMPTY = '-';
|
||||
// Widget that will be saved as "main widget" for easier retrieval
|
||||
public static final char MAIN_WIDGET = 'm';
|
||||
// Everything else will be consider a widget
|
||||
}
|
||||
|
||||
public static class WidgetRect {
|
||||
public char mType;
|
||||
public Rect mBounds;
|
||||
|
||||
WidgetRect(char type, Rect bounds) {
|
||||
this.mType = type;
|
||||
this.mBounds = bounds;
|
||||
}
|
||||
|
||||
int getSpanX() {
|
||||
return mBounds.right - mBounds.left + 1;
|
||||
}
|
||||
|
||||
int getSpanY() {
|
||||
return mBounds.top - mBounds.bottom + 1;
|
||||
}
|
||||
|
||||
int getCellX() {
|
||||
return mBounds.left;
|
||||
}
|
||||
|
||||
int getCellY() {
|
||||
return mBounds.bottom;
|
||||
}
|
||||
|
||||
boolean shouldIgnore() {
|
||||
return this.mType == CellType.IGNORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WidgetRect type = " + mType + " bounds = " + mBounds.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class IconPoint {
|
||||
public Point coord;
|
||||
public char mType;
|
||||
|
||||
public IconPoint(Point coord, char type) {
|
||||
this.coord = coord;
|
||||
mType = type;
|
||||
}
|
||||
|
||||
public char getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public void setType(char type) {
|
||||
mType = type;
|
||||
}
|
||||
|
||||
public Point getCoord() {
|
||||
return coord;
|
||||
}
|
||||
|
||||
public void setCoord(Point coord) {
|
||||
this.coord = coord;
|
||||
}
|
||||
}
|
||||
|
||||
static final int INFINITE = 99999;
|
||||
|
||||
char[][] mBoard = new char[30][30];
|
||||
char[][] mWidget = new char[30][30];
|
||||
|
||||
List<TestBoardWidget> mWidgetsRects = new ArrayList<>();
|
||||
Map<Character, TestBoardWidget> mWidgetsMap = new HashMap<>();
|
||||
List<WidgetRect> mWidgetsRects = new ArrayList<>();
|
||||
Map<Character, WidgetRect> mWidgetsMap = new HashMap<>();
|
||||
|
||||
List<TestBoardAppIcon> mIconPoints = new ArrayList<>();
|
||||
Map<Character, TestBoardAppIcon> mIconsMap = new HashMap<>();
|
||||
List<IconPoint> mIconPoints = new ArrayList<>();
|
||||
Map<Character, IconPoint> mIconsMap = new HashMap<>();
|
||||
|
||||
Point mMain = new Point();
|
||||
|
||||
CellLayoutBoard() {
|
||||
for (int x = 0; x < mBoard.length; x++) {
|
||||
for (int y = 0; y < mBoard[0].length; y++) {
|
||||
mBoard[x][y] = '-';
|
||||
for (int x = 0; x < mWidget.length; x++) {
|
||||
for (int y = 0; y < mWidget[0].length; y++) {
|
||||
mWidget[x][y] = CellType.EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<TestBoardWidget> getWidgets() {
|
||||
public List<WidgetRect> getWidgets() {
|
||||
return mWidgetsRects;
|
||||
}
|
||||
|
||||
public List<IconPoint> getIcons() {
|
||||
return mIconPoints;
|
||||
}
|
||||
|
||||
public Point getMain() {
|
||||
return mMain;
|
||||
}
|
||||
|
||||
public TestBoardWidget getWidgetRect(char c) {
|
||||
public WidgetRect getWidgetRect(char c) {
|
||||
return mWidgetsMap.get(c);
|
||||
}
|
||||
|
||||
public static TestBoardWidget getWidgetRect(int x, int y, Set<Point> used, char[][] board) {
|
||||
public static WidgetRect getWidgetRect(int x, int y, Set<Point> used, char[][] board) {
|
||||
char type = board[x][y];
|
||||
Queue<Point> search = new ArrayDeque<Point>();
|
||||
Point current = new Point(x, y);
|
||||
@@ -91,20 +169,20 @@ public class CellLayoutBoard {
|
||||
}
|
||||
}
|
||||
}
|
||||
return new TestBoardWidget(type, widgetRect);
|
||||
return new WidgetRect(type, widgetRect);
|
||||
}
|
||||
|
||||
public static boolean isWidget(char type) {
|
||||
return type != 'i' && type != '-';
|
||||
return type != CellType.ICON && type != CellType.EMPTY;
|
||||
}
|
||||
|
||||
public static boolean isIcon(char type) {
|
||||
return type == 'i';
|
||||
return type == CellType.ICON;
|
||||
}
|
||||
|
||||
private static List<TestBoardWidget> getRects(char[][] board) {
|
||||
private static List<WidgetRect> getRects(char[][] board) {
|
||||
Set<Point> used = new HashSet<>();
|
||||
List<TestBoardWidget> widgetsRects = new ArrayList<>();
|
||||
List<WidgetRect> widgetsRects = new ArrayList<>();
|
||||
for (int x = 0; x < board.length; x++) {
|
||||
for (int y = 0; y < board[0].length; y++) {
|
||||
if (!used.contains(new Point(x, y)) && isWidget(board[x][y])) {
|
||||
@@ -115,12 +193,12 @@ public class CellLayoutBoard {
|
||||
return widgetsRects;
|
||||
}
|
||||
|
||||
private static List<TestBoardAppIcon> getIconPoints(char[][] board) {
|
||||
List<TestBoardAppIcon> iconPoints = new ArrayList<>();
|
||||
private static List<IconPoint> getIconPoints(char[][] board) {
|
||||
List<IconPoint> iconPoints = new ArrayList<>();
|
||||
for (int x = 0; x < board.length; x++) {
|
||||
for (int y = 0; y < board[0].length; y++) {
|
||||
if (isIcon(board[x][y])) {
|
||||
iconPoints.add(new TestBoardAppIcon(new Point(x, y), board[x][y]));
|
||||
iconPoints.add(new IconPoint(new Point(x, y), board[x][y]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,18 +213,18 @@ public class CellLayoutBoard {
|
||||
String line = lines[y];
|
||||
for (int x = 0; x < line.length(); x++) {
|
||||
char c = line.charAt(x);
|
||||
if (c == 'm') {
|
||||
if (c == CellType.MAIN_WIDGET) {
|
||||
board.mMain = new Point(x, y);
|
||||
}
|
||||
if (c != '-') {
|
||||
board.mBoard[x][y] = line.charAt(x);
|
||||
if (c != CellType.EMPTY) {
|
||||
board.mWidget[x][y] = line.charAt(x);
|
||||
}
|
||||
}
|
||||
}
|
||||
board.mWidgetsRects = getRects(board.mBoard);
|
||||
board.mWidgetsRects = getRects(board.mWidget);
|
||||
board.mWidgetsRects.forEach(
|
||||
widgetRect -> board.mWidgetsMap.put(widgetRect.mType, widgetRect));
|
||||
board.mIconPoints = getIconPoints(board.mBoard);
|
||||
board.mIconPoints = getIconPoints(board.mWidget);
|
||||
return board;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,13 @@
|
||||
*/
|
||||
package com.android.launcher3.celllayout;
|
||||
|
||||
import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
@@ -34,13 +31,14 @@ import com.android.launcher3.celllayout.testcases.MoveOutReorderCase;
|
||||
import com.android.launcher3.celllayout.testcases.PushReorderCase;
|
||||
import com.android.launcher3.celllayout.testcases.ReorderTestCase;
|
||||
import com.android.launcher3.celllayout.testcases.SimpleReorderCase;
|
||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.tapl.Widget;
|
||||
import com.android.launcher3.tapl.WidgetResizeFrame;
|
||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||
import com.android.launcher3.ui.TaplTestsLauncher3;
|
||||
import com.android.launcher3.ui.TestViewHelpers;
|
||||
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
|
||||
import com.android.launcher3.util.rule.ShellCommandRule;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
|
||||
import com.android.launcher3.views.DoubleShadowBubbleTextView;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetHostView;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
@@ -60,6 +58,8 @@ public class ReorderWidgets extends AbstractLauncherUiTest {
|
||||
|
||||
private static final String TAG = ReorderWidgets.class.getSimpleName();
|
||||
|
||||
TestWorkspaceBuilder mBoardBuilder;
|
||||
|
||||
private View getViewAt(int cellX, int cellY) {
|
||||
return getFromLauncher(l -> l.getWorkspace().getScreenWithId(
|
||||
l.getWorkspace().getScreenIdForPageIndex(0)).getChildAt(cellX, cellY));
|
||||
@@ -76,6 +76,7 @@ public class ReorderWidgets extends AbstractLauncherUiTest {
|
||||
|
||||
@Before
|
||||
public void setup() throws Throwable {
|
||||
mBoardBuilder = new TestWorkspaceBuilder(this);
|
||||
TaplTestsLauncher3.initialize(this);
|
||||
clearHomescreen();
|
||||
}
|
||||
@@ -86,78 +87,44 @@ public class ReorderWidgets extends AbstractLauncherUiTest {
|
||||
private boolean validateBoard(CellLayoutBoard board) {
|
||||
boolean match = true;
|
||||
Point cellDimensions = getCellDimensions();
|
||||
for (TestBoardWidget widgetRect: board.getWidgets()) {
|
||||
for (CellLayoutBoard.WidgetRect widgetRect: board.getWidgets()) {
|
||||
if (widgetRect.shouldIgnore()) {
|
||||
continue;
|
||||
}
|
||||
View widget = getViewAt(widgetRect.getCellX(), widgetRect.getCellY());
|
||||
assertTrue("The view selected at " + board + " is not a widget",
|
||||
widget instanceof LauncherAppWidgetHostView);
|
||||
match &= widgetRect.getSpanX()
|
||||
== Math.round(widget.getWidth() / (float) cellDimensions.x);
|
||||
match &= widgetRect.getSpanY()
|
||||
== Math.round(widget.getHeight() / (float) cellDimensions.y);
|
||||
if (!match) return match;
|
||||
}
|
||||
for (CellLayoutBoard.IconPoint iconPoint : board.getIcons()) {
|
||||
View icon = getViewAt(iconPoint.getCoord().x, iconPoint.getCoord().y);
|
||||
assertTrue("The view selected at " + iconPoint.coord + " is not an Icon",
|
||||
icon instanceof DoubleShadowBubbleTextView);
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases.
|
||||
*/
|
||||
private void fillWithWidgets(TestBoardWidget widgetRect) {
|
||||
int initX = widgetRect.getCellX();
|
||||
int initY = widgetRect.getCellY();
|
||||
for (int x = 0; x < widgetRect.getSpanX(); x++) {
|
||||
for (int y = 0; y < widgetRect.getSpanY(); y++) {
|
||||
int auxX = initX + x;
|
||||
int auxY = initY + y;
|
||||
try {
|
||||
// this widgets are filling, we don't care if we can't place them
|
||||
addWidgetInCell(
|
||||
new TestBoardWidget('x',
|
||||
new Rect(auxX, auxY, auxX, auxY))
|
||||
);
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Unable to place filling widget at " + auxX + "," + auxY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addWidgetInCell(TestBoardWidget widgetRect) {
|
||||
LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false);
|
||||
LauncherAppWidgetInfo item = createWidgetInfo(info,
|
||||
ApplicationProvider.getApplicationContext(), true);
|
||||
item.cellX = widgetRect.getCellX();
|
||||
item.cellY = widgetRect.getCellY();
|
||||
|
||||
item.spanX = widgetRect.getSpanX();
|
||||
item.spanY = widgetRect.getSpanY();
|
||||
addItemToScreen(item);
|
||||
}
|
||||
|
||||
private void addCorrespondingWidgetRect(TestBoardWidget widgetRect) {
|
||||
if (widgetRect.mType == 'x') {
|
||||
fillWithWidgets(widgetRect);
|
||||
} else {
|
||||
addWidgetInCell(widgetRect);
|
||||
}
|
||||
}
|
||||
|
||||
private void runTestCase(ReorderTestCase testCase) {
|
||||
Point mainWidgetCellPos = testCase.mStart.getMain();
|
||||
|
||||
testCase.mStart.getWidgets().forEach(this::addCorrespondingWidgetRect);
|
||||
mBoardBuilder.buildBoard(testCase.mStart);
|
||||
|
||||
mLauncher.getWorkspace()
|
||||
.getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y)
|
||||
.dragWidgetToWorkspace(testCase.moveMainTo.x, testCase.moveMainTo.y)
|
||||
.dismiss(); // dismiss resize frame
|
||||
Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x,
|
||||
mainWidgetCellPos.y);
|
||||
assertNotNull(widget);
|
||||
WidgetResizeFrame resizeFrame = widget.dragWidgetToWorkspace(testCase.moveMainTo.x,
|
||||
testCase.moveMainTo.y);
|
||||
resizeFrame.dismiss();
|
||||
|
||||
boolean isValid = false;
|
||||
for (CellLayoutBoard board : testCase.mEnd) {
|
||||
isValid |= validateBoard(board);
|
||||
}
|
||||
assertTrue("None of the valid boards match with the current state", isValid);
|
||||
assertTrue("Non of the valid boards match with the current state", isValid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.celllayout;
|
||||
|
||||
import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.ui.AbstractLauncherUiTest;
|
||||
import com.android.launcher3.ui.TestViewHelpers;
|
||||
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
|
||||
|
||||
public class TestWorkspaceBuilder {
|
||||
|
||||
private static final ComponentName APP_COMPONENT_NAME = new ComponentName(
|
||||
"com.google.android.calculator", "com.android.calculator2.Calculator");
|
||||
|
||||
public AbstractLauncherUiTest mTest;
|
||||
|
||||
private UserHandle mMyUser;
|
||||
|
||||
public TestWorkspaceBuilder(AbstractLauncherUiTest test) {
|
||||
mTest = test;
|
||||
mMyUser = Process.myUserHandle();
|
||||
}
|
||||
|
||||
private static final String TAG = "CellLayoutBoardBuilder";
|
||||
|
||||
/**
|
||||
* Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases.
|
||||
*/
|
||||
private void fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect) {
|
||||
int initX = widgetRect.getCellX();
|
||||
int initY = widgetRect.getCellY();
|
||||
for (int x = initX; x < initX + widgetRect.getSpanX(); x++) {
|
||||
for (int y = initY; y < initY + widgetRect.getSpanY(); y++) {
|
||||
try {
|
||||
// this widgets are filling, we don't care if we can't place them
|
||||
addWidgetInCell(
|
||||
new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE,
|
||||
new Rect(x, y, x, y))
|
||||
);
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Unable to place filling widget at " + x + "," + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) {
|
||||
LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false);
|
||||
LauncherAppWidgetInfo item = createWidgetInfo(info,
|
||||
ApplicationProvider.getApplicationContext(), true);
|
||||
|
||||
item.cellX = widgetRect.getCellX();
|
||||
item.cellY = widgetRect.getCellY();
|
||||
item.spanX = widgetRect.getSpanX();
|
||||
item.spanY = widgetRect.getSpanY();
|
||||
mTest.addItemToScreen(item);
|
||||
}
|
||||
|
||||
private void addIconInCell(CellLayoutBoard.IconPoint iconPoint) {
|
||||
AppInfo appInfo = new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser,
|
||||
AppInfo.makeLaunchIntent(APP_COMPONENT_NAME));
|
||||
|
||||
appInfo.cellX = iconPoint.getCoord().x;
|
||||
appInfo.cellY = iconPoint.getCoord().y;
|
||||
appInfo.minSpanY = appInfo.minSpanX = appInfo.spanX = appInfo.spanY = 1;
|
||||
appInfo.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
|
||||
appInfo.componentName = APP_COMPONENT_NAME;
|
||||
|
||||
mTest.addItemToScreen(new WorkspaceItemInfo(appInfo));
|
||||
}
|
||||
|
||||
private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect) {
|
||||
if (widgetRect.mType == 'x') {
|
||||
fillWithWidgets(widgetRect);
|
||||
} else {
|
||||
addWidgetInCell(widgetRect);
|
||||
}
|
||||
}
|
||||
|
||||
public void buildBoard(CellLayoutBoard board) {
|
||||
board.getWidgets().forEach(this::addCorrespondingWidgetRect);
|
||||
board.getIcons().forEach(this::addIconInCell);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,10 @@ import android.graphics.Point;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
|
||||
* in the board mean refer to {@code CellType}
|
||||
*/
|
||||
public class FullReorderCase {
|
||||
|
||||
/** 5x5 Test
|
||||
|
||||
@@ -19,6 +19,10 @@ import android.graphics.Point;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
|
||||
* in the board mean refer to {@code CellType}
|
||||
*/
|
||||
public class MoveOutReorderCase {
|
||||
|
||||
/** 5x5 Test
|
||||
|
||||
@@ -19,6 +19,10 @@ import android.graphics.Point;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
|
||||
* in the board mean refer to {@code CellType}
|
||||
*/
|
||||
public class PushReorderCase {
|
||||
|
||||
/** 5x5 Test
|
||||
|
||||
@@ -19,6 +19,10 @@ import android.graphics.Point;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
|
||||
* in the board mean refer to {@code CellType}
|
||||
*/
|
||||
public class SimpleReorderCase {
|
||||
|
||||
/** 5x5 Test
|
||||
|
||||
@@ -319,7 +319,7 @@ public abstract class AbstractLauncherUiTest {
|
||||
/**
|
||||
* Adds {@param item} on the homescreen on the 0th screen
|
||||
*/
|
||||
protected void addItemToScreen(ItemInfo item) {
|
||||
public void addItemToScreen(ItemInfo item) {
|
||||
WidgetUtils.addItemToScreen(item, mTargetContext);
|
||||
resetLoaderState();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user