Merge "Fix qsb when flinging to home during gesture to overview from home" into ub-launcher3-rvc-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
index f881610..0113570 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/appprediction/PredictionUiStateManager.java
@@ -18,12 +18,12 @@
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALL_APPS_RANKED;
import android.app.prediction.AppPredictor;
import android.app.prediction.AppTarget;
import android.content.ComponentName;
import android.content.Context;
-import android.os.Process;
import androidx.annotation.NonNull;
@@ -36,9 +36,10 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsStore.OnUpdateListener;
-import com.android.launcher3.hybridhotseat.HotseatFileLog;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
+import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.shortcuts.ShortcutKey;
@@ -50,6 +51,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.OptionalInt;
import java.util.stream.IntStream;
/**
@@ -304,6 +306,41 @@
}
/**
+ * Logs ranking info for launched app within all apps prediction.
+ * Only applicable when {@link ItemInfo#itemType} is one of the followings:
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
+ * {@link LauncherSettings.Favorites#ITEM_TYPE_DEEP_SHORTCUT}
+ */
+ public void logLaunchedAppRankingInfo(@NonNull ItemInfo itemInfo, InstanceId instanceId) {
+ if (itemInfo.getTargetComponent() == null || itemInfo.user == null
+ || (itemInfo.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+ && itemInfo.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
+ && itemInfo.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)) {
+ return;
+ }
+
+ Launcher launcher = Launcher.getLauncher(mAppsView.getContext());
+ final ComponentKey k = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user);
+ final List<ComponentKeyMapper> predictedApps = getCurrentState().apps;
+ OptionalInt rank = IntStream.range(0, predictedApps.size())
+ .filter((i) -> k.equals(predictedApps.get(i).getComponentKey()))
+ .findFirst();
+ if (!rank.isPresent()) {
+ return;
+ }
+
+ LauncherAtom.ItemInfo.Builder atomBuilder = LauncherAtom.ItemInfo.newBuilder();
+ atomBuilder.setRank(rank.getAsInt());
+ atomBuilder.setContainerInfo(
+ LauncherAtom.ContainerInfo.newBuilder().setPredictionContainer(
+ LauncherAtom.PredictionContainer.newBuilder().build()).build());
+ launcher.getStatsLogManager().log(LAUNCHER_ALL_APPS_RANKED, instanceId,
+ atomBuilder.build());
+ }
+
+
+ /**
* Fill in predicted_rank field based on app prediction.
* Only applicable when {@link ItemInfo#itemType} is one of the followings:
* {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
@@ -313,17 +350,6 @@
public static void fillInPredictedRank(
@NonNull ItemInfo itemInfo, @NonNull LauncherLogProto.Target target) {
- HotseatFileLog hotseatFileLog = HotseatFileLog.INSTANCE.getNoCreate();
-
- if (hotseatFileLog != null && itemInfo != null && Utilities.IS_DEBUG_DEVICE) {
- final String pkg = itemInfo.getTargetComponent() != null
- ? itemInfo.getTargetComponent().getPackageName() : "unknown";
- hotseatFileLog.log("UserEvent",
- "appLaunch: packageName:" + pkg + ",isWorkApp:" + (itemInfo.user != null
- && !Process.myUserHandle().equals(itemInfo.user))
- + ",launchLocation:" + itemInfo.container);
- }
-
final PredictionUiStateManager manager = PredictionUiStateManager.INSTANCE.getNoCreate();
if (manager == null || itemInfo.getTargetComponent() == null || itemInfo.user == null
|| (itemInfo.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
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 6ca07bb..30a34e4 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
@@ -18,6 +18,7 @@
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.hybridhotseat.HotseatEduController.SETTINGS_ACTION;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_RANKED;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -29,6 +30,7 @@
import android.app.prediction.AppTargetEvent;
import android.content.ComponentName;
import android.content.Intent;
+import android.os.Process;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -52,6 +54,8 @@
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
@@ -185,7 +189,6 @@
/**
* Returns if hotseat client has predictions
- * @return
*/
public boolean hasPredictions() {
return !mComponentKeyMappers.isEmpty();
@@ -358,6 +361,7 @@
updateDependencies();
bindItems(items, false, null);
}
+
private void setPredictedApps(List<AppTarget> appTargets) {
mComponentKeyMappers.clear();
if (appTargets.isEmpty()) {
@@ -635,6 +639,48 @@
mHotseat.fillInLogContainerData(childInfo, child, parents);
}
+ /**
+ * Logs rank info based on current list of predicted items
+ */
+ public void logLaunchedAppRankingInfo(@NonNull ItemInfo itemInfo, InstanceId instanceId) {
+ if (Utilities.IS_DEBUG_DEVICE) {
+ final String pkg = itemInfo.getTargetComponent() != null
+ ? itemInfo.getTargetComponent().getPackageName() : "unknown";
+ HotseatFileLog.INSTANCE.get(mLauncher).log("UserEvent",
+ "appLaunch: packageName:" + pkg + ",isWorkApp:" + (itemInfo.user != null
+ && !Process.myUserHandle().equals(itemInfo.user))
+ + ",launchLocation:" + itemInfo.container);
+ }
+
+ final ComponentKey k = new ComponentKey(itemInfo.getTargetComponent(), itemInfo.user);
+
+ final List<ComponentKeyMapper> predictedApps = new ArrayList<>(mComponentKeyMappers);
+ OptionalInt rank = IntStream.range(0, predictedApps.size())
+ .filter((i) -> k.equals(predictedApps.get(i).getComponentKey()))
+ .findFirst();
+ if (!rank.isPresent()) {
+ return;
+ }
+ LauncherAtom.PredictedHotseatContainer.Builder containerBuilder =
+ LauncherAtom.PredictedHotseatContainer.newBuilder();
+ LauncherAtom.ItemInfo.Builder atomBuilder = LauncherAtom.ItemInfo.newBuilder();
+ int cardinality = 0;
+ for (PredictedAppIcon icon : getPredictedIcons()) {
+ ItemInfo info = (ItemInfo) icon.getTag();
+ cardinality |= 1 << info.screenId;
+ }
+ containerBuilder.setCardinality(cardinality);
+ atomBuilder.setRank(rank.getAsInt());
+ if (itemInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) {
+ containerBuilder.setIndex(rank.getAsInt());
+ }
+ atomBuilder.setContainerInfo(
+ LauncherAtom.ContainerInfo.newBuilder().setPredictedHotseatContainer(
+ containerBuilder).build());
+ mLauncher.getStatsLogManager().log(LAUNCHER_HOTSEAT_RANKED, instanceId,
+ atomBuilder.build());
+ }
+
private class PinPrediction extends SystemShortcut<QuickstepLauncher> {
private PinPrediction(QuickstepLauncher target, ItemInfo itemInfo) {
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 77d71a3..0e690eb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -29,6 +29,7 @@
import android.content.Intent;
import android.content.res.Configuration;
+import android.os.Bundle;
import android.util.Log;
import android.view.View;
@@ -41,10 +42,12 @@
import com.android.launcher3.Workspace;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.appprediction.PredictionUiStateManager;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.hybridhotseat.HotseatEduController;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
+import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -89,11 +92,18 @@
SystemUiProxy.INSTANCE.get(context).setShelfHeight(arg1 != 0, arg2);
@Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (mHotseatPredictionController != null) {
+ mHotseatPredictionController.createPredictor();
+ }
+ }
+
+ @Override
protected void setupViews() {
super.setupViews();
if (FeatureFlags.ENABLE_HYBRID_HOTSEAT.get()) {
mHotseatPredictionController = new HotseatPredictionController(this);
- mHotseatPredictionController.createPredictor();
}
}
@@ -112,6 +122,15 @@
}
@Override
+ protected void logAppLaunch(ItemInfo info, InstanceId instanceId) {
+ super.logAppLaunch(info, instanceId);
+ if (mHotseatPredictionController != null) {
+ mHotseatPredictionController.logLaunchedAppRankingInfo(info, instanceId);
+ }
+ PredictionUiStateManager.INSTANCE.get(this).logLaunchedAppRankingInfo(info, instanceId);
+ }
+
+ @Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
onStateOrResumeChanging(false /* inTransition */);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 11fee2f..32b1c58 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -36,8 +36,6 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
-import java.util.function.Predicate;
-
/**
* Input consumer for handling touch on the recents/Launcher activity.
*/
@@ -50,8 +48,6 @@
private final InputMonitorCompat mInputMonitor;
private final int[] mLocationOnScreen = new int[2];
- private final boolean mProxyTouch;
- private final Predicate<MotionEvent> mEventReceiver;
private final boolean mStartingInActivityBounds;
private boolean mTargetHandledTouch;
@@ -64,15 +60,7 @@
mActivityInterface = gestureState.getActivityInterface();
mTarget = activity.getDragLayer();
- if (startingInActivityBounds) {
- mEventReceiver = mTarget::dispatchTouchEvent;
- mProxyTouch = true;
- } else {
- // Only proxy touches to controllers if we are starting touch from nav bar.
- mEventReceiver = mTarget::proxyTouchEvent;
- mTarget.getLocationOnScreen(mLocationOnScreen);
- mProxyTouch = mTarget.prepareProxyEventStarting();
- }
+ mTarget.getLocationOnScreen(mLocationOnScreen);
}
@Override
@@ -87,10 +75,6 @@
@Override
public void onMotionEvent(MotionEvent ev) {
- if (!mProxyTouch) {
- return;
- }
-
int flags = ev.getEdgeFlags();
if (!mStartingInActivityBounds) {
ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
@@ -99,7 +83,7 @@
if (TestProtocol.sDebugTracing) {
Log.d(TestProtocol.PAUSE_NOT_DETECTED, "OverviewInputConsumer");
}
- boolean handled = mEventReceiver.test(ev);
+ boolean handled = mTarget.proxyTouchEvent(ev, mStartingInActivityBounds);
ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
ev.setEdgeFlags(flags);
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 873c672..2066d52 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
@@ -2111,6 +2111,12 @@
return mClearAllButton;
}
+ @Override
+ protected boolean onOverscroll(int amount) {
+ // overscroll should only be accepted on -1 direction (for clear all button)
+ if ((amount > 0 && !mIsRtl) || (amount < 0 && mIsRtl)) return false;
+ return super.onOverscroll(amount);
+ }
/**
* @return How many pixels the running task is offset on the currently laid out dominant axis.
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 3b1210e..f2e4127 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
@@ -975,6 +975,9 @@
}
void updateCurrentFullscreenParams(PreviewPositionHelper previewPositionHelper) {
+ if (getRecentsView() == null) {
+ return;
+ }
mCurrentFullscreenParams.setProgress(
mFullscreenProgress,
getRecentsView().getScaleX(),
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index ebb44e2..e820b3f 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -78,7 +78,7 @@
*/
@Override
public void log(EventEnum event) {
- log(event, DEFAULT_INSTANCE_ID, null);
+ log(event, DEFAULT_INSTANCE_ID, (ItemInfo) null);
}
/**
@@ -86,7 +86,7 @@
*/
@Override
public void log(EventEnum event, InstanceId instanceId) {
- log(event, instanceId, null);
+ log(event, instanceId, (ItemInfo) null);
}
/**
@@ -101,6 +101,25 @@
* Logs an event.
*
* @param event an enum implementing EventEnum interface.
+ * @param atomInfo item typically containing app or task launch related information.
+ */
+ public void log(EventEnum event, InstanceId instanceId, LauncherAtom.ItemInfo atomInfo) {
+ LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
+ new BaseModelUpdateTask() {
+ @Override
+ public void execute(LauncherAppState app, BgDataModel dataModel,
+ AllAppsList apps) {
+ write(event, instanceId, atomInfo, null,
+ LAUNCHER_UICHANGED__DST_STATE__HOME,
+ LAUNCHER_UICHANGED__DST_STATE__BACKGROUND);
+ }
+ });
+ }
+
+ /**
+ * Logs an event.
+ *
+ * @param event an enum implementing EventEnum interface.
* @param atomItemInfo item typically containing app or task launch related information.
*/
@Override
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index bec3050..19e278b 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -244,13 +244,17 @@
@Override
protected void updateSysUiColors() {
- // Use a light system UI (dark icons) if all apps is behind at least half of the
- // status bar.
- boolean forceChange = mShelfTop <= mLauncher.getDeviceProfile().getInsets().top / 2f;
- if (forceChange) {
- mLauncher.getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, !mIsScrimDark);
+ if (mDrawingFlatColor) {
+ super.updateSysUiColors();
} else {
- mLauncher.getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, 0);
+ // Use a light system UI (dark icons) if all apps is behind at least half of the
+ // status bar.
+ boolean forceChange = mShelfTop <= mLauncher.getDeviceProfile().getInsets().top / 2f;
+ if (forceChange) {
+ mLauncher.getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, !mIsScrimDark);
+ } else {
+ mLauncher.getSystemUiController().updateUiState(UI_STATE_SCRIM_VIEW, 0);
+ }
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index a343e7c..ffe55b6 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -120,6 +120,8 @@
TestCommandReceiver.callCommand(TestCommandReceiver.DISABLE_TEST_LAUNCHER);
UiDevice.getInstance(getInstrumentation()).executeShellCommand(
getLauncherCommand(getLauncherInMyProcess()));
+ // b/143488140
+ mLauncher.pressHome();
}
}
};
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a922183..ac00488 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -50,7 +50,7 @@
<item name="folderFillColor">#CDFFFFFF</item>
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
<item name="folderTextColor">#FF212121</item>
- <item name="folderHintColor">#FF616161</item>
+ <item name="folderHintColor">#89616161</item>
<item name="loadingIconColor">#CCFFFFFF</item>
<item name="iconOnlyShortcutColor">?android:attr/textColorSecondary</item>
<item name="workProfileOverlayTextColor">#FF212121</item>
@@ -106,7 +106,7 @@
<item name="folderFillColor">#DD3C4043</item> <!-- 87% GM2 800 -->
<item name="folderIconBorderColor">#FF80868B</item>
<item name="folderTextColor">@android:color/white</item>
- <item name="folderHintColor">#FFCCCCCC</item>
+ <item name="folderHintColor">#89CCCCCC</item>
<item name="isMainColorDark">true</item>
<item name="loadingIconColor">#99FFFFFF</item>
<item name="iconOnlyShortcutColor">#B3FFFFFF</item>
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 88dbfd6..61ecdd7 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -43,6 +43,8 @@
import androidx.annotation.Nullable;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.AppLaunchTracker;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -188,7 +190,8 @@
}
getUserEventDispatcher().logAppLaunch(v, intent, user);
if (item != null) {
- getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, item);
+ InstanceId instanceId = new InstanceIdSequence().newInstanceId();
+ logAppLaunch(item, instanceId);
}
return true;
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
@@ -198,6 +201,10 @@
return false;
}
+ protected void logAppLaunch(ItemInfo info, InstanceId instanceId) {
+ getStatsLogManager().log(LAUNCHER_APP_LAUNCH_TAP, instanceId, info);
+ }
+
private void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info,
@Nullable String sourceContainer) {
try {
diff --git a/src/com/android/launcher3/folder/FolderNameEditText.java b/src/com/android/launcher3/folder/FolderNameEditText.java
index edf2c70..6038a05 100644
--- a/src/com/android/launcher3/folder/FolderNameEditText.java
+++ b/src/com/android/launcher3/folder/FolderNameEditText.java
@@ -70,8 +70,11 @@
for (int i = 0; i < cnt; i++) {
cInfo[i] = new CompletionInfo(i, i, suggestList.get(i));
}
- post(() -> getContext().getSystemService(InputMethodManager.class)
- .displayCompletions(this, cInfo));
+ // post it to future frame so that onSelectionChanged, onFocusChanged, all other
+ // TextView flag change and IME animation has settled. Ideally, there should be IMM
+ // callback to notify when the IME animation and state handling is finished.
+ postDelayed(() -> getContext().getSystemService(InputMethodManager.class)
+ .displayCompletions(this, cInfo), 40 /* 2~3 frame delay */);
}
/**
diff --git a/src/com/android/launcher3/logging/InstanceIdSequence.java b/src/com/android/launcher3/logging/InstanceIdSequence.java
index a4b7953..ee6a5a4 100644
--- a/src/com/android/launcher3/logging/InstanceIdSequence.java
+++ b/src/com/android/launcher3/logging/InstanceIdSequence.java
@@ -45,6 +45,13 @@
}
/**
+ * Constructs a sequence with identifiers [1, InstanceId.INSTANCE_ID_MAX].
+ */
+ public InstanceIdSequence() {
+ this(InstanceId.INSTANCE_ID_MAX);
+ }
+
+ /**
* Gets the next instance from the sequence. Safe for concurrent use.
* @return new InstanceId
*/
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index fee91b0..c84b9fe 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -143,7 +143,13 @@
LAUNCHER_HOTSEAT_EDU_DENY(481),
@UiEvent(doc = "Hotseat education tip shown")
- LAUNCHER_HOTSEAT_EDU_ONLY_TIP(482);
+ LAUNCHER_HOTSEAT_EDU_ONLY_TIP(482),
+
+ @UiEvent(doc = "App launch ranking logged for all apps predictions")
+ LAUNCHER_ALL_APPS_RANKED(552),
+
+ @UiEvent(doc = "App launch ranking logged for hotseat predictions)")
+ LAUNCHER_HOTSEAT_RANKED(553);
// ADD MORE
private final int mId;
@@ -218,6 +224,15 @@
}
/**
+ * Logs an event.
+ *
+ * @param event an enum implementing EventEnum interface.
+ * @param atomInfo item typically containing app or task launch related information.
+ */
+ public void log(EventEnum event, InstanceId instanceId, LauncherAtom.ItemInfo atomInfo) {
+ }
+
+ /**
* Logs an event and accompanying {@link LauncherState}s.
*
* @param event an enum implementing EventEnum interface.
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index f54edc2..b010b4b 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -90,13 +90,23 @@
}
};
- // Touch is being dispatched through the normal view dispatch system
- private static final int TOUCH_DISPATCHING_VIEW = 1 << 0;
+ // Touch coming from normal view system is being dispatched.
+ private static final int TOUCH_DISPATCHING_FROM_VIEW = 1 << 0;
// Touch is being dispatched through the normal view dispatch system, and started at the
- // system gesture region
- private static final int TOUCH_DISPATCHING_GESTURE = 1 << 1;
- // Touch is being dispatched through a proxy from InputMonitor
- private static final int TOUCH_DISPATCHING_PROXY = 1 << 2;
+ // system gesture region. In this case we prevent internal gesture handling and only allow
+ // normal view event handling.
+ private static final int TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION = 1 << 1;
+ // Touch coming from InputMonitor proxy is being dispatched 'only to gestures'. Note that both
+ // this and view-system can be active at the same time where view-system would go to the views,
+ // and this would go to the gestures.
+ // Note that this is not set when events are coming from proxy, but going through full dispatch
+ // process (both views and gestures) to allow view-system to easily take over in case it
+ // comes later.
+ private static final int TOUCH_DISPATCHING_FROM_PROXY = 1 << 2;
+ // ACTION_DOWN has been dispatched to child views and ACTION_UP or ACTION_CANCEL is pending.
+ // Note that the event source can either be view-dispatching or proxy-dispatching based on if
+ // TOUCH_DISPATCHING_VIEW is present or not.
+ private static final int TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS = 1 << 3;
protected final float[] mTmpXY = new float[2];
protected final float[] mTmpRectPoints = new float[4];
@@ -204,7 +214,8 @@
protected boolean findActiveController(MotionEvent ev) {
mActiveController = null;
- if ((mTouchDispatchState & (TOUCH_DISPATCHING_GESTURE | TOUCH_DISPATCHING_PROXY)) == 0) {
+ if ((mTouchDispatchState & (TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION
+ | TOUCH_DISPATCHING_FROM_PROXY)) == 0) {
// Only look for controllers if we are not dispatching from gesture area and proxy is
// not active
mActiveController = findControllerToHandleTouch(ev);
@@ -283,19 +294,28 @@
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case ACTION_DOWN: {
- mTouchDispatchState |= TOUCH_DISPATCHING_VIEW;
+ if ((mTouchDispatchState & TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS) != 0) {
+ // Cancel the previous touch
+ int action = ev.getAction();
+ ev.setAction(ACTION_CANCEL);
+ super.dispatchTouchEvent(ev);
+ ev.setAction(action);
+ }
+ mTouchDispatchState |= TOUCH_DISPATCHING_FROM_VIEW
+ | TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;
if (isEventInLauncher(ev)) {
- mTouchDispatchState &= ~TOUCH_DISPATCHING_GESTURE;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION;
} else {
- mTouchDispatchState |= TOUCH_DISPATCHING_GESTURE;
+ mTouchDispatchState |= TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION;
}
break;
}
case ACTION_CANCEL:
case ACTION_UP:
- mTouchDispatchState &= ~TOUCH_DISPATCHING_GESTURE;
- mTouchDispatchState &= ~TOUCH_DISPATCHING_VIEW;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_VIEW_GESTURE_REGION;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_VIEW;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;
break;
}
super.dispatchTouchEvent(ev);
@@ -305,43 +325,53 @@
}
/**
- * Called before we are about to receive proxy events.
- *
- * @return false if we can't handle proxy at this time
- */
- public boolean prepareProxyEventStarting() {
- mProxyTouchController = null;
- if ((mTouchDispatchState & TOUCH_DISPATCHING_VIEW) != 0 && mActiveController != null) {
- // We are already dispatching using view system and have an active controller, we can't
- // handle another controller.
-
- // This flag was already cleared in proxy ACTION_UP or ACTION_CANCEL. Added here just
- // to be safe
- mTouchDispatchState &= ~TOUCH_DISPATCHING_PROXY;
- return false;
- }
-
- mTouchDispatchState |= TOUCH_DISPATCHING_PROXY;
- return true;
- }
-
- /**
* Proxies the touch events to the gesture handlers
*/
- public boolean proxyTouchEvent(MotionEvent ev) {
- boolean handled;
- if (mProxyTouchController != null) {
- handled = mProxyTouchController.onControllerTouchEvent(ev);
+ public boolean proxyTouchEvent(MotionEvent ev, boolean allowViewDispatch) {
+ int actionMasked = ev.getActionMasked();
+ boolean isViewDispatching = (mTouchDispatchState & TOUCH_DISPATCHING_FROM_VIEW) != 0;
+
+ // Only do view dispatch if another view-dispatching is not running, or we already started
+ // proxy-dispatching before. Note that view-dispatching can always take over the proxy
+ // dispatching at anytime, but not vice-versa.
+ allowViewDispatch = allowViewDispatch && !isViewDispatching
+ && (actionMasked == ACTION_DOWN
+ || ((mTouchDispatchState & TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS) != 0));
+
+ if (allowViewDispatch) {
+ mTouchDispatchState |= TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;
+ super.dispatchTouchEvent(ev);
+
+ if (actionMasked == ACTION_UP || actionMasked == ACTION_CANCEL) {
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_PROXY;
+ }
+ return true;
} else {
- mProxyTouchController = findControllerToHandleTouch(ev);
- handled = mProxyTouchController != null;
+ boolean handled;
+ if (mProxyTouchController != null) {
+ handled = mProxyTouchController.onControllerTouchEvent(ev);
+ } else {
+ if (actionMasked == ACTION_DOWN) {
+ if (isViewDispatching && mActiveController != null) {
+ // A controller is already active, we can't initiate our own controller
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_PROXY;
+ } else {
+ // We will control the handler via proxy
+ mTouchDispatchState |= TOUCH_DISPATCHING_FROM_PROXY;
+ }
+ }
+ if ((mTouchDispatchState & TOUCH_DISPATCHING_FROM_PROXY) != 0) {
+ mProxyTouchController = findControllerToHandleTouch(ev);
+ }
+ handled = mProxyTouchController != null;
+ }
+ if (actionMasked == ACTION_UP || actionMasked == ACTION_CANCEL) {
+ mProxyTouchController = null;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_FROM_PROXY;
+ }
+ return handled;
}
- int action = ev.getAction();
- if (action == ACTION_UP || action == ACTION_CANCEL) {
- mProxyTouchController = null;
- mTouchDispatchState &= ~TOUCH_DISPATCHING_PROXY;
- }
- return handled;
}
/**