Snap for 8287852 from 7db484396a to tm-release
Change-Id: I661f70a4b5eea3cccc6d527380b5dd846bfbfe9d
This commit is contained in:
@@ -31,6 +31,7 @@ android_library {
|
||||
"androidx.test.uiautomator_uiautomator",
|
||||
"androidx.preference_preference",
|
||||
"SystemUISharedLib",
|
||||
"SystemUIAnimationLib",
|
||||
],
|
||||
srcs: [
|
||||
"tests/tapl/**/*.java",
|
||||
@@ -196,6 +197,7 @@ android_library {
|
||||
"lottie",
|
||||
"SystemUISharedLib",
|
||||
"SystemUI-statsd",
|
||||
"SystemUIAnimationLib",
|
||||
],
|
||||
manifest: "quickstep/AndroidManifest.xml",
|
||||
min_sdk_version: "current",
|
||||
@@ -287,6 +289,7 @@ android_library {
|
||||
"SystemUISharedLib",
|
||||
"Launcher3CommonDepsLib",
|
||||
"QuickstepResLib",
|
||||
"SystemUIAnimationLib",
|
||||
],
|
||||
manifest: "quickstep/AndroidManifest.xml",
|
||||
platform_apis: true,
|
||||
|
||||
@@ -39,6 +39,7 @@ peanutbutter@google.com
|
||||
xuqiu@google.com
|
||||
sreyasr@google.com
|
||||
thiruram@google.com
|
||||
brianji@google.com
|
||||
|
||||
per-file FeatureFlags.java, globs = set noparent
|
||||
per-file FeatureFlags.java = sunnygoyal@google.com, winsonc@google.com, zakcohen@google.com, mrcasey@google.com, adamcohen@google.com, hyunyoungs@google.com
|
||||
|
||||
@@ -292,8 +292,8 @@ public abstract class BaseQuickstepLauncher extends Launcher {
|
||||
mActionsView = findViewById(R.id.overview_actions_view);
|
||||
RecentsView overviewPanel = (RecentsView) getOverviewPanel();
|
||||
SplitSelectStateController controller =
|
||||
new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this),
|
||||
getStateManager(), getDepthController());
|
||||
new SplitSelectStateController(this, mHandler, getStateManager(),
|
||||
getDepthController());
|
||||
overviewPanel.init(mActionsView, controller);
|
||||
mActionsView.setDp(getDeviceProfile());
|
||||
mActionsView.updateVerticalMargin(DisplayController.getNavigationMode(this));
|
||||
|
||||
@@ -1301,8 +1301,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
}
|
||||
}
|
||||
|
||||
return mLauncher.getFirstMatchForAppClose(launchCookieItemId,
|
||||
packageName, UserHandle.of(runningTaskTarget.taskInfo.userId));
|
||||
return mLauncher.getFirstMatchForAppClose(launchCookieItemId, packageName,
|
||||
UserHandle.of(runningTaskTarget.taskInfo.userId), true /* supportsAllAppsState */);
|
||||
}
|
||||
|
||||
private @NonNull RectF getDefaultWindowTargetRect() {
|
||||
|
||||
@@ -29,13 +29,16 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.RecentsAnimationCallbacks;
|
||||
import com.android.quickstep.RecentsAnimationController;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
import com.android.systemui.animation.ViewRootSync;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -76,6 +79,9 @@ import java.util.function.Supplier;
|
||||
|
||||
private boolean mShouldDelayLauncherStateAnim;
|
||||
|
||||
// We skip any view synchronizations during init/destroy.
|
||||
private boolean mCanSyncViews;
|
||||
|
||||
private final StateManager.StateListener<LauncherState> mStateListener =
|
||||
new StateManager.StateListener<LauncherState>() {
|
||||
|
||||
@@ -102,6 +108,8 @@ import java.util.function.Supplier;
|
||||
};
|
||||
|
||||
public void init(TaskbarControllers controllers, BaseQuickstepLauncher launcher) {
|
||||
mCanSyncViews = false;
|
||||
|
||||
mControllers = controllers;
|
||||
mLauncher = launcher;
|
||||
|
||||
@@ -121,9 +129,13 @@ import java.util.function.Supplier;
|
||||
updateStateForFlag(FLAG_RESUMED, launcher.hasBeenResumed());
|
||||
mLauncherState = launcher.getStateManager().getState();
|
||||
applyState(0);
|
||||
|
||||
mCanSyncViews = true;
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
mCanSyncViews = false;
|
||||
|
||||
mIconAlignmentForResumedState.finishAnimation();
|
||||
mIconAlignmentForGestureState.finishAnimation();
|
||||
mIconAlignmentForLauncherState.finishAnimation();
|
||||
@@ -131,6 +143,8 @@ import java.util.function.Supplier;
|
||||
mIconAlphaForHome.setConsumer(null);
|
||||
mLauncher.getHotseat().setIconsAlpha(1f);
|
||||
mLauncher.getStateManager().removeStateListener(mStateListener);
|
||||
|
||||
mCanSyncViews = true;
|
||||
}
|
||||
|
||||
public Animator createAnimToLauncher(@NonNull LauncherState toState,
|
||||
@@ -380,6 +394,27 @@ import java.util.function.Supplier;
|
||||
return;
|
||||
}
|
||||
float alignment = alignmentSupplier.get();
|
||||
float currentValue = mIconAlphaForHome.getValue();
|
||||
boolean taskbarWillBeVisible = alignment < 1;
|
||||
boolean firstFrameVisChanged = (taskbarWillBeVisible && Float.compare(currentValue, 1) != 0)
|
||||
|| (!taskbarWillBeVisible && Float.compare(currentValue, 0) != 0);
|
||||
|
||||
// Sync the first frame where we swap taskbar and hotseat.
|
||||
if (firstFrameVisChanged && mCanSyncViews && !Utilities.IS_RUNNING_IN_TEST_HARNESS) {
|
||||
DeviceProfile dp = mLauncher.getDeviceProfile();
|
||||
|
||||
// Do all the heavy work before the sync.
|
||||
mControllers.taskbarViewController.createIconAlignmentControllerIfNotExists(dp);
|
||||
|
||||
ViewRootSync.synchronizeNextDraw(mLauncher.getHotseat(),
|
||||
mControllers.taskbarActivityContext.getDragLayer(),
|
||||
() -> updateIconAlignment(alignment));
|
||||
} else {
|
||||
updateIconAlignment(alignment);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateIconAlignment(float alignment) {
|
||||
mControllers.taskbarViewController.setLauncherIconAlignment(
|
||||
alignment, mLauncher.getDeviceProfile());
|
||||
|
||||
|
||||
@@ -182,6 +182,16 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
+ mTaskbarIconTranslationYForStash.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the icon alignment controller if it does not already exist.
|
||||
* @param launcherDp Launcher device profile.
|
||||
*/
|
||||
public void createIconAlignmentControllerIfNotExists(DeviceProfile launcherDp) {
|
||||
if (mIconAlignControllerLazy == null) {
|
||||
mIconAlignControllerLazy = createIconAlignmentController(launcherDp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the taskbar icon alignment relative to Launcher hotseat icons
|
||||
* @param alignmentRatio [0, 1]
|
||||
@@ -189,9 +199,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
* 1 => fully aligned
|
||||
*/
|
||||
public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) {
|
||||
if (mIconAlignControllerLazy == null) {
|
||||
mIconAlignControllerLazy = createIconAlignmentController(launcherDp);
|
||||
}
|
||||
createIconAlignmentControllerIfNotExists(launcherDp);
|
||||
mIconAlignControllerLazy.setPlayFraction(alignmentRatio);
|
||||
if (alignmentRatio <= 0 || alignmentRatio >= 1) {
|
||||
// Cleanup lazy controller so that it is created again in next animation
|
||||
|
||||
@@ -233,7 +233,8 @@ public class LauncherSwipeHandlerV2 extends
|
||||
|
||||
return mActivity.getFirstMatchForAppClose(launchCookieItemId,
|
||||
runningTaskView.getTask().key.getComponent().getPackageName(),
|
||||
UserHandle.of(runningTaskView.getTask().key.userId));
|
||||
UserHandle.of(runningTaskView.getTask().key.userId),
|
||||
false /* supportsAllAppsState */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -135,8 +135,8 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
|
||||
SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
|
||||
|
||||
SplitSelectStateController controller =
|
||||
new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this),
|
||||
getStateManager(), null /*depthController*/);
|
||||
new SplitSelectStateController(this, mHandler, getStateManager(),
|
||||
null /* depthController */);
|
||||
mDragLayer.recreateControllers();
|
||||
mFallbackRecentsView.init(mActionsView, controller);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.quickstep.util;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
import static android.app.PendingIntent.FLAG_MUTABLE;
|
||||
|
||||
import static com.android.launcher3.Utilities.postAsyncCallback;
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
@@ -27,9 +28,11 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityThread;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.text.TextUtils;
|
||||
import android.view.RemoteAnimationAdapter;
|
||||
import android.view.SurfaceControl;
|
||||
import android.window.TransitionInfo;
|
||||
@@ -45,6 +48,7 @@ import com.android.quickstep.TaskAnimationManager;
|
||||
import com.android.quickstep.TaskViewUtils;
|
||||
import com.android.quickstep.views.GroupedTaskView;
|
||||
import com.android.quickstep.views.TaskView;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
@@ -59,12 +63,13 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class SplitSelectStateController {
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private final SystemUiProxy mSystemUiProxy;
|
||||
private final StateManager mStateManager;
|
||||
private final DepthController mDepthController;
|
||||
private @StagePosition int mStagePosition;
|
||||
private PendingIntent mInitialTaskPendingIntent;
|
||||
private Intent mInitialTaskIntent;
|
||||
private int mInitialTaskId = INVALID_TASK_ID;
|
||||
private int mSecondTaskId = INVALID_TASK_ID;
|
||||
private boolean mRecentsAnimationRunning;
|
||||
@@ -72,10 +77,11 @@ public class SplitSelectStateController {
|
||||
@Nullable
|
||||
private GroupedTaskView mLaunchingTaskView;
|
||||
|
||||
public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy,
|
||||
StateManager stateManager, DepthController depthController) {
|
||||
public SplitSelectStateController(Context context, Handler handler, StateManager stateManager,
|
||||
DepthController depthController) {
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
mSystemUiProxy = systemUiProxy;
|
||||
mSystemUiProxy = SystemUiProxy.INSTANCE.get(mContext);
|
||||
mStateManager = stateManager;
|
||||
mDepthController = depthController;
|
||||
}
|
||||
@@ -86,12 +92,11 @@ public class SplitSelectStateController {
|
||||
public void setInitialTaskSelect(int taskId, @StagePosition int stagePosition) {
|
||||
mInitialTaskId = taskId;
|
||||
mStagePosition = stagePosition;
|
||||
mInitialTaskPendingIntent = null;
|
||||
mInitialTaskIntent = null;
|
||||
}
|
||||
|
||||
public void setInitialTaskSelect(PendingIntent pendingIntent,
|
||||
@StagePosition int stagePosition) {
|
||||
mInitialTaskPendingIntent = pendingIntent;
|
||||
public void setInitialTaskSelect(Intent intent, @StagePosition int stagePosition) {
|
||||
mInitialTaskIntent = intent;
|
||||
mStagePosition = stagePosition;
|
||||
mInitialTaskId = INVALID_TASK_ID;
|
||||
}
|
||||
@@ -99,9 +104,22 @@ public class SplitSelectStateController {
|
||||
/**
|
||||
* To be called after second task selected
|
||||
*/
|
||||
public void setSecondTaskId(int taskId, Consumer<Boolean> callback) {
|
||||
mSecondTaskId = taskId;
|
||||
launchTasks(mInitialTaskId, mInitialTaskPendingIntent, mSecondTaskId, mStagePosition,
|
||||
public void setSecondTask(Task task, Consumer<Boolean> callback) {
|
||||
mSecondTaskId = task.key.id;
|
||||
final Intent fillInIntent;
|
||||
if (mInitialTaskIntent != null) {
|
||||
fillInIntent = new Intent();
|
||||
if (TextUtils.equals(mInitialTaskIntent.getComponent().getPackageName(),
|
||||
task.topActivity.getPackageName())) {
|
||||
fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||
}
|
||||
} else {
|
||||
fillInIntent = null;
|
||||
}
|
||||
final PendingIntent pendingIntent =
|
||||
mInitialTaskIntent == null ? null : PendingIntent.getActivity(mContext, 0,
|
||||
mInitialTaskIntent, FLAG_MUTABLE);
|
||||
launchTasks(mInitialTaskId, pendingIntent, fillInIntent, mSecondTaskId, mStagePosition,
|
||||
callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO);
|
||||
}
|
||||
|
||||
@@ -113,18 +131,32 @@ public class SplitSelectStateController {
|
||||
mLaunchingTaskView = groupedTaskView;
|
||||
TaskView.TaskIdAttributeContainer[] taskIdAttributeContainers =
|
||||
groupedTaskView.getTaskIdAttributeContainers();
|
||||
launchTasks(taskIdAttributeContainers[0].getTask().key.id, null,
|
||||
launchTasks(taskIdAttributeContainers[0].getTask().key.id,
|
||||
taskIdAttributeContainers[1].getTask().key.id,
|
||||
taskIdAttributeContainers[0].getStagePosition(), callback, freezeTaskList,
|
||||
groupedTaskView.getSplitRatio());
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called when we want to launch split pairs from Overview when split is initiated from
|
||||
* Overview.
|
||||
*/
|
||||
public void launchTasks(int taskId1, int taskId2, @StagePosition int stagePosition,
|
||||
Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) {
|
||||
launchTasks(taskId1, null /* taskPendingIntent */, null /* fillInIntent */, taskId2,
|
||||
stagePosition, callback, freezeTaskList, splitRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called when we want to launch split pairs from Overview. Split can be initiated from
|
||||
* either Overview or home, or all apps. Either both taskIds are set, or a pending intent + a
|
||||
* fill in intent with a taskId2 are set.
|
||||
* @param taskPendingIntent is null when split is initiated from Overview
|
||||
* @param stagePosition representing location of task1
|
||||
*/
|
||||
public void launchTasks(int taskId1, @Nullable PendingIntent taskPendingIntent,
|
||||
int taskId2, @StagePosition int stagePosition, Consumer<Boolean> callback,
|
||||
boolean freezeTaskList, float splitRatio) {
|
||||
@Nullable Intent fillInIntent, int taskId2, @StagePosition int stagePosition,
|
||||
Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) {
|
||||
// Assume initial task is for top/left part of screen
|
||||
final int[] taskIds = stagePosition == STAGE_POSITION_TOP_OR_LEFT
|
||||
? new int[]{taskId1, taskId2}
|
||||
@@ -156,7 +188,7 @@ public class SplitSelectStateController {
|
||||
splitRatio, adapter);
|
||||
} else {
|
||||
mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent,
|
||||
new Intent(), taskId2, mainOpts.toBundle(), null /* sideOptions */,
|
||||
fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */,
|
||||
stagePosition, splitRatio, adapter);
|
||||
}
|
||||
}
|
||||
@@ -250,7 +282,7 @@ public class SplitSelectStateController {
|
||||
*/
|
||||
public void resetState() {
|
||||
mInitialTaskId = INVALID_TASK_ID;
|
||||
mInitialTaskPendingIntent = null;
|
||||
mInitialTaskIntent = null;
|
||||
mSecondTaskId = INVALID_TASK_ID;
|
||||
mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
|
||||
mRecentsAnimationRunning = false;
|
||||
@@ -262,7 +294,7 @@ public class SplitSelectStateController {
|
||||
* chosen
|
||||
*/
|
||||
public boolean isSplitSelectActive() {
|
||||
return (mInitialTaskId != INVALID_TASK_ID || mInitialTaskPendingIntent != null)
|
||||
return (mInitialTaskId != INVALID_TASK_ID || mInitialTaskIntent != null)
|
||||
&& mSecondTaskId == INVALID_TASK_ID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,9 +182,8 @@ public class GroupedTaskView extends TaskView {
|
||||
|
||||
@Override
|
||||
public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) {
|
||||
getRecentsView().getSplitPlaceholder().launchTasks(mTask.key.id, null,
|
||||
mSecondaryTask.key.id, STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList,
|
||||
getSplitRatio());
|
||||
getRecentsView().getSplitPlaceholder().launchTasks(mTask.key.id, mSecondaryTask.key.id,
|
||||
STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList, getSplitRatio());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.quickstep.views;
|
||||
|
||||
import static android.app.PendingIntent.FLAG_MUTABLE;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
import static android.view.View.MeasureSpec.EXACTLY;
|
||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
||||
@@ -67,8 +66,6 @@ import android.animation.PropertyValuesHolder;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.LocusId;
|
||||
import android.content.res.Configuration;
|
||||
@@ -2011,22 +2008,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TaskView getTaskViewByComponentName(ComponentName componentName) {
|
||||
if (componentName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < getTaskViewCount(); i++) {
|
||||
TaskView taskView = requireTaskViewAt(i);
|
||||
if (taskView.getItemInfo().getIntent().getComponent().getPackageName().equals(
|
||||
componentName.getPackageName())) {
|
||||
return taskView;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getRunningTaskIndex() {
|
||||
TaskView taskView = getRunningTaskView();
|
||||
return taskView == null ? -1 : indexOfChild(taskView);
|
||||
@@ -3969,17 +3950,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
|
||||
public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) {
|
||||
// Remove the task if it exists in Overview
|
||||
TaskView matchingTaskView = getTaskViewByComponentName(
|
||||
splitSelectSource.intent.getComponent());
|
||||
if (matchingTaskView != null) {
|
||||
removeTaskInternal(matchingTaskView.getTaskViewId());
|
||||
}
|
||||
|
||||
mSplitSelectSource = splitSelectSource;
|
||||
mSplitSelectStateController.setInitialTaskSelect(
|
||||
PendingIntent.getActivity(
|
||||
mContext, 0, splitSelectSource.intent, FLAG_MUTABLE),
|
||||
mSplitSelectStateController.setInitialTaskSelect(splitSelectSource.intent,
|
||||
splitSelectSource.position.stagePosition);
|
||||
}
|
||||
|
||||
@@ -4033,8 +4005,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
|
||||
secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isInitialSplit */);
|
||||
pendingAnimation.addEndListener(aBoolean ->
|
||||
mSplitSelectStateController.setSecondTaskId(task.key.id,
|
||||
aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
|
||||
mSplitSelectStateController.setSecondTask(
|
||||
task, aBoolean1 -> RecentsView.this.resetFromSplitSelectionState()));
|
||||
if (containerTaskView.containsMultipleTasks()) {
|
||||
// If we are launching from a child task, then only hide the thumbnail itself
|
||||
mSecondSplitHiddenView = thumbnailView;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
<item name="preferenceScreenStyle">@style/HomeSettings.PreferenceScreenStyle</item>
|
||||
<item name="preferenceStyle">@style/HomeSettings.PreferenceStyle</item>
|
||||
<item name="switchPreferenceStyle">@style/HomeSettings.SwitchPreferenceStyle</item>
|
||||
<item name="android:fontFamily">google-sans-text</item>
|
||||
</style>
|
||||
|
||||
<style name="HomeSettings.CategoryStyle" parent="@style/Preference.Category.Material">
|
||||
|
||||
@@ -2747,8 +2747,11 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
* @param preferredItemId The id of the preferred item to match to if it exists.
|
||||
* @param packageName The package name of the app to match.
|
||||
* @param user The user of the app to match.
|
||||
* @param supportsAllAppsState If true and we are in All Apps state, looks for view in All Apps.
|
||||
* Else we only looks on the workspace.
|
||||
*/
|
||||
public View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user) {
|
||||
public View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user,
|
||||
boolean supportsAllAppsState) {
|
||||
final ItemInfoMatcher preferredItem = (info, cn) ->
|
||||
info != null && info.id == preferredItemId;
|
||||
final ItemInfoMatcher packageAndUserAndApp = (info, cn) ->
|
||||
@@ -2759,7 +2762,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
&& TextUtils.equals(info.getTargetComponent().getPackageName(),
|
||||
packageName);
|
||||
|
||||
if (isInState(LauncherState.ALL_APPS)) {
|
||||
if (supportsAllAppsState && isInState(LauncherState.ALL_APPS)) {
|
||||
return getFirstMatch(Collections.singletonList(mAppsView.getActiveRecyclerView()),
|
||||
preferredItem, packageAndUserAndApp);
|
||||
} else {
|
||||
|
||||
@@ -81,7 +81,7 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
private final List<FastScrollSectionInfo> mFastScrollerSections = new ArrayList<>();
|
||||
|
||||
// The of ordered component names as a result of a search query
|
||||
private ArrayList<AdapterItem> mSearchResults;
|
||||
private final ArrayList<AdapterItem> mSearchResults = new ArrayList<>();
|
||||
private BaseAllAppsAdapter<T> mAdapter;
|
||||
private AppInfoComparator mAppNameComparator;
|
||||
private final int mNumAppsPerRow;
|
||||
@@ -171,30 +171,33 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
* Returns whether there are is a filter set.
|
||||
*/
|
||||
public boolean hasFilter() {
|
||||
return (mSearchResults != null);
|
||||
return !mSearchResults.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there are no filtered results.
|
||||
*/
|
||||
public boolean hasNoFilteredResults() {
|
||||
return (mSearchResults != null) && mAccessibilityResultsCount == 0;
|
||||
return hasFilter() && mAccessibilityResultsCount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets results list for search
|
||||
*/
|
||||
public boolean setSearchResults(ArrayList<AdapterItem> results) {
|
||||
if (!Objects.equals(results, mSearchResults)) {
|
||||
mSearchResults = results;
|
||||
updateAdapterItems();
|
||||
return true;
|
||||
if (Objects.equals(results, mSearchResults)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
mSearchResults.clear();
|
||||
if (results != null) {
|
||||
mSearchResults.addAll(results);
|
||||
}
|
||||
updateAdapterItems();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean appendSearchResults(ArrayList<AdapterItem> results) {
|
||||
if (mSearchResults != null && results != null && results.size() > 0) {
|
||||
if (hasFilter() && results != null && results.size() > 0) {
|
||||
updateSearchAdapterItems(results, mSearchResults.size());
|
||||
refreshRecyclerView();
|
||||
return true;
|
||||
@@ -259,7 +262,7 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
|
||||
}
|
||||
|
||||
// Recompose the set of adapter items from the current set of apps
|
||||
if (mSearchResults == null) {
|
||||
if (mSearchResults.isEmpty()) {
|
||||
updateAdapterItems();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,4 +65,7 @@ public interface SearchUiManager {
|
||||
* sets highlight result's title
|
||||
*/
|
||||
default void setFocusedResultTitle(@Nullable CharSequence title) { }
|
||||
|
||||
/** Refresh the currently displayed list of results. */
|
||||
default void refreshResults() {}
|
||||
}
|
||||
|
||||
@@ -100,12 +100,14 @@ public class AllAppsSearchBarController
|
||||
@Override
|
||||
public void afterTextChanged(final Editable s) {
|
||||
mQuery = s.toString();
|
||||
mInput.getSelectionStart();
|
||||
if (mQuery.isEmpty()) {
|
||||
mSearchAlgorithm.cancel(true);
|
||||
mCallback.clearSearchResult();
|
||||
} else {
|
||||
mSearchAlgorithm.cancel(false);
|
||||
mSearchAlgorithm.doSearch(mQuery, mTextConversions, mCallback);
|
||||
mSearchAlgorithm.doSearch(mQuery, mInput.getSelectionStart(), mTextConversions,
|
||||
mCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +117,7 @@ public class AllAppsSearchBarController
|
||||
}
|
||||
// If play store continues auto updating an app, we want to show partial result.
|
||||
mSearchAlgorithm.cancel(false);
|
||||
mSearchAlgorithm.doSearch(mQuery, mCallback);
|
||||
mSearchAlgorithm.doSearch(mQuery, mInput.getSelectionStart(), mCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -58,7 +58,7 @@ public class DefaultAppSearchAlgorithm implements SearchAlgorithm<AdapterItem> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSearch(String query, SearchCallback<AdapterItem> callback) {
|
||||
public void doSearch(String query, int cursorLocation, SearchCallback<AdapterItem> callback) {
|
||||
mAppState.getModel().enqueueModelUpdateTask(new BaseModelUpdateTask() {
|
||||
@Override
|
||||
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
|
||||
|
||||
@@ -25,13 +25,14 @@ public interface SearchAlgorithm<T> {
|
||||
/**
|
||||
* Performs search and sends the result to {@link SearchCallback}.
|
||||
*/
|
||||
void doSearch(String query, SearchCallback<T> callback);
|
||||
void doSearch(String query, int cursorLocation, SearchCallback<T> callback);
|
||||
|
||||
/**
|
||||
* Performs search with {@code query} and the {@code suggestedQueries}/
|
||||
*/
|
||||
default void doSearch(String query, String[] suggestedQueries, SearchCallback<T> callback) {
|
||||
doSearch(query, callback);
|
||||
default void doSearch(String query, int cursorLocation, String[] suggestedQueries,
|
||||
SearchCallback<T> callback) {
|
||||
doSearch(query, cursorLocation, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -159,7 +159,8 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
|
||||
return;
|
||||
}
|
||||
View icon = mLauncher.getFirstMatchForAppClose(-1,
|
||||
mContract.componentName.getPackageName(), mContract.user);
|
||||
mContract.componentName.getPackageName(), mContract.user,
|
||||
false /* supportsAllAppsState */);
|
||||
|
||||
boolean iconChanged = mIcon != icon;
|
||||
if (iconChanged) {
|
||||
|
||||
@@ -48,7 +48,8 @@ public final class SimpleWidgetsSearchAlgorithm implements SearchAlgorithm<Widge
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doSearch(String query, SearchCallback<WidgetsListBaseEntry> callback) {
|
||||
public void doSearch(String query, int cursorLocation,
|
||||
SearchCallback<WidgetsListBaseEntry> callback) {
|
||||
ArrayList<WidgetsListBaseEntry> result = getFilteredWidgets(mDataProvider, query);
|
||||
mResultHandler.post(() -> callback.onSearchResult(query, result));
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class WidgetsSearchBarController implements TextWatcher,
|
||||
} else {
|
||||
mSearchAlgorithm.cancel(/* interruptActiveRequests= */ false);
|
||||
mSearchModeListener.enterSearchMode();
|
||||
mSearchAlgorithm.doSearch(mQuery, this);
|
||||
mSearchAlgorithm.doSearch(mQuery, mInput.getSelectionStart(), this);
|
||||
mCancelButton.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -163,7 +163,7 @@ public class SimpleWidgetsSearchAlgorithmTest {
|
||||
mCameraContentEntry, mClockHeaderEntry, mClockContentEntry))
|
||||
.when(mDataProvider)
|
||||
.getAllWidgets();
|
||||
mSimpleWidgetsSearchAlgorithm.doSearch("Ca", mSearchCallback);
|
||||
mSimpleWidgetsSearchAlgorithm.doSearch("Ca", 2, mSearchCallback);
|
||||
MAIN_EXECUTOR.submit(() -> { }).get();
|
||||
verify(mSearchCallback).onSearchResult(
|
||||
matches("Ca"), argThat(a -> a != null && !a.isEmpty()));
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class WidgetsSearchBarControllerTest {
|
||||
public void afterTextChanged_shouldDoSearch() {
|
||||
mEditText.setText("abc");
|
||||
|
||||
verify(mSearchAlgorithm).doSearch(eq("abc"), any());
|
||||
verify(mSearchAlgorithm).doSearch(eq("abc"), 3, any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user