Merge "Revert "Cleanup code related to ag/11035582"" into ub-launcher3-rvc-dev
diff --git a/Android.mk b/Android.mk
index 9cfcf17..352885b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -32,7 +32,8 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
LauncherPluginLib \
- launcher_log_protos_lite
+ launcher_log_protos_lite \
+ uieventloggerlib
LOCAL_SRC_FILES := \
$(call all-proto-files-under, protos) \
@@ -130,8 +131,10 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
SystemUISharedLib \
+ SystemUI-statsd \
launcherprotosnano \
launcher_log_protos_lite
+
ifneq (,$(wildcard frameworks/base))
LOCAL_PRIVATE_PLATFORM_APIS := true
else
@@ -202,8 +205,10 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
SystemUISharedLib \
+ SystemUI-statsd \
launcherprotosnano \
launcher_log_protos_lite
+
ifneq (,$(wildcard frameworks/base))
LOCAL_PRIVATE_PLATFORM_APIS := true
else
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/ComponentKeyMapper.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/ComponentKeyMapper.java
index fdb8e4c..d200868 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/ComponentKeyMapper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/ComponentKeyMapper.java
@@ -21,7 +21,6 @@
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
-import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.ComponentKey;
public class ComponentKeyMapper {
@@ -57,9 +56,8 @@
return item;
} else if (getComponentClass().equals(COMPONENT_CLASS_MARKER)) {
return mCache.getInstantApp(componentKey.componentName.getPackageName());
- } else if (componentKey instanceof ShortcutKey) {
- return mCache.getShortcutInfo((ShortcutKey) componentKey);
+ } else {
+ return mCache.getShortcutInfo(componentKey);
}
- return null;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java
index 6c4bfe8..ab96b1340 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/DynamicItemCache.java
@@ -45,6 +45,7 @@
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
+import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import java.util.ArrayList;
@@ -76,7 +77,7 @@
private final Runnable mOnUpdateCallback;
private final IconCache mIconCache;
- private final Map<ShortcutKey, WorkspaceItemInfo> mShortcuts;
+ private final Map<ComponentKey, WorkspaceItemInfo> mShortcuts;
private final Map<String, InstantAppItemInfo> mInstantApps;
public DynamicItemCache(Context context, Runnable onUpdateCallback) {
@@ -230,7 +231,7 @@
}
@MainThread
- public WorkspaceItemInfo getShortcutInfo(ShortcutKey key) {
+ public WorkspaceItemInfo getShortcutInfo(ComponentKey key) {
return mShortcuts.get(key);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index f907089..78cc2dc 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -200,6 +200,7 @@
pageId = LauncherSettings.Settings.call(mLauncher.getContentResolver(),
LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
+ mNewScreens = IntArray.wrap(pageId);
}
for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
View child = mHotseat.getChildAt(i, 0);
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index 4213740..fa137f8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -33,6 +33,7 @@
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.Workspace;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.UserEventDispatcher;
@@ -153,6 +154,12 @@
private void logUserAction(boolean migrated, int pageIndex) {
LauncherLogProto.Action action = new LauncherLogProto.Action();
LauncherLogProto.Target target = new LauncherLogProto.Target();
+
+ int hotseatItemsCount = mLauncher.getHotseat().getShortcutsAndWidgets().getChildCount();
+ // -1 to exclude smart space
+ int workspaceItemCount = mLauncher.getWorkspace().getScreenWithId(
+ Workspace.FIRST_SCREEN_ID).getShortcutsAndWidgets().getChildCount() - 1;
+
action.type = LauncherLogProto.Action.Type.TOUCH;
action.touch = LauncherLogProto.Action.Touch.TAP;
target.containerType = LauncherLogProto.ContainerType.TIP;
@@ -162,7 +169,7 @@
target.rank = MIGRATION_EXPERIMENT_IDENTIFIER;
// encoding migration type on pageIndex
target.pageIndex = pageIndex;
- target.cardinality = HotseatPredictionController.MAX_ITEMS_FOR_MIGRATION;
+ target.cardinality = (workspaceItemCount * 1000) + hotseatItemsCount;
LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
UserEventDispatcher.newInstance(getContext()).dispatchUserEvent(event, null);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 63277d2..1aff8e9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -95,12 +95,11 @@
private static final String TAG = "PredictiveHotseat";
private static final boolean DEBUG = false;
- public static final int MAX_ITEMS_FOR_MIGRATION = DeviceConfig.getInt(
- DeviceFlag.NAMESPACE_LAUNCHER, "max_homepage_items_for_migration", 5);
-
//TODO: replace this with AppTargetEvent.ACTION_UNPIN (b/144119543)
private static final int APPTARGET_ACTION_UNPIN = 4;
+ private static final String PREDICTED_ITEMS_CACHE_KEY = "predicted_item_keys";
+
private static final String APP_LOCATION_HOTSEAT = "hotseat";
private static final String APP_LOCATION_WORKSPACE = "workspace";
@@ -125,6 +124,7 @@
private AllAppsStore mAllAppsStore;
private AnimatorSet mIconRemoveAnimators;
private boolean mUIUpdatePaused = false;
+ private boolean mRequiresCacheUpdate = false;
private HotseatEduController mHotseatEduController;
@@ -151,6 +151,7 @@
if (mHotseat.isAttachedToWindow()) {
onViewAttachedToWindow(mHotseat);
}
+ showCachedItems();
}
/**
@@ -300,6 +301,16 @@
mAppPredictor.requestPredictionUpdate();
}
+ private void showCachedItems() {
+ ArrayList<ComponentKey> componentKeys = getCachedComponentKeys();
+ mComponentKeyMappers.clear();
+ for (ComponentKey key : componentKeys) {
+ mComponentKeyMappers.add(new ComponentKeyMapper(key, mDynamicItemCache));
+ }
+ updateDependencies();
+ fillGapsWithPrediction();
+ }
+
private Bundle getAppPredictionContextExtra() {
Bundle bundle = new Bundle();
@@ -356,6 +367,7 @@
private void setPredictedApps(List<AppTarget> appTargets) {
mComponentKeyMappers.clear();
StringBuilder predictionLog = new StringBuilder("predictedApps: [\n");
+ ArrayList<ComponentKey> componentKeys = new ArrayList<>();
for (AppTarget appTarget : appTargets) {
ComponentKey key;
if (appTarget.getShortcutInfo() != null) {
@@ -364,6 +376,7 @@
key = new ComponentKey(new ComponentName(appTarget.getPackageName(),
appTarget.getClassName()), appTarget.getUser());
}
+ componentKeys.add(key);
predictionLog.append(key.toString());
predictionLog.append(",rank:");
predictionLog.append(appTarget.getRank());
@@ -378,6 +391,35 @@
} else if (mHotseatEduController != null) {
mHotseatEduController.setPredictedApps(mapToWorkspaceItemInfo(mComponentKeyMappers));
}
+ // should invalidate cache if AiAi sends empty list of AppTargets
+ if (appTargets.isEmpty()) {
+ mRequiresCacheUpdate = true;
+ }
+ cachePredictionComponentKeys(componentKeys);
+ }
+
+ private void cachePredictionComponentKeys(ArrayList<ComponentKey> componentKeys) {
+ if (!mRequiresCacheUpdate) return;
+ StringBuilder builder = new StringBuilder();
+ for (ComponentKey componentKey : componentKeys) {
+ builder.append(componentKey);
+ builder.append("\n");
+ }
+ mLauncher.getDevicePrefs().edit().putString(PREDICTED_ITEMS_CACHE_KEY,
+ builder.toString()).apply();
+ mRequiresCacheUpdate = false;
+ }
+
+ private ArrayList<ComponentKey> getCachedComponentKeys() {
+ String cachedBlob = mLauncher.getDevicePrefs().getString(PREDICTED_ITEMS_CACHE_KEY, "");
+ ArrayList<ComponentKey> results = new ArrayList<>();
+ for (String line : cachedBlob.split("\n")) {
+ ComponentKey key = ComponentKey.fromString(line);
+ if (key != null) {
+ results.add(key);
+ }
+ }
+ return results;
}
private void updateDependencies() {
@@ -403,6 +445,7 @@
icon.pin(workspaceItemInfo);
AppTarget appTarget = getAppTargetFromItemInfo(workspaceItemInfo);
notifyItemAction(appTarget, APP_LOCATION_HOTSEAT, AppTargetEvent.ACTION_PIN);
+ mRequiresCacheUpdate = true;
}
private List<WorkspaceItemInfo> mapToWorkspaceItemInfo(
@@ -569,6 +612,7 @@
}
mDragObject = null;
fillGapsWithPrediction(true, this::removeOutlineDrawings);
+ mRequiresCacheUpdate = true;
}
@Nullable
@@ -642,6 +686,9 @@
if (isReady()) return;
int hotseatItemsCount = mHotseat.getShortcutsAndWidgets().getChildCount();
+ int maxItems = DeviceConfig.getInt(
+ DeviceFlag.NAMESPACE_LAUNCHER, "max_homepage_items_for_migration", 5);
+
// -1 to exclude smart space
int workspaceItemCount = mLauncher.getWorkspace().getScreenWithId(
Workspace.FIRST_SCREEN_ID).getShortcutsAndWidgets().getChildCount() - 1;
@@ -650,7 +697,7 @@
// open spots in their hotseat and have more than maxItems in their hotseat + workspace
if (hotseatItemsCount == mHotSeatItemsCount && workspaceItemCount + hotseatItemsCount
- > MAX_ITEMS_FOR_MIGRATION) {
+ > maxItems) {
mLauncher.getSharedPrefs().edit().putBoolean(HotseatEduController.KEY_HOTSEAT_EDU_SEEN,
true).apply();
@@ -662,8 +709,8 @@
// temporarily encode details in log target (go/hotseat_migration)
target.rank = 2;
- target.cardinality = MAX_ITEMS_FOR_MIGRATION;
- target.pageIndex = (workspaceItemCount * 1000) + hotseatItemsCount;
+ target.cardinality = (workspaceItemCount * 1000) + hotseatItemsCount;
+ target.pageIndex = maxItems;
LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
UserEventDispatcher.newInstance(mLauncher).dispatchUserEvent(event, null);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
index 70b139d..fadde37 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java
@@ -204,27 +204,23 @@
true /* freezeTaskList */);
} else {
int taskId = mRecentsView.getNextPageTaskView().getTask().key.id;
- mFinishingRecentsAnimationForNewTaskId = taskId;
- mRecentsAnimationController.finish(true /* toRecents */, () -> {
- if (!mCanceled) {
- TaskView nextTask = mRecentsView.getTaskView(taskId);
- if (nextTask != null) {
- nextTask.launchTask(false /* animate */, true /* freezeTaskList */,
- success -> {
- resultCallback.accept(success);
- if (!success) {
- mActivityInterface.onLaunchTaskFailed();
- nextTask.notifyTaskLaunchFailed(TAG);
- } else {
- mActivityInterface.onLaunchTaskSuccess();
- }
- }, MAIN_EXECUTOR.getHandler());
- }
- mStateCallback.setStateOnUiThread(successStateFlag);
+ if (!mCanceled) {
+ TaskView nextTask = mRecentsView.getTaskView(taskId);
+ if (nextTask != null) {
+ nextTask.launchTask(false /* animate */, true /* freezeTaskList */,
+ success -> {
+ resultCallback.accept(success);
+ if (!success) {
+ mActivityInterface.onLaunchTaskFailed();
+ nextTask.notifyTaskLaunchFailed(TAG);
+ } else {
+ mActivityInterface.onLaunchTaskSuccess();
+ }
+ }, MAIN_EXECUTOR.getHandler());
}
- mCanceled = false;
- mFinishingRecentsAnimationForNewTaskId = -1;
- });
+ mStateCallback.setStateOnUiThread(successStateFlag);
+ }
+ mCanceled = false;
}
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
index 8574cf1..31a2814 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
@@ -30,6 +30,7 @@
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.GestureState.STATE_END_TARGET_ANIMATION_FINISHED;
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
+import static com.android.quickstep.GestureState.STATE_TASK_APPEARED_DURING_SWITCH;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
@@ -253,6 +254,8 @@
| STATE_RECENTS_SCROLLING_FINISHED,
this::onSettledOnEndTarget);
+ mGestureState.runOnceAtState(STATE_TASK_APPEARED_DURING_SWITCH, this::onTaskAppeared);
+
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher);
@@ -727,6 +730,22 @@
}
}
+ private void onTaskAppeared() {
+ RemoteAnimationTargetCompat app = mGestureState.getAnimationTarget();
+ if (mRecentsAnimationController != null && app != null) {
+
+ // TODO(b/152480470): Update Task target animation after onTaskAppeared holistically.
+ /* android.util.Log.d("LauncherSwipeHandler", "onTaskAppeared");
+
+ final boolean result = mRecentsAnimationController.removeTaskTarget(app);
+ mGestureState.setAnimationTarget(null);
+ android.util.Log.d("LauncherSwipeHandler", "removeTask, result=" + result); */
+
+ mRecentsAnimationController.finish(false /* toRecents */,
+ null /* onFinishComplete */);
+ }
+ }
+
private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
boolean isCancel) {
final GestureEndTarget endTarget;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index a18f7ba..7aee308 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -30,8 +30,8 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_DISMISS_SWIPE_UP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_SWIPE_DOWN;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
@@ -1280,7 +1280,8 @@
ComponentKey compKey = TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key);
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
endState.logAction, Direction.UP, index, compKey);
- mActivity.getStatsLogManager().log(TASK_DISMISS_SWIPE_UP, taskView.buildProto());
+ mActivity.getStatsLogManager().log(LAUNCHER_TASK_DISMISS_SWIPE_UP,
+ taskView.buildProto());
}
}
@@ -1830,7 +1831,8 @@
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
endState.logAction, Direction.DOWN, indexOfChild(tv),
TaskUtils.getLaunchComponentKeyForTask(task.key));
- mActivity.getStatsLogManager().log(TASK_LAUNCH_SWIPE_DOWN, tv.buildProto()
+ mActivity.getStatsLogManager().log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN,
+ tv.buildProto()
);
}
} else {
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index 470b720..171c91d 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -29,7 +29,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.TASK_LAUNCH_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -209,7 +209,7 @@
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
TaskUtils.getLaunchComponentKeyForTask(getTask().key));
- mActivity.getStatsLogManager().log(TASK_LAUNCH_TAP, buildProto());
+ mActivity.getStatsLogManager().log(LAUNCHER_TASK_LAUNCH_TAP, buildProto());
});
mCornerRadius = TaskCornerRadius.get(context);
mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 123c988..0f45196 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -62,10 +62,13 @@
@Override
public void setState(@NonNull LauncherState state) {
- ScaleAndTranslation scaleAndTranslation = state
- .getOverviewScaleAndTranslation(mLauncher);
+ ScaleAndTranslation scaleAndTranslation = state.getOverviewScaleAndTranslation(mLauncher);
+ float translationX = scaleAndTranslation.translationX;
+ if (mRecentsView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ translationX = -translationX;
+ }
SCALE_PROPERTY.set(mRecentsView, scaleAndTranslation.scale);
- mRecentsView.setTranslationX(scaleAndTranslation.translationX);
+ mRecentsView.setTranslationX(translationX);
mRecentsView.setTranslationY(scaleAndTranslation.translationY);
getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
@@ -96,9 +99,13 @@
void setStateWithAnimationInternal(@NonNull final LauncherState toState,
@NonNull StateAnimationConfig config, @NonNull PendingAnimation setter) {
ScaleAndTranslation scaleAndTranslation = toState.getOverviewScaleAndTranslation(mLauncher);
+ float translationX = scaleAndTranslation.translationX;
+ if (mRecentsView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ translationX = -translationX;
+ }
setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleAndTranslation.scale,
config.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR));
- setter.setFloat(mRecentsView, VIEW_TRANSLATE_X, scaleAndTranslation.translationX,
+ setter.setFloat(mRecentsView, VIEW_TRANSLATE_X, translationX,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
setter.setFloat(mRecentsView, VIEW_TRANSLATE_Y, scaleAndTranslation.translationY,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 5118906..544f420 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -23,6 +23,7 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.systemui.shared.recents.model.ThumbnailData;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -109,6 +110,9 @@
public static final int STATE_RECENTS_SCROLLING_FINISHED =
getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED");
+ // Called when the new task appeared from quick switching.
+ public static final int STATE_TASK_APPEARED_DURING_SWITCH =
+ getFlagForIndex("STATE_TASK_APPEARED_DURING_SWITCH");
// Needed to interact with the current activity
private final Intent mHomeIntent;
@@ -119,6 +123,7 @@
private ActivityManager.RunningTaskInfo mRunningTask;
private GestureEndTarget mEndTarget;
+ private RemoteAnimationTargetCompat mAnimationTarget;
// TODO: This can be removed once we stop finishing the animation when starting a new task
private int mFinishingRecentsAnimationTaskId = -1;
@@ -227,6 +232,14 @@
return mEndTarget;
}
+ public void setAnimationTarget(RemoteAnimationTargetCompat target) {
+ mAnimationTarget = target;
+ }
+
+ public RemoteAnimationTargetCompat getAnimationTarget() {
+ return mAnimationTarget;
+ }
+
/**
* Sets the end target of this gesture and immediately notifies the state changes.
*/
@@ -301,6 +314,12 @@
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
}
+ @Override
+ public void onTaskAppeared(RemoteAnimationTargetCompat app) {
+ mAnimationTarget = app;
+ mStateCallback.setState(STATE_TASK_APPEARED_DURING_SWITCH);
+ }
+
public void dump(PrintWriter pw) {
pw.println("GestureState:");
pw.println(" gestureID=" + mGestureId);
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 10f9feb..b0ce8e6 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -124,6 +124,17 @@
}
@Override
+ public void onRecentTaskListUpdated() {
+ // In some cases immediately after booting, the tasks in the system recent task list may be
+ // loaded, but not in the active task hierarchy in the system. These tasks are displayed in
+ // overview, but removing them don't result in a onTaskStackChanged() nor a onTaskRemoved()
+ // callback (those are for changes to the active tasks), but the task list is still updated,
+ // so we should also invalidate the change id to ensure we load a new list instead of
+ // reusing a stale list.
+ mChangeId++;
+ }
+
+ @Override
public void onTaskRemoved(int taskId) {
mTasks = loadTasksInBackground(Integer.MAX_VALUE, false);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index d1dbcfb..7d568a4 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -118,6 +118,16 @@
});
}
+ @BinderThread
+ @Override
+ public void onTaskAppeared(RemoteAnimationTargetCompat app) {
+ Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
+ for (RecentsAnimationListener listener : getListeners()) {
+ listener.onTaskAppeared(app);
+ }
+ });
+ }
+
private final void onAnimationFinished(RecentsAnimationController controller) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (RecentsAnimationListener listener : getListeners()) {
@@ -147,5 +157,10 @@
* Callback made whenever the recents animation is finished.
*/
default void onRecentsAnimationFinished(RecentsAnimationController controller) {}
+
+ /**
+ * Callback made when a task started from the recents is ready for an app transition.
+ */
+ default void onTaskAppeared(RemoteAnimationTargetCompat app) {}
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 8dd4aa4..5ece2d7 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -28,12 +28,14 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
+import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import com.android.launcher3.util.Preconditions;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -107,6 +109,15 @@
UI_HELPER_EXECUTOR.execute(() -> mController.cleanupScreenshot());
}
+ /**
+ * Remove task remote animation target from
+ * {@link RecentsAnimationCallbacks#onTaskAppeared(RemoteAnimationTargetCompat)}}.
+ */
+ @UiThread
+ public boolean removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) {
+ return mController.removeTask(target.taskId);
+ }
+
@UiThread
public void finishAnimationToHome() {
finishAndClear(true /* toRecents */, null, false /* sendUserLeaveHint */);
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 5a15ec6..e946835 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -118,6 +118,8 @@
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
<attr name="dbFile" format="string" />
+ <!-- numAllAppsColumns defaults to numColumns, if not specified -->
+ <attr name="numAllAppsColumns" format="integer" />
<attr name="defaultLayoutId" format="reference" />
<attr name="demoModeLayoutId" format="reference" />
</declare-styleable>
@@ -133,6 +135,12 @@
<attr name="iconTextSize" format="float" />
<!-- If true, this display option is used to determine the default grid -->
<attr name="canBeDefault" format="boolean" />
+
+ <!-- The following values are only enabled if grid is supported. -->
+ <!-- allAppsIconSize defaults to iconSize, if not specified -->
+ <attr name="allAppsIconSize" format="float" />
+ <!-- allAppsIconTextSize defaults to iconTextSize, if not specified -->
+ <attr name="allAppsIconTextSize" format="float" />
</declare-styleable>
<declare-styleable name="CellLayout">
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 2dc7836..ec93eda 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -16,7 +16,7 @@
package com.android.launcher3;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.APP_LAUNCH_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.util.DefaultDisplay.CHANGE_ROTATION;
import android.app.ActivityOptions;
@@ -184,7 +184,7 @@
sourceContainer);
}
getUserEventDispatcher().logAppLaunch(v, intent, user);
- getStatsLogManager().log(APP_LAUNCH_TAP, item.buildProto(null, null));
+ getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item.buildProto(null, null));
return true;
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 4e1e586..fc3c9fd 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -25,8 +25,6 @@
import android.util.DisplayMetrics;
import android.view.Surface;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.DotRenderer;
@@ -36,8 +34,6 @@
public class DeviceProfile {
public final InvariantDeviceProfile inv;
- // IDP with no grid override values.
- @Nullable private final InvariantDeviceProfile originalIdp;
// Device properties
public final boolean isTablet;
@@ -138,11 +134,10 @@
public DotRenderer mDotRendererAllApps;
public DeviceProfile(Context context, InvariantDeviceProfile inv,
- InvariantDeviceProfile originalIDP, Point minSize, Point maxSize,
+ Point minSize, Point maxSize,
int width, int height, boolean isLandscape, boolean isMultiWindowMode) {
this.inv = inv;
- this.originalIdp = inv;
this.isLandscape = isLandscape;
this.isMultiWindowMode = isMultiWindowMode;
@@ -234,19 +229,6 @@
// Recalculate the available dimensions using the new hotseat size.
updateAvailableDimensions(dm, res);
}
-
- if (originalIDP != null) {
- // Grid size change should not affect All Apps UI, so we use the original profile
- // measurements here.
- DeviceProfile originalProfile = isLandscape
- ? originalIDP.landscapeProfile
- : originalIDP.portraitProfile;
- allAppsIconSizePx = originalProfile.iconSizePx;
- allAppsIconTextSizePx = originalProfile.iconTextSizePx;
- allAppsCellHeightPx = originalProfile.allAppsCellHeightPx;
- allAppsIconDrawablePaddingPx = originalProfile.iconDrawablePaddingOriginalPx;
- allAppsCellWidthPx = allAppsIconSizePx + 2 * allAppsIconDrawablePaddingPx;
- }
updateWorkspacePadding();
// This is done last, after iconSizePx is calculated above.
@@ -259,8 +241,8 @@
public DeviceProfile copy(Context context) {
Point size = new Point(availableWidthPx, availableHeightPx);
- return new DeviceProfile(context, inv, originalIdp, size, size, widthPx, heightPx,
- isLandscape, isMultiWindowMode);
+ return new DeviceProfile(context, inv, size, size, widthPx, heightPx, isLandscape,
+ isMultiWindowMode);
}
public DeviceProfile getMultiWindowProfile(Context context, Point mwSize) {
@@ -271,8 +253,8 @@
// In multi-window mode, we can have widthPx = availableWidthPx
// and heightPx = availableHeightPx because Launcher uses the InvariantDeviceProfiles'
// widthPx and heightPx values where it's needed.
- DeviceProfile profile = new DeviceProfile(context, inv, null, mwSize, mwSize,
- mwSize.x, mwSize.y, isLandscape, true);
+ DeviceProfile profile = new DeviceProfile(context, inv, mwSize, mwSize, mwSize.x, mwSize.y,
+ isLandscape, true);
// If there isn't enough vertical cell padding with the labels displayed, hide the labels.
float workspaceCellPaddingY = profile.getCellSize().y - profile.iconSizePx
@@ -356,11 +338,19 @@
}
cellWidthPx = iconSizePx + iconDrawablePaddingPx;
- allAppsIconSizePx = iconSizePx;
- allAppsIconTextSizePx = iconTextSizePx;
- allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
- allAppsCellHeightPx = getCellSize().y;
- allAppsCellWidthPx = allAppsIconSizePx + 2 * allAppsIconDrawablePaddingPx;
+ // All apps
+ if (allAppsHasDifferentNumColumns()) {
+ allAppsIconSizePx = ResourceUtils.pxFromDp(inv.allAppsIconSize, dm);
+ allAppsIconTextSizePx = Utilities.pxFromSp(inv.allAppsIconTextSize, dm);
+ allAppsCellHeightPx = getCellSize(inv.numAllAppsColumns, inv.numAllAppsColumns).y;
+ allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
+ } else {
+ allAppsIconSizePx = iconSizePx;
+ allAppsIconTextSizePx = iconTextSizePx;
+ allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
+ allAppsCellHeightPx = getCellSize().y;
+ }
+ allAppsCellWidthPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx;
if (isVerticalBarLayout()) {
// Always hide the Workspace text with vertical bar layout.
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 7414a88..d2d0863 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -47,7 +47,6 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.graphics.IconShape;
-import com.android.launcher3.graphics.LauncherPreviewRenderer;
import com.android.launcher3.util.ConfigMonitor;
import com.android.launcher3.util.DefaultDisplay;
import com.android.launcher3.util.DefaultDisplay.Info;
@@ -61,7 +60,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Comparator;
public class InvariantDeviceProfile {
@@ -107,6 +105,8 @@
public int iconBitmapSize;
public int fillResIconDpi;
public float iconTextSize;
+ public float allAppsIconSize;
+ public float allAppsIconTextSize;
private SparseArray<TypedValue> mExtraAttrs;
@@ -149,6 +149,8 @@
numHotseatIcons = p.numHotseatIcons;
numAllAppsColumns = p.numAllAppsColumns;
dbFile = p.dbFile;
+ allAppsIconSize = p.allAppsIconSize;
+ allAppsIconTextSize = p.allAppsIconTextSize;
defaultLayoutId = p.defaultLayoutId;
demoModeLayoutId = p.demoModeLayoutId;
mExtraAttrs = p.mExtraAttrs;
@@ -157,12 +159,9 @@
@TargetApi(23)
private InvariantDeviceProfile(Context context) {
- if (context instanceof LauncherPreviewRenderer.PreviewContext) {
- throw new IllegalArgumentException(
- "PreviewContext is passed into this IDP constructor");
- }
-
- String gridName = getCurrentGridName(context);
+ String gridName = Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)
+ ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null)
+ : null;
initGrid(context, gridName);
mConfigMonitor = new ConfigMonitor(context,
APPLY_CONFIG_AT_RUNTIME.get() ? this::onConfigChanged : this::killProcess);
@@ -179,7 +178,7 @@
}
}
- /**
+/**
* This constructor should NOT have any monitors by design.
*/
public InvariantDeviceProfile(Context context, Display display) {
@@ -211,11 +210,55 @@
Point smallestSize = new Point(displayInfo.smallestSize);
Point largestSize = new Point(displayInfo.largestSize);
+ ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
// This guarantees that width < height
float minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y),
displayInfo.metrics);
float minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y),
displayInfo.metrics);
+ // Sort the profiles based on the closeness to the device size
+ Collections.sort(allOptions, (a, b) ->
+ Float.compare(dist(minWidthDps, minHeightDps, a.minWidthDps, a.minHeightDps),
+ dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps)));
+ DisplayOption interpolatedDisplayOption =
+ invDistWeightedInterpolate(minWidthDps, minHeightDps, allOptions);
+
+ GridOption closestProfile = allOptions.get(0).grid;
+ numRows = closestProfile.numRows;
+ numColumns = closestProfile.numColumns;
+ numHotseatIcons = closestProfile.numHotseatIcons;
+ dbFile = closestProfile.dbFile;
+ defaultLayoutId = closestProfile.defaultLayoutId;
+ demoModeLayoutId = closestProfile.demoModeLayoutId;
+ numFolderRows = closestProfile.numFolderRows;
+ numFolderColumns = closestProfile.numFolderColumns;
+ numAllAppsColumns = closestProfile.numAllAppsColumns;
+
+ mExtraAttrs = closestProfile.extraAttrs;
+
+ if (!closestProfile.name.equals(gridName)) {
+ Utilities.getPrefs(context).edit()
+ .putString(KEY_IDP_GRID_NAME, closestProfile.name).apply();
+ }
+
+ iconSize = interpolatedDisplayOption.iconSize;
+ iconShapePath = getIconShapePath(context);
+ landscapeIconSize = interpolatedDisplayOption.landscapeIconSize;
+ iconBitmapSize = ResourceUtils.pxFromDp(iconSize, displayInfo.metrics);
+ iconTextSize = interpolatedDisplayOption.iconTextSize;
+ fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
+
+ if (Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)) {
+ allAppsIconSize = interpolatedDisplayOption.allAppsIconSize;
+ allAppsIconTextSize = interpolatedDisplayOption.allAppsIconTextSize;
+ } else {
+ allAppsIconSize = iconSize;
+ allAppsIconTextSize = iconTextSize;
+ }
+
+ // If the partner customization apk contains any grid overrides, apply them
+ // Supported overrides: numRows, numColumns, iconSize
+ applyPartnerDeviceProfileOverrides(context, displayInfo.metrics);
Point realSize = new Point(displayInfo.realSize);
// The real size never changes. smallSide and largeSide will remain the
@@ -223,64 +266,10 @@
int smallSide = Math.min(realSize.x, realSize.y);
int largeSide = Math.max(realSize.x, realSize.y);
- // We want a list of all options as well as the list of filtered options. This allows us
- // to have a consistent UI for areas that the grid size change should not affect
- // ie. All Apps should be consistent between grid sizes.
- ArrayList<DisplayOption> allOptions = new ArrayList<>();
- ArrayList<DisplayOption> filteredOptions = new ArrayList<>();
- getPredefinedDeviceProfiles(context, gridName, filteredOptions, allOptions);
-
- if (allOptions.isEmpty() && filteredOptions.isEmpty()) {
- throw new RuntimeException("No display option with canBeDefault=true");
- }
-
- // Sort the profiles based on the closeness to the device size
- Comparator<DisplayOption> comparator = (a, b) -> Float.compare(dist(minWidthDps,
- minHeightDps, a.minWidthDps, a.minHeightDps),
- dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps));
-
- // Calculate the device profiles as if there is no grid override.
- Collections.sort(allOptions, comparator);
- DisplayOption interpolatedDisplayOption =
- invDistWeightedInterpolate(minWidthDps, minHeightDps, allOptions);
- initGridOption(context, allOptions, interpolatedDisplayOption, displayInfo.metrics);
-
- // Create IDP with no grid override values.
- InvariantDeviceProfile originalIDP = new InvariantDeviceProfile(this);
- originalIDP.landscapeProfile = new DeviceProfile(context, this, null, smallestSize,
- largestSize, largeSide, smallSide, true /* isLandscape */,
- false /* isMultiWindowMode */);
- originalIDP.portraitProfile = new DeviceProfile(context, this, null, smallestSize,
- largestSize, smallSide, largeSide, false /* isLandscape */,
- false /* isMultiWindowMode */);
-
- if (filteredOptions.isEmpty()) {
- filteredOptions = allOptions;
-
- landscapeProfile = originalIDP.landscapeProfile;
- portraitProfile = originalIDP.portraitProfile;
- } else {
- Collections.sort(filteredOptions, comparator);
- interpolatedDisplayOption =
- invDistWeightedInterpolate(minWidthDps, minHeightDps, filteredOptions);
-
- initGridOption(context, filteredOptions, interpolatedDisplayOption,
- displayInfo.metrics);
- numAllAppsColumns = originalIDP.numAllAppsColumns;
-
- landscapeProfile = new DeviceProfile(context, this, originalIDP, smallestSize,
- largestSize, largeSide, smallSide, true /* isLandscape */,
- false /* isMultiWindowMode */);
- portraitProfile = new DeviceProfile(context, this, originalIDP, smallestSize,
- largestSize, smallSide, largeSide, false /* isLandscape */,
- false /* isMultiWindowMode */);
- }
-
- GridOption closestProfile = filteredOptions.get(0).grid;
- if (!closestProfile.name.equals(gridName)) {
- Utilities.getPrefs(context).edit()
- .putString(KEY_IDP_GRID_NAME, closestProfile.name).apply();
- }
+ landscapeProfile = new DeviceProfile(context, this, smallestSize, largestSize,
+ largeSide, smallSide, true /* isLandscape */, false /* isMultiWindowMode */);
+ portraitProfile = new DeviceProfile(context, this, smallestSize, largestSize,
+ smallSide, largeSide, false /* isLandscape */, false /* isMultiWindowMode */);
// We need to ensure that there is enough extra space in the wallpaper
// for the intended parallax effects
@@ -298,34 +287,6 @@
return closestProfile.name;
}
- private void initGridOption(Context context, ArrayList<DisplayOption> options,
- DisplayOption displayOption, DisplayMetrics metrics) {
- GridOption closestProfile = options.get(0).grid;
- numRows = closestProfile.numRows;
- numColumns = closestProfile.numColumns;
- numHotseatIcons = closestProfile.numHotseatIcons;
- dbFile = closestProfile.dbFile;
- defaultLayoutId = closestProfile.defaultLayoutId;
- demoModeLayoutId = closestProfile.demoModeLayoutId;
- numFolderRows = closestProfile.numFolderRows;
- numFolderColumns = closestProfile.numFolderColumns;
- numAllAppsColumns = numColumns;
-
- mExtraAttrs = closestProfile.extraAttrs;
-
- iconSize = displayOption.iconSize;
- iconShapePath = getIconShapePath(context);
- landscapeIconSize = displayOption.landscapeIconSize;
- iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
- iconTextSize = displayOption.iconTextSize;
- fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
-
- // If the partner customization apk contains any grid overrides, apply them
- // Supported overrides: numRows, numColumns, iconSize
- applyPartnerDeviceProfileOverrides(context, metrics);
- }
-
-
@Nullable
public TypedValue getAttrValue(int attr) {
return mExtraAttrs == null ? null : mExtraAttrs.get(attr);
@@ -403,13 +364,7 @@
}
}
- /**
- * @param gridName The current grid name.
- * @param filteredOptionsOut List filled with all the filtered options based on gridName.
- * @param allOptionsOut List filled with all the options that can be the default option.
- */
- static void getPredefinedDeviceProfiles(Context context, String gridName,
- ArrayList<DisplayOption> filteredOptionsOut, ArrayList<DisplayOption> allOptionsOut) {
+ static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) {
ArrayList<DisplayOption> profiles = new ArrayList<>();
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
final int depth = parser.getDepth();
@@ -436,19 +391,26 @@
throw new RuntimeException(e);
}
+ ArrayList<DisplayOption> filteredProfiles = new ArrayList<>();
if (!TextUtils.isEmpty(gridName)) {
for (DisplayOption option : profiles) {
if (gridName.equals(option.grid.name)) {
- filteredOptionsOut.add(option);
+ filteredProfiles.add(option);
}
}
}
-
- for (DisplayOption option : profiles) {
- if (option.canBeDefault) {
- allOptionsOut.add(option);
+ if (filteredProfiles.isEmpty()) {
+ // No grid found, use the default options
+ for (DisplayOption option : profiles) {
+ if (option.canBeDefault) {
+ filteredProfiles.add(option);
+ }
}
}
+ if (filteredProfiles.isEmpty()) {
+ throw new RuntimeException("No display option with canBeDefault=true");
+ }
+ return filteredProfiles;
}
private int getLauncherIconDensity(int requiredSize) {
@@ -493,7 +455,7 @@
@VisibleForTesting
static DisplayOption invDistWeightedInterpolate(float width, float height,
- ArrayList<DisplayOption> points) {
+ ArrayList<DisplayOption> points) {
float weights = 0;
DisplayOption p = points.get(0);
@@ -573,6 +535,8 @@
private final int numHotseatIcons;
private final String dbFile;
+ private final int numAllAppsColumns;
+
private final int defaultLayoutId;
private final int demoModeLayoutId;
@@ -596,6 +560,8 @@
R.styleable.GridDisplayOption_numFolderRows, numRows);
numFolderColumns = a.getInt(
R.styleable.GridDisplayOption_numFolderColumns, numColumns);
+ numAllAppsColumns = a.getInt(
+ R.styleable.GridDisplayOption_numAllAppsColumns, numColumns);
a.recycle();
@@ -615,6 +581,8 @@
private float iconSize;
private float iconTextSize;
private float landscapeIconSize;
+ private float allAppsIconSize;
+ private float allAppsIconTextSize;
DisplayOption(GridOption grid, Context context, AttributeSet attrs) {
this.grid = grid;
@@ -633,6 +601,10 @@
iconSize);
iconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0);
+ allAppsIconSize = a.getFloat(R.styleable.ProfileDisplayOption_allAppsIconSize,
+ iconSize);
+ allAppsIconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_allAppsIconTextSize,
+ iconTextSize);
a.recycle();
}
@@ -647,14 +619,18 @@
private DisplayOption multiply(float w) {
iconSize *= w;
landscapeIconSize *= w;
+ allAppsIconSize *= w;
iconTextSize *= w;
+ allAppsIconTextSize *= w;
return this;
}
private DisplayOption add(DisplayOption p) {
iconSize += p.iconSize;
landscapeIconSize += p.landscapeIconSize;
+ allAppsIconSize += p.allAppsIconSize;
iconTextSize += p.iconTextSize;
+ allAppsIconTextSize += p.allAppsIconTextSize;
return this;
}
}
@@ -672,4 +648,4 @@
onConfigChanged(context);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
index 2515c24..2de425e 100644
--- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
@@ -135,8 +135,8 @@
@Override
public void setActiveMarker(int activePage) {
updateTabTextColor(activePage);
- updateIndicatorPosition(activePage);
if (mContainerView != null && mLastActivePage != activePage) {
+ updateIndicatorPosition(activePage);
mContainerView.onTabChanged(activePage);
}
mLastActivePage = activePage;
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index c1621b0..33262b6 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -25,6 +25,8 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
import android.widget.Switch;
import com.android.launcher3.Insettable;
@@ -46,16 +48,28 @@
private Rect mInsets = new Rect();
+ private final float[] mTouch = new float[2];
+ private int mTouchSlop;
+
public WorkModeSwitch(Context context) {
super(context);
+ init();
}
public WorkModeSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
+ init();
+
}
public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
+ mTouchSlop = viewConfiguration.getScaledTouchSlop();
}
@Override
@@ -84,6 +98,25 @@
setEnabled(true);
}
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ mTouch[0] = ev.getX();
+ mTouch[1] = ev.getY();
+ } else if (ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ if (Math.abs(mTouch[0] - ev.getX()) > mTouchSlop
+ || Math.abs(mTouch[1] - ev.getY()) > mTouchSlop) {
+ int action = ev.getAction();
+ ev.setAction(MotionEvent.ACTION_CANCEL);
+ super.onTouchEvent(ev);
+ ev.setAction(action);
+ return false;
+ }
+ }
+ return super.onTouchEvent(ev);
+ }
+
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 96ddd57..32531c0 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -153,6 +153,7 @@
CellLayout page = (CellLayout) getChildAt(i);
ShortcutAndWidgetContainer container = page.getShortcutsAndWidgets();
for (int j = container.getChildCount() - 1; j >= 0; j--) {
+ container.getChildAt(j).setVisibility(View.VISIBLE);
mViewCache.recycleView(R.layout.folder_application, container.getChildAt(j));
}
page.removeAllViews();
diff --git a/src/com/android/launcher3/logging/LauncherUiEvent.java b/src/com/android/launcher3/logging/LauncherUiEvent.java
deleted file mode 100644
index 4507ff7..0000000
--- a/src/com/android/launcher3/logging/LauncherUiEvent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.logging;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Retention(SOURCE)
-@Target(FIELD)
-public @interface LauncherUiEvent {
- /** An explanation, suitable for Android analysts, of the UI event that this log represents. */
- String doc();
-}
-
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 2829951..60d790f 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -17,6 +17,8 @@
import android.content.Context;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
import com.android.launcher3.R;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logger.LauncherAtom.ItemInfo;
@@ -28,19 +30,15 @@
*/
public class StatsLogManager implements ResourceBasedOverride {
- interface EventEnum {
- int getId();
- }
-
- public enum LauncherEvent implements EventEnum {
- @LauncherUiEvent(doc = "App launched from workspace, hotseat or folder in launcher")
- APP_LAUNCH_TAP(1),
- @LauncherUiEvent(doc = "Task launched from overview using TAP")
- TASK_LAUNCH_TAP(2),
- @LauncherUiEvent(doc = "Task launched from overview using SWIPE DOWN")
- TASK_LAUNCH_SWIPE_DOWN(2),
- @LauncherUiEvent(doc = "TASK dismissed from overview using SWIPE UP")
- TASK_DISMISS_SWIPE_UP(3);
+ public enum LauncherEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "App launched from workspace, hotseat or folder in launcher")
+ LAUNCHER_APP_LAUNCH_TAP(338),
+ @UiEvent(doc = "Task launched from overview using TAP")
+ LAUNCHER_TASK_LAUNCH_TAP(339),
+ @UiEvent(doc = "Task launched from overview using SWIPE DOWN")
+ LAUNCHER_TASK_LAUNCH_SWIPE_DOWN(340),
+ @UiEvent(doc = "TASK dismissed from overview using SWIPE UP")
+ LAUNCHER_TASK_DISMISS_SWIPE_UP(341);
// ADD MORE
private final int mId;