Snap for 9744603 from 0529dbe41f to udc-release

Change-Id: I622fb534fd7ef6edff5519fceff674cc221e8dda
This commit is contained in:
Android Build Coastguard Worker
2023-03-15 01:31:42 +00:00
11 changed files with 254 additions and 16 deletions
@@ -52,6 +52,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAU
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.util.DisplayController.isTransientTaskbar;
import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
@@ -123,7 +124,6 @@ import com.android.launcher3.testing.shared.ResourceUtils;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.util.RunnableList;
@@ -449,7 +449,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
if (mDeviceProfile.isTaskbarPresentInApps
&& !target.willShowImeOnTarget
&& !DisplayController.isTransientTaskbar(mLauncher)) {
&& !isTransientTaskbar(mLauncher)) {
// Animate to above the taskbar.
bounds.bottom -= target.contentInsets.bottom;
}
@@ -636,7 +636,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
RectF launcherIconBounds = new RectF();
FloatingIconView floatingView = getFloatingIconView(mLauncher, v,
mLauncher.getTaskbarUIController() == null
(mLauncher.getTaskbarUIController() == null || !isTransientTaskbar(mLauncher))
? null
: mLauncher.getTaskbarUIController().findMatchingView(v),
!appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */);
@@ -317,7 +317,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
return mTransientTaskbarBounds;
}
@VisibleForTesting
@Override
public StatsLogManager getStatsLogManager() {
// Used to mock, can't mock a default interface method directly
@@ -25,6 +25,8 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.FORCE_PERSISTENT_TASKBAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_SHOW;
import static com.android.launcher3.taskbar.Utilities.appendFlag;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
@@ -972,6 +974,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_LONGPRESS_SHOW);
}
}
if (hasAnyFlag(changedFlags, FLAG_STASHED_IN_APP_AUTO)) {
mActivity.getStatsLogManager().logger().log(hasAnyFlag(FLAG_STASHED_IN_APP_AUTO)
? LAUNCHER_TRANSIENT_TASKBAR_HIDE
: LAUNCHER_TRANSIENT_TASKBAR_SHOW);
}
}
private void notifyStashChange(boolean visible, boolean stashed) {
@@ -23,10 +23,14 @@ import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
import android.window.BackEvent;
import android.window.OnBackAnimationCallback;
import android.window.OnBackInvokedDispatcher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsViewController.TaskbarAllAppsCallbacks;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
import com.android.launcher3.views.AbstractSlideInView;
@@ -53,6 +57,28 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarOverla
mAllAppsCallbacks = callbacks;
}
private final OnBackAnimationCallback mOnBackAnimationCallback = new OnBackAnimationCallback() {
@Override
public void onBackCancelled() {
TaskbarAllAppsSlideInView.this.onBackCancelled();
}
@Override
public void onBackInvoked() {
TaskbarAllAppsSlideInView.this.onBackInvoked();
}
@Override
public void onBackProgressed(BackEvent backEvent) {
TaskbarAllAppsSlideInView.this.onBackProgressed(backEvent.getProgress());
}
@Override
public void onBackStarted(BackEvent backEvent) {
TaskbarAllAppsSlideInView.this.onBackStarted();
}
};
/** Opens the all apps view. */
void show(boolean animate) {
if (mIsOpen || mOpenCloseAnimator.isRunning()) {
@@ -69,6 +95,11 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarOverla
} else {
mTranslationShift = TRANSLATION_SHIFT_OPENED;
}
if (FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()) {
findOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT, mOnBackAnimationCallback);
}
}
/** The apps container inside this view. */
@@ -79,6 +110,9 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarOverla
@Override
protected void handleClose(boolean animate) {
handleClose(animate, mAllAppsCallbacks.getCloseDuration());
if (FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()) {
findOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mOnBackAnimationCallback);
}
}
@Override
@@ -32,6 +32,7 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
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.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -103,7 +104,10 @@ public class QuickstepAtomicAnimationFactory extends
}
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, 0, 0.25f));
config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress(LINEAR, 0.33f, 1));
config.setInterpolator(ANIM_SCRIM_FADE,
fromState == OVERVIEW_SPLIT_SELECT
? clampToProgress(LINEAR, 0.33f, 1)
: LINEAR);
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
@@ -112,7 +116,10 @@ public class QuickstepAtomicAnimationFactory extends
// Overview is going offscreen, so keep it at its current scale and opacity.
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, EMPHASIZED_DECELERATE);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X,
fromState == OVERVIEW_SPLIT_SELECT
? EMPHASIZED_DECELERATE
: clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f));
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
// Scroll RecentsView to page 0 as it goes offscreen, if necessary.
@@ -3166,6 +3166,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
InteractionJankMonitorWrapper.cancel(
InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
}
updateCurrentTaskActionsVisibility();
});
}
@@ -4666,6 +4668,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mSecondSplitHiddenView = null;
}
// We are leaving split selection state, so it is safe to reset thumbnail translations for
// the next time split is invoked.
setTaskViewsPrimarySplitTranslation(0);
setTaskViewsSecondarySplitTranslation(0);
if (mSplitHiddenTaskViewIndex == -1) {
return;
}
@@ -4680,11 +4687,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
// We are leaving split selection state, so it is safe to reset thumbnail translations for
// the next time split is invoked.
setTaskViewsPrimarySplitTranslation(0);
setTaskViewsSecondarySplitTranslation(0);
resetTaskVisuals();
mSplitHiddenTaskViewIndex = -1;
if (mSplitHiddenTaskView != null) {
@@ -44,12 +44,14 @@ import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.function.Predicate;
@@ -93,7 +95,11 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP
StatsLogManager statsLogManager) {
mUserManager = userManager;
mAllApps = allApps;
mMatcher = mAllApps.mPersonalMatcher.negate();
if (FeatureFlags.ENABLE_APP_CLONING_CHANGES_IN_LAUNCHER.get()) {
mMatcher = ofWorkProfileUser(userManager);
} else {
mMatcher = mAllApps.mPersonalMatcher.negate();
}
mStatsLogManager = statsLogManager;
}
@@ -260,4 +266,27 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP
}
};
}
/**
* Filter to only display apps in managed profile in work tab.
*/
private Predicate<ItemInfo> ofWorkProfileUser(UserManager um) {
return info -> info != null && isManagedProfile(um, info.user.hashCode());
}
private static boolean isManagedProfile(UserManager um, int userId) {
try {
// isManagedProfile is a @SystemApi.
String methodName = "isManagedProfile";
Method method = um.getClass().getDeclaredMethod(methodName, int.class);
Object result = method.invoke(um, userId);
if (result instanceof Boolean) {
return (boolean) result;
}
} catch (Exception e) {
Log.e(TAG, "Failed to call #isManagedProfile via reflection from Launcher");
}
return false;
}
}
@@ -385,6 +385,11 @@ public final class FeatureFlags {
"Enables taskbar pinning to allow user to switch between transient and persistent "
+ "taskbar flavors");
public static final BooleanFlag ENABLE_WORKSPACE_LOADING_OPTIMIZATION = getDebugFlag(251502424,
"ENABLE_WORKSPACE_LOADING_OPTIMIZATION", false, "load the current workspace screen "
+ "visible to the user before the rest rather than loading all of them at once."
);
public static final BooleanFlag ENABLE_GRID_ONLY_OVERVIEW = getDebugFlag(270397206,
"ENABLE_GRID_ONLY_OVERVIEW", false,
"Enable a grid-only overview without a focused task.");
@@ -398,6 +403,10 @@ public final class FeatureFlags {
"ENABLE_KEYBOARD_QUICK_SWITCH", true,
"Enables keyboard quick switching");
public static final BooleanFlag ENABLE_APP_CLONING_CHANGES_IN_LAUNCHER = getDebugFlag(266177840,
"ENABLE_APP_CLONING_CHANGES_IN_LAUNCHER", false,
"Removes clone apps from the work profile tab.");
public static class BooleanFlag {
private final boolean mCurrentValue;
@@ -636,6 +636,12 @@ public class StatsLogManager implements ResourceBasedOverride {
@UiEvent(doc = "User scrolled up on the search result page.")
LAUNCHER_ALLAPPS_SEARCH_SCROLLED_UP(1286),
@UiEvent(doc = "User or automatic timeout has hidden transient taskbar.")
LAUNCHER_TRANSIENT_TASKBAR_HIDE(1330),
@UiEvent(doc = "User has swiped upwards from the gesture handle to show transient taskbar.")
LAUNCHER_TRANSIENT_TASKBAR_SHOW(1331),
;
// ADD MORE
@@ -27,6 +27,7 @@ import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -42,8 +43,10 @@ import com.android.launcher3.util.RunnableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -77,6 +80,36 @@ public abstract class BaseLauncherBinder {
* Binds all loaded data to actual views on the main thread.
*/
public void bindWorkspace(boolean incrementBindId) {
if (FeatureFlags.ENABLE_WORKSPACE_LOADING_OPTIMIZATION.get()) {
DisjointWorkspaceBinder workspaceBinder =
initWorkspaceBinder(incrementBindId, mBgDataModel.collectWorkspaceScreens());
workspaceBinder.bindCurrentWorkspacePages();
workspaceBinder.bindOtherWorkspacePages();
} else {
bindWorkspaceAllAtOnce(incrementBindId);
}
}
/**
* Initializes the WorkspaceBinder for binding.
*
* @param incrementBindId this is used to stop previously started binding tasks that are
* obsolete but still queued.
* @param workspacePages this allows the Launcher to add the correct workspace screens.
*/
public DisjointWorkspaceBinder initWorkspaceBinder(boolean incrementBindId,
IntArray workspacePages) {
synchronized (mBgDataModel) {
if (incrementBindId) {
mBgDataModel.lastBindId++;
}
mMyBindingId = mBgDataModel.lastBindId;
return new DisjointWorkspaceBinder(workspacePages);
}
}
private void bindWorkspaceAllAtOnce(boolean incrementBindId) {
// Save a copy of all the bg-thread collections
ArrayList<ItemInfo> workspaceItems = new ArrayList<>();
ArrayList<LauncherAppWidgetInfo> appWidgets = new ArrayList<>();
@@ -95,7 +128,7 @@ public abstract class BaseLauncherBinder {
}
for (Callbacks cb : mCallbacksList) {
new WorkspaceBinder(cb, mUiExecutor, mApp, mBgDataModel, mMyBindingId,
new UnifiedWorkspaceBinder(cb, mUiExecutor, mApp, mBgDataModel, mMyBindingId,
workspaceItems, appWidgets, extraItems, orderedScreenIds).bind();
}
}
@@ -180,7 +213,7 @@ public abstract class BaseLauncherBinder {
return idleLock;
}
private class WorkspaceBinder {
private class UnifiedWorkspaceBinder {
private final Executor mUiExecutor;
private final Callbacks mCallbacks;
@@ -194,7 +227,7 @@ public abstract class BaseLauncherBinder {
private final IntArray mOrderedScreenIds;
private final ArrayList<FixedContainerItems> mExtraItems;
WorkspaceBinder(Callbacks callbacks,
UnifiedWorkspaceBinder(Callbacks callbacks,
Executor uiExecutor,
LauncherAppState app,
BgDataModel bgDataModel,
@@ -320,4 +353,115 @@ public abstract class BaseLauncherBinder {
});
}
}
private class DisjointWorkspaceBinder {
private final IntArray mOrderedScreenIds;
private final IntSet mCurrentScreenIds = new IntSet();
private final Set<Integer> mBoundItemIds = new HashSet<>();
protected DisjointWorkspaceBinder(IntArray orderedScreenIds) {
mOrderedScreenIds = orderedScreenIds;
for (Callbacks cb : mCallbacksList) {
mCurrentScreenIds.addAll(cb.getPagesToBindSynchronously(orderedScreenIds));
}
if (mCurrentScreenIds.size() == 0) {
mCurrentScreenIds.add(Workspace.FIRST_SCREEN_ID);
}
}
/**
* Binds the currently loaded items in the Data Model. Also signals to the Callbacks[]
* that these items have been bound and their respective screens are ready to be shown.
*
* If this method is called after all the items on the workspace screen have already been
* loaded, it will bind all workspace items immediately, and bindOtherWorkspacePages() will
* not bind any items.
*/
protected void bindCurrentWorkspacePages() {
// Save a copy of all the bg-thread collections
ArrayList<ItemInfo> workspaceItems;
ArrayList<LauncherAppWidgetInfo> appWidgets;
synchronized (mBgDataModel) {
workspaceItems = new ArrayList<>(mBgDataModel.workspaceItems);
appWidgets = new ArrayList<>(mBgDataModel.appWidgets);
}
workspaceItems.forEach(it -> mBoundItemIds.add(it.id));
appWidgets.forEach(it -> mBoundItemIds.add(it.id));
sortWorkspaceItemsSpatially(mApp.getInvariantDeviceProfile(), workspaceItems);
// Tell the workspace that we're about to start binding items
executeCallbacksTask(c -> {
c.clearPendingBinds();
c.startBinding();
}, mUiExecutor);
// Bind workspace screens
executeCallbacksTask(c -> c.bindScreens(mOrderedScreenIds), mUiExecutor);
bindWorkspaceItems(workspaceItems);
bindAppWidgets(appWidgets);
executeCallbacksTask(c -> {
MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
c.onInitialBindComplete(mCurrentScreenIds, new RunnableList());
}, mUiExecutor);
}
protected void bindOtherWorkspacePages() {
// Save a copy of all the bg-thread collections
ArrayList<ItemInfo> workspaceItems;
ArrayList<LauncherAppWidgetInfo> appWidgets;
synchronized (mBgDataModel) {
workspaceItems = new ArrayList<>(mBgDataModel.workspaceItems);
appWidgets = new ArrayList<>(mBgDataModel.appWidgets);
}
workspaceItems.removeIf(it -> mBoundItemIds.contains(it.id));
appWidgets.removeIf(it -> mBoundItemIds.contains(it.id));
sortWorkspaceItemsSpatially(mApp.getInvariantDeviceProfile(), workspaceItems);
bindWorkspaceItems(workspaceItems);
bindAppWidgets(appWidgets);
executeCallbacksTask(c -> c.finishBindingItems(mCurrentScreenIds), mUiExecutor);
mUiExecutor.execute(() -> {
MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
ItemInstallQueue.INSTANCE.get(mApp.getContext())
.resumeModelPush(FLAG_LOADER_RUNNING);
});
for (Callbacks cb : mCallbacksList) {
cb.bindStringCache(mBgDataModel.stringCache.clone());
}
}
private void bindWorkspaceItems(final ArrayList<ItemInfo> workspaceItems) {
// Bind the workspace items
int count = workspaceItems.size();
for (int i = 0; i < count; i += ITEMS_CHUNK) {
final int start = i;
final int chunkSize = (i + ITEMS_CHUNK <= count) ? ITEMS_CHUNK : (count - i);
executeCallbacksTask(
c -> c.bindItems(workspaceItems.subList(start, start + chunkSize), false),
mUiExecutor);
}
}
private void bindAppWidgets(List<LauncherAppWidgetInfo> appWidgets) {
// Bind the widgets, one at a time
int count = appWidgets.size();
for (int i = 0; i < count; i++) {
final ItemInfo widget = appWidgets.get(i);
executeCallbacksTask(
c -> c.bindItems(Collections.singletonList(widget), false),
mUiExecutor);
}
}
}
}
@@ -520,7 +520,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
@Test
@PortraitLandscape
@ScreenRecord // (b/256659409)
public void testUninstallFromAllApps() throws Exception {
installDummyAppAndWaitForUIUpdate();
try {
@@ -529,6 +528,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
allApps.freeze();
try {
workspace = allApps.getAppIcon(DUMMY_APP_NAME).uninstall();
// After the toast clears, then the model tries to commit the uninstall transaction
mLauncher.waitForModelQueueCleared();
} finally {
allApps.unfreeze();
}