Using StatsLog for notifyingAppPredictor
> Adding a listener in StartsLogManager for listening to events. This allows events to be directored to the predictor only if it is already running, instead of creating it. > Unifying the event format to be same as hotseat predictor Bug: 160748731 Change-Id: Ib00e6249ff642c030f00bcad5b748255e704d16a
This commit is contained in:
parent
2c0cdfb100
commit
852537fd98
|
@ -131,6 +131,7 @@ message Application {
|
||||||
// Legacy shortcuts and shortcuts handled by ShortcutManager
|
// Legacy shortcuts and shortcuts handled by ShortcutManager
|
||||||
message Shortcut {
|
message Shortcut {
|
||||||
optional string shortcut_name = 1;
|
optional string shortcut_name = 1;
|
||||||
|
optional string shortcut_id = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppWidgets handled by AppWidgetManager
|
// AppWidgets handled by AppWidgetManager
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
package com.android.launcher3.appprediction;
|
package com.android.launcher3.appprediction;
|
||||||
|
|
||||||
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
|
import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_GRID;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
|
||||||
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
|
||||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
|
@ -31,29 +37,38 @@ import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
import android.os.Process;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.AnyThread;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
import com.android.launcher3.InvariantDeviceProfile;
|
import com.android.launcher3.InvariantDeviceProfile;
|
||||||
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
|
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
|
||||||
|
import com.android.launcher3.logger.LauncherAtom;
|
||||||
|
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
|
||||||
|
import com.android.launcher3.logger.LauncherAtom.FolderContainer;
|
||||||
|
import com.android.launcher3.logger.LauncherAtom.HotseatContainer;
|
||||||
|
import com.android.launcher3.logger.LauncherAtom.WorkspaceContainer;
|
||||||
|
import com.android.launcher3.logging.StatsLogManager.EventEnum;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
import com.android.launcher3.model.AppLaunchTracker;
|
||||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
import com.android.launcher3.pm.UserCache;
|
||||||
import com.android.systemui.plugins.AppLaunchEventsPlugin;
|
import com.android.quickstep.logging.StatsLogCompatManager;
|
||||||
import com.android.systemui.plugins.PluginListener;
|
import com.android.quickstep.logging.StatsLogCompatManager.StatsLogConsumer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.Locale;
|
||||||
import java.util.List;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass of app tracker which publishes the data to the prediction engine and gets back results.
|
* Subclass of app tracker which publishes the data to the prediction engine and gets back results.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.Q)
|
@TargetApi(Build.VERSION_CODES.Q)
|
||||||
public class PredictionAppTracker extends AppLaunchTracker
|
public class PredictionAppTracker extends AppLaunchTracker implements StatsLogConsumer {
|
||||||
implements PluginListener<AppLaunchEventsPlugin> {
|
|
||||||
|
|
||||||
private static final String TAG = "PredictionAppTracker";
|
private static final String TAG = "PredictionAppTracker";
|
||||||
private static final boolean DBG = false;
|
private static final boolean DBG = false;
|
||||||
|
@ -65,7 +80,6 @@ public class PredictionAppTracker extends AppLaunchTracker
|
||||||
|
|
||||||
protected final Context mContext;
|
protected final Context mContext;
|
||||||
private final Handler mMessageHandler;
|
private final Handler mMessageHandler;
|
||||||
private final List<AppLaunchEventsPlugin> mAppLaunchEventsPluginsList;
|
|
||||||
|
|
||||||
// Accessed only on worker thread
|
// Accessed only on worker thread
|
||||||
private AppPredictor mHomeAppPredictor;
|
private AppPredictor mHomeAppPredictor;
|
||||||
|
@ -76,10 +90,6 @@ public class PredictionAppTracker extends AppLaunchTracker
|
||||||
InvariantDeviceProfile.INSTANCE.get(mContext).addOnChangeListener(this::onIdpChanged);
|
InvariantDeviceProfile.INSTANCE.get(mContext).addOnChangeListener(this::onIdpChanged);
|
||||||
|
|
||||||
mMessageHandler.sendEmptyMessage(MSG_INIT);
|
mMessageHandler.sendEmptyMessage(MSG_INIT);
|
||||||
|
|
||||||
mAppLaunchEventsPluginsList = new ArrayList<>();
|
|
||||||
PluginManagerWrapper.INSTANCE.get(context)
|
|
||||||
.addPluginListener(this, AppLaunchEventsPlugin.class, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
|
@ -96,6 +106,7 @@ public class PredictionAppTracker extends AppLaunchTracker
|
||||||
mHomeAppPredictor.destroy();
|
mHomeAppPredictor.destroy();
|
||||||
mHomeAppPredictor = null;
|
mHomeAppPredictor = null;
|
||||||
}
|
}
|
||||||
|
StatsLogCompatManager.LOGS_CONSUMER.remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
|
@ -137,6 +148,7 @@ public class PredictionAppTracker extends AppLaunchTracker
|
||||||
// Initialize the clients
|
// Initialize the clients
|
||||||
int count = InvariantDeviceProfile.INSTANCE.get(mContext).numAllAppsColumns;
|
int count = InvariantDeviceProfile.INSTANCE.get(mContext).numAllAppsColumns;
|
||||||
mHomeAppPredictor = createPredictor(Client.HOME, count);
|
mHomeAppPredictor = createPredictor(Client.HOME, count);
|
||||||
|
StatsLogCompatManager.LOGS_CONSUMER.add(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case MSG_DESTROY: {
|
case MSG_DESTROY: {
|
||||||
|
@ -168,98 +180,142 @@ public class PredictionAppTracker extends AppLaunchTracker
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Log.d(TAG, String.format("Sent immediate message to update %s", client));
|
Log.d(TAG, String.format("Sent immediate message to update %s", client));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relay onReturnedToHome to every plugin.
|
|
||||||
mAppLaunchEventsPluginsList.forEach(AppLaunchEventsPlugin::onReturnedToHome);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@AnyThread
|
||||||
@UiThread
|
private void sendEvent(LauncherAtom.ItemInfo atomInfo, int eventId) {
|
||||||
public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
|
AppTarget target = toAppTarget(atomInfo);
|
||||||
String container) {
|
if (target != null) {
|
||||||
// TODO: Use the full shortcut info
|
|
||||||
AppTarget target = new AppTarget.Builder(
|
|
||||||
new AppTargetId("shortcut:" + shortcutId), packageName, user)
|
|
||||||
.setClassName(shortcutId)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
sendLaunch(target, container);
|
|
||||||
|
|
||||||
// Relay onStartShortcut info to every connected plugin.
|
|
||||||
mAppLaunchEventsPluginsList
|
|
||||||
.forEach(plugin -> plugin.onStartShortcut(
|
|
||||||
packageName,
|
|
||||||
shortcutId,
|
|
||||||
user,
|
|
||||||
container != null ? container : CONTAINER_DEFAULT)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@UiThread
|
|
||||||
public void onStartApp(ComponentName cn, UserHandle user, String container) {
|
|
||||||
if (cn != null) {
|
|
||||||
AppTarget target = new AppTarget.Builder(
|
|
||||||
new AppTargetId("app:" + cn), cn.getPackageName(), user)
|
|
||||||
.setClassName(cn.getClassName())
|
|
||||||
.build();
|
|
||||||
sendLaunch(target, container);
|
|
||||||
|
|
||||||
// Relay onStartApp to every connected plugin.
|
|
||||||
mAppLaunchEventsPluginsList
|
|
||||||
.forEach(plugin -> plugin.onStartApp(
|
|
||||||
cn,
|
|
||||||
user,
|
|
||||||
container != null ? container : CONTAINER_DEFAULT)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@UiThread
|
|
||||||
public void onDismissApp(ComponentName cn, UserHandle user, String container) {
|
|
||||||
if (cn == null) return;
|
|
||||||
AppTarget target = new AppTarget.Builder(
|
|
||||||
new AppTargetId("app: " + cn), cn.getPackageName(), user)
|
|
||||||
.setClassName(cn.getClassName())
|
|
||||||
.build();
|
|
||||||
sendDismiss(target, container);
|
|
||||||
|
|
||||||
// Relay onDismissApp to every connected plugin.
|
|
||||||
mAppLaunchEventsPluginsList
|
|
||||||
.forEach(plugin -> plugin.onDismissApp(
|
|
||||||
cn,
|
|
||||||
user,
|
|
||||||
container != null ? container : CONTAINER_DEFAULT)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@UiThread
|
|
||||||
private void sendEvent(AppTarget target, String container, int eventId) {
|
|
||||||
AppTargetEvent event = new AppTargetEvent.Builder(target, eventId)
|
AppTargetEvent event = new AppTargetEvent.Builder(target, eventId)
|
||||||
.setLaunchLocation(container == null ? CONTAINER_DEFAULT : container)
|
.setLaunchLocation(getContainer(atomInfo))
|
||||||
.build();
|
.build();
|
||||||
Message.obtain(mMessageHandler, MSG_LAUNCH, event).sendToTarget();
|
Message.obtain(mMessageHandler, MSG_LAUNCH, event).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
|
||||||
private void sendLaunch(AppTarget target, String container) {
|
|
||||||
sendEvent(target, container, AppTargetEvent.ACTION_LAUNCH);
|
|
||||||
}
|
|
||||||
|
|
||||||
@UiThread
|
|
||||||
private void sendDismiss(AppTarget target, String container) {
|
|
||||||
sendEvent(target, container, AppTargetEvent.ACTION_DISMISS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPluginConnected(AppLaunchEventsPlugin appLaunchEventsPlugin, Context context) {
|
public void consume(EventEnum event, LauncherAtom.ItemInfo atomInfo) {
|
||||||
mAppLaunchEventsPluginsList.add(appLaunchEventsPlugin);
|
if (event == LAUNCHER_APP_LAUNCH_TAP
|
||||||
|
|| event == LAUNCHER_TASK_LAUNCH_SWIPE_DOWN
|
||||||
|
|| event == LAUNCHER_TASK_LAUNCH_TAP
|
||||||
|
|| event == LAUNCHER_QUICKSWITCH_RIGHT
|
||||||
|
|| event == LAUNCHER_QUICKSWITCH_LEFT) {
|
||||||
|
sendEvent(atomInfo, AppTargetEvent.ACTION_LAUNCH);
|
||||||
|
} else if (event == LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST) {
|
||||||
|
sendEvent(atomInfo, AppTargetEvent.ACTION_DISMISS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Nullable
|
||||||
public void onPluginDisconnected(AppLaunchEventsPlugin appLaunchEventsPlugin) {
|
private AppTarget toAppTarget(LauncherAtom.ItemInfo info) {
|
||||||
mAppLaunchEventsPluginsList.remove(appLaunchEventsPlugin);
|
UserHandle userHandle = Process.myUserHandle();
|
||||||
|
if (info.getIsWork()) {
|
||||||
|
userHandle = UserCache.INSTANCE.get(mContext).getUserProfiles().stream()
|
||||||
|
.filter(((Predicate<UserHandle>) userHandle::equals).negate())
|
||||||
|
.findAny()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
if (userHandle == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ComponentName cn = null;
|
||||||
|
String id = null;
|
||||||
|
|
||||||
|
switch (info.getItemCase()) {
|
||||||
|
case APPLICATION: {
|
||||||
|
LauncherAtom.Application app = info.getApplication();
|
||||||
|
if ((cn = parseNullable(app.getComponentName())) != null) {
|
||||||
|
id = "app:" + cn.getPackageName();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SHORTCUT: {
|
||||||
|
LauncherAtom.Shortcut si = info.getShortcut();
|
||||||
|
if (!TextUtils.isEmpty(si.getShortcutId())
|
||||||
|
&& (cn = parseNullable(si.getShortcutName())) != null) {
|
||||||
|
id = "shortcut:" + si.getShortcutId();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WIDGET: {
|
||||||
|
LauncherAtom.Widget widget = info.getWidget();
|
||||||
|
if ((cn = parseNullable(widget.getComponentName())) != null) {
|
||||||
|
id = "widget:" + cn.getPackageName();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TASK: {
|
||||||
|
LauncherAtom.Task task = info.getTask();
|
||||||
|
if ((cn = parseNullable(task.getComponentName())) != null) {
|
||||||
|
id = "app:" + cn.getPackageName();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FOLDER_ICON: {
|
||||||
|
id = "folder:" + SystemClock.uptimeMillis();
|
||||||
|
cn = new ComponentName(mContext.getPackageName(), "#folder");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (id != null && cn != null) {
|
||||||
|
return new AppTarget.Builder(new AppTargetId(id), cn.getPackageName(), userHandle)
|
||||||
|
.setClassName(cn.getClassName())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getContainer(LauncherAtom.ItemInfo info) {
|
||||||
|
ContainerInfo ci = info.getContainerInfo();
|
||||||
|
switch (ci.getContainerCase()) {
|
||||||
|
case WORKSPACE: {
|
||||||
|
// In case the item type is not widgets, the spaceX and spanY default to 1.
|
||||||
|
int spanX = info.getWidget().getSpanX();
|
||||||
|
int spanY = info.getWidget().getSpanY();
|
||||||
|
return getWorkspaceContainerString(ci.getWorkspace(), spanX, spanY);
|
||||||
|
}
|
||||||
|
case HOTSEAT: {
|
||||||
|
return getHotseatContainerString(ci.getHotseat());
|
||||||
|
}
|
||||||
|
case TASK_SWITCHER_CONTAINER: {
|
||||||
|
return "task-switcher";
|
||||||
|
}
|
||||||
|
case ALL_APPS_CONTAINER: {
|
||||||
|
return "all-apps";
|
||||||
|
}
|
||||||
|
case SEARCH_RESULT_CONTAINER: {
|
||||||
|
return "search-results";
|
||||||
|
}
|
||||||
|
case PREDICTED_HOTSEAT_CONTAINER: {
|
||||||
|
return "predictions/hotseat";
|
||||||
|
}
|
||||||
|
case PREDICTION_CONTAINER: {
|
||||||
|
return "predictions";
|
||||||
|
}
|
||||||
|
case FOLDER: {
|
||||||
|
FolderContainer fc = ci.getFolder();
|
||||||
|
switch (fc.getParentContainerCase()) {
|
||||||
|
case WORKSPACE:
|
||||||
|
return "folder/" + getWorkspaceContainerString(fc.getWorkspace(), 1, 1);
|
||||||
|
case HOTSEAT:
|
||||||
|
return "folder/" + getHotseatContainerString(fc.getHotseat());
|
||||||
|
}
|
||||||
|
return "folder";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getWorkspaceContainerString(WorkspaceContainer wc, int spanX, int spanY) {
|
||||||
|
return String.format(Locale.ENGLISH, "workspace/%d/[%d,%d]/[%d,%d]",
|
||||||
|
wc.getPageIndex(), wc.getGridX(), wc.getGridY(), spanX, spanY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getHotseatContainerString(HotseatContainer hc) {
|
||||||
|
return String.format(Locale.ENGLISH, "hotseat/%d", hc.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ComponentName parseNullable(String componentNameString) {
|
||||||
|
return TextUtils.isEmpty(componentNameString)
|
||||||
|
? null : ComponentName.unflattenFromString(componentNameString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@ import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.keyboard.FocusIndicatorHelper;
|
import com.android.launcher3.keyboard.FocusIndicatorHelper;
|
||||||
import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper;
|
import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper;
|
||||||
import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
|
import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
|
||||||
import com.android.launcher3.model.data.AppInfo;
|
import com.android.launcher3.model.data.AppInfo;
|
||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||||
|
@ -93,9 +92,6 @@ public class PredictionRowView extends LinearLayout implements
|
||||||
private static final Interpolator ALPHA_FACTOR_INTERPOLATOR =
|
private static final Interpolator ALPHA_FACTOR_INTERPOLATOR =
|
||||||
(t) -> (t < 0.8f) ? 0 : (t - 0.8f) / 0.2f;
|
(t) -> (t < 0.8f) ? 0 : (t - 0.8f) / 0.2f;
|
||||||
|
|
||||||
private static final OnClickListener PREDICTION_CLICK_LISTENER =
|
|
||||||
ItemClickHandler.getInstance(AppLaunchTracker.CONTAINER_PREDICTIONS);
|
|
||||||
|
|
||||||
private final Launcher mLauncher;
|
private final Launcher mLauncher;
|
||||||
private final PredictionUiStateManager mPredictionUiStateManager;
|
private final PredictionUiStateManager mPredictionUiStateManager;
|
||||||
private int mNumPredictedAppsPerRow;
|
private int mNumPredictedAppsPerRow;
|
||||||
|
@ -246,7 +242,7 @@ public class PredictionRowView extends LinearLayout implements
|
||||||
while (getChildCount() < mNumPredictedAppsPerRow) {
|
while (getChildCount() < mNumPredictedAppsPerRow) {
|
||||||
BubbleTextView icon = (BubbleTextView) inflater.inflate(
|
BubbleTextView icon = (BubbleTextView) inflater.inflate(
|
||||||
R.layout.all_apps_icon, this, false);
|
R.layout.all_apps_icon, this, false);
|
||||||
icon.setOnClickListener(PREDICTION_CLICK_LISTENER);
|
icon.setOnClickListener(ItemClickHandler.INSTANCE);
|
||||||
icon.setOnLongClickListener(ItemLongClickListener.INSTANCE_ALL_APPS);
|
icon.setOnLongClickListener(ItemLongClickListener.INSTANCE_ALL_APPS);
|
||||||
icon.setLongPressTimeoutFactor(1f);
|
icon.setLongPressTimeoutFactor(1f);
|
||||||
icon.setOnFocusChangeListener(mFocusHelper);
|
icon.setOnFocusChangeListener(mFocusHelper);
|
||||||
|
|
|
@ -34,8 +34,6 @@ import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.launcher3.BaseQuickstepLauncher;
|
import com.android.launcher3.BaseQuickstepLauncher;
|
||||||
import com.android.launcher3.DeviceProfile;
|
import com.android.launcher3.DeviceProfile;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
|
@ -129,12 +127,11 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
|
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
|
||||||
@Nullable String sourceContainer) {
|
|
||||||
if (mHotseatPredictionController != null) {
|
if (mHotseatPredictionController != null) {
|
||||||
mHotseatPredictionController.setPauseUIUpdate(true);
|
mHotseatPredictionController.setPauseUIUpdate(true);
|
||||||
}
|
}
|
||||||
return super.startActivitySafely(v, intent, item, sourceContainer);
|
return super.startActivitySafely(v, intent, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -59,6 +59,7 @@ import android.view.ViewTreeObserver.OnDrawListener;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
import androidx.annotation.UiThread;
|
||||||
|
|
||||||
import com.android.launcher3.AbstractFloatingView;
|
import com.android.launcher3.AbstractFloatingView;
|
||||||
|
@ -69,6 +70,7 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.logging.StatsLogManager;
|
import com.android.launcher3.logging.StatsLogManager;
|
||||||
|
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
|
||||||
import com.android.launcher3.logging.UserEventDispatcher;
|
import com.android.launcher3.logging.UserEventDispatcher;
|
||||||
import com.android.launcher3.statemanager.StatefulActivity;
|
import com.android.launcher3.statemanager.StatefulActivity;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||||
|
@ -876,22 +878,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
||||||
animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocityPxPerMs);
|
animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocityPxPerMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doLogGesture(GestureEndTarget endTarget) {
|
private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
|
||||||
DeviceProfile dp = mDp;
|
|
||||||
if (dp == null || mDownPos == null) {
|
|
||||||
// We probably never received an animation controller, skip logging.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pageIndex = endTarget == LAST_TASK
|
|
||||||
? LOG_NO_OP_PAGE_INDEX
|
|
||||||
: mRecentsView.getNextPage();
|
|
||||||
UserEventDispatcher.newInstance(mContext).logStateChangeAction(
|
|
||||||
mLogAction, mLogDirection,
|
|
||||||
(int) mDownPos.x, (int) mDownPos.y,
|
|
||||||
ContainerType.NAVBAR, ContainerType.APP,
|
|
||||||
endTarget.containerType,
|
|
||||||
pageIndex);
|
|
||||||
StatsLogManager.EventEnum event;
|
StatsLogManager.EventEnum event;
|
||||||
switch (endTarget) {
|
switch (endTarget) {
|
||||||
case HOME:
|
case HOME:
|
||||||
|
@ -909,10 +896,29 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
||||||
default:
|
default:
|
||||||
event = IGNORE;
|
event = IGNORE;
|
||||||
}
|
}
|
||||||
StatsLogManager.newInstance(mContext).logger()
|
StatsLogger logger = StatsLogManager.newInstance(mContext).logger()
|
||||||
.withSrcState(LAUNCHER_STATE_BACKGROUND)
|
.withSrcState(LAUNCHER_STATE_BACKGROUND)
|
||||||
.withDstState(StatsLogManager.containerTypeToAtomState(endTarget.containerType))
|
.withDstState(StatsLogManager.containerTypeToAtomState(endTarget.containerType));
|
||||||
.log(event);
|
if (targetTask != null) {
|
||||||
|
logger.withItemInfo(targetTask.getItemInfo());
|
||||||
|
}
|
||||||
|
logger.log(event);
|
||||||
|
|
||||||
|
|
||||||
|
DeviceProfile dp = mDp;
|
||||||
|
if (dp == null || mDownPos == null) {
|
||||||
|
// We probably never received an animation controller, skip logging.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int pageIndex = endTarget == LAST_TASK
|
||||||
|
? LOG_NO_OP_PAGE_INDEX
|
||||||
|
: mRecentsView.getNextPage();
|
||||||
|
UserEventDispatcher.newInstance(mContext).logStateChangeAction(
|
||||||
|
mLogAction, mLogDirection,
|
||||||
|
(int) mDownPos.x, (int) mDownPos.y,
|
||||||
|
ContainerType.NAVBAR, ContainerType.APP,
|
||||||
|
endTarget.containerType,
|
||||||
|
pageIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
|
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
|
||||||
|
@ -1117,7 +1123,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
||||||
private void resumeLastTask() {
|
private void resumeLastTask() {
|
||||||
mRecentsAnimationController.finish(false /* toRecents */, null);
|
mRecentsAnimationController.finish(false /* toRecents */, null);
|
||||||
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
|
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false);
|
||||||
doLogGesture(LAST_TASK);
|
doLogGesture(LAST_TASK, null);
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,6 +1138,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
private void startNewTaskInternal() {
|
private void startNewTaskInternal() {
|
||||||
|
TaskView taskToLaunch = mRecentsView == null ? null : mRecentsView.getNextPageTaskView();
|
||||||
startNewTask(success -> {
|
startNewTask(success -> {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
reset();
|
reset();
|
||||||
|
@ -1140,7 +1147,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
||||||
endLauncherTransitionController();
|
endLauncherTransitionController();
|
||||||
updateSysUiFlags(1 /* windowProgress == overview */);
|
updateSysUiFlags(1 /* windowProgress == overview */);
|
||||||
}
|
}
|
||||||
doLogGesture(NEW_TASK);
|
doLogGesture(NEW_TASK, taskToLaunch);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1285,7 +1292,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
||||||
() -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
|
() -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
|
||||||
}
|
}
|
||||||
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
|
ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", true);
|
||||||
doLogGesture(HOME);
|
doLogGesture(HOME, mRecentsView == null ? null : mRecentsView.getCurrentPageTaskView());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void finishRecentsControllerToHome(Runnable callback);
|
protected abstract void finishRecentsControllerToHome(Runnable callback);
|
||||||
|
@ -1300,7 +1307,7 @@ public abstract class BaseSwipeUpHandlerV2<T extends StatefulActivity<?>, Q exte
|
||||||
mRecentsView.onSwipeUpAnimationSuccess();
|
mRecentsView.onSwipeUpAnimationSuccess();
|
||||||
|
|
||||||
SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
|
SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG);
|
||||||
doLogGesture(RECENTS);
|
doLogGesture(RECENTS, mRecentsView.getCurrentPageTaskView());
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,6 @@ import com.android.launcher3.R;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.config.FeatureFlags;
|
import com.android.launcher3.config.FeatureFlags;
|
||||||
import com.android.launcher3.logging.UserEventDispatcher;
|
import com.android.launcher3.logging.UserEventDispatcher;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
|
||||||
import com.android.launcher3.provider.RestoreDbTask;
|
import com.android.launcher3.provider.RestoreDbTask;
|
||||||
import com.android.launcher3.statemanager.StatefulActivity;
|
import com.android.launcher3.statemanager.StatefulActivity;
|
||||||
import com.android.launcher3.testing.TestLogging;
|
import com.android.launcher3.testing.TestLogging;
|
||||||
|
@ -771,13 +770,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||||
mOverviewComponentObserver.getActivityInterface();
|
mOverviewComponentObserver.getActivityInterface();
|
||||||
final Intent overviewIntent = new Intent(
|
final Intent overviewIntent = new Intent(
|
||||||
mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState());
|
mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState());
|
||||||
if (activityInterface.getCreatedActivity() == null) {
|
if (activityInterface.getCreatedActivity() != null && fromInit) {
|
||||||
// Make sure that UI states will be initialized.
|
|
||||||
activityInterface.createActivityInitListener((wasVisible) -> {
|
|
||||||
AppLaunchTracker.INSTANCE.get(TouchInteractionService.this);
|
|
||||||
return false;
|
|
||||||
}).register(overviewIntent);
|
|
||||||
} else if (fromInit) {
|
|
||||||
// The activity has been created before the initialization of overview service. It is
|
// The activity has been created before the initialization of overview service. It is
|
||||||
// usually happens when booting or launcher is the top activity, so we should already
|
// usually happens when booting or launcher is the top activity, so we should already
|
||||||
// have the latest state.
|
// have the latest state.
|
||||||
|
|
|
@ -63,12 +63,6 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity>
|
||||||
mActivity.startHome();
|
mActivity.startHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldUseMultiWindowTaskSizeStrategy() {
|
|
||||||
// Just use the activity task size for multi-window as well.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When starting gesture interaction from home, we add a temporary invisible tile corresponding
|
* When starting gesture interaction from home, we add a temporary invisible tile corresponding
|
||||||
* to the home task. This allows us to handle quick-switch similarly to a quick-switching
|
* to the home task. This allows us to handle quick-switch similarly to a quick-switching
|
||||||
|
|
|
@ -31,7 +31,6 @@ import android.animation.ObjectAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
|
@ -41,18 +40,15 @@ import com.android.launcher3.BaseQuickstepLauncher;
|
||||||
import com.android.launcher3.Hotseat;
|
import com.android.launcher3.Hotseat;
|
||||||
import com.android.launcher3.LauncherState;
|
import com.android.launcher3.LauncherState;
|
||||||
import com.android.launcher3.anim.Interpolators;
|
import com.android.launcher3.anim.Interpolators;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
|
||||||
import com.android.launcher3.statehandlers.DepthController;
|
import com.android.launcher3.statehandlers.DepthController;
|
||||||
import com.android.launcher3.statemanager.StateManager.StateListener;
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
||||||
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
|
||||||
import com.android.launcher3.util.TraceHelper;
|
|
||||||
import com.android.launcher3.views.ScrimView;
|
import com.android.launcher3.views.ScrimView;
|
||||||
import com.android.quickstep.LauncherActivityInterface;
|
import com.android.quickstep.LauncherActivityInterface;
|
||||||
import com.android.quickstep.SysUINavigationMode;
|
import com.android.quickstep.SysUINavigationMode;
|
||||||
import com.android.quickstep.util.TransformParams;
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.systemui.plugins.PluginListener;
|
import com.android.systemui.plugins.PluginListener;
|
||||||
import com.android.systemui.plugins.RecentsExtraCard;
|
import com.android.systemui.plugins.RecentsExtraCard;
|
||||||
import com.android.systemui.shared.recents.model.Task;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link RecentsView} used in Launcher activity
|
* {@link RecentsView} used in Launcher activity
|
||||||
|
@ -178,18 +174,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
|
||||||
super.onTaskLaunchAnimationEnd(success);
|
super.onTaskLaunchAnimationEnd(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTaskLaunched(Task task) {
|
|
||||||
UserHandle user = UserHandle.of(task.key.userId);
|
|
||||||
AppLaunchTracker.INSTANCE.get(getContext()).onStartApp(task.getTopComponent(), user,
|
|
||||||
AppLaunchTracker.CONTAINER_OVERVIEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldUseMultiWindowTaskSizeStrategy() {
|
|
||||||
return TraceHelper.whitelistIpcs("isInMultiWindowMode", mActivity::isInMultiWindowMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scrollTo(int x, int y) {
|
public void scrollTo(int x, int y) {
|
||||||
super.scrollTo(x, y);
|
super.scrollTo(x, y);
|
||||||
|
|
|
@ -55,11 +55,8 @@ import android.animation.LayoutTransition.TransitionListener;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.ActivityManager.RunningTaskInfo;
|
import android.app.ActivityManager.RunningTaskInfo;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
|
@ -1997,19 +1994,12 @@ public abstract class RecentsView<T extends StatefulActivity> extends PagedView
|
||||||
protected void onTaskLaunchAnimationUpdate(float progress, TaskView tv) {
|
protected void onTaskLaunchAnimationUpdate(float progress, TaskView tv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean shouldUseMultiWindowTaskSizeStrategy();
|
|
||||||
|
|
||||||
protected void onTaskLaunchAnimationEnd(boolean success) {
|
protected void onTaskLaunchAnimationEnd(boolean success) {
|
||||||
if (success) {
|
if (success) {
|
||||||
resetTaskVisuals();
|
resetTaskVisuals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when task activity is launched
|
|
||||||
*/
|
|
||||||
public void onTaskLaunched(Task task){ }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void notifyPageSwitchListener(int prevPage) {
|
protected void notifyPageSwitchListener(int prevPage) {
|
||||||
super.notifyPageSwitchListener(prevPage);
|
super.notifyPageSwitchListener(prevPage);
|
||||||
|
|
|
@ -30,8 +30,7 @@ import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||||
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
|
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.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
|
||||||
.LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS;
|
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
|
@ -385,7 +384,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
|
||||||
}
|
}
|
||||||
}, resultCallbackHandler);
|
}, resultCallbackHandler);
|
||||||
}
|
}
|
||||||
getRecentsView().onTaskLaunched(mTask);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGE
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.WorkerThread;
|
||||||
|
|
||||||
import com.android.launcher3.LauncherAppState;
|
import com.android.launcher3.LauncherAppState;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
|
@ -54,6 +54,7 @@ import com.android.systemui.shared.system.SysUiStatsLog;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.OptionalInt;
|
import java.util.OptionalInt;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class calls StatsLog compile time generated methods.
|
* This class calls StatsLog compile time generated methods.
|
||||||
|
@ -68,8 +69,6 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
private static final String TAG = "StatsLog";
|
private static final String TAG = "StatsLog";
|
||||||
private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG);
|
private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG);
|
||||||
|
|
||||||
private static Context sContext;
|
|
||||||
|
|
||||||
private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
|
private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
|
||||||
// LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates
|
// LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates
|
||||||
// from nano to lite, bake constant to prevent robo test failure.
|
// from nano to lite, bake constant to prevent robo test failure.
|
||||||
|
@ -77,8 +76,13 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
private static final int FOLDER_HIERARCHY_OFFSET = 100;
|
private static final int FOLDER_HIERARCHY_OFFSET = 100;
|
||||||
private static final int SEARCH_RESULT_HIERARCHY_OFFSET = 200;
|
private static final int SEARCH_RESULT_HIERARCHY_OFFSET = 200;
|
||||||
|
|
||||||
|
public static final CopyOnWriteArrayList<StatsLogConsumer> LOGS_CONSUMER =
|
||||||
|
new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
|
||||||
public StatsLogCompatManager(Context context) {
|
public StatsLogCompatManager(Context context) {
|
||||||
sContext = context;
|
mContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -86,25 +90,12 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
return new StatsCompatLogger();
|
return new StatsCompatLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a ranking event and accompanying {@link InstanceId} and package name.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void log(EventEnum rankingEvent, InstanceId instanceId, @Nullable String packageName,
|
|
||||||
int position) {
|
|
||||||
SysUiStatsLog.write(SysUiStatsLog.RANKING_SELECTED,
|
|
||||||
rankingEvent.getId() /* event_id = 1; */,
|
|
||||||
packageName /* package_name = 2; */,
|
|
||||||
instanceId.getId() /* instance_id = 3; */,
|
|
||||||
position /* position_picked = 4; */);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs the workspace layout information on the model thread.
|
* Logs the workspace layout information on the model thread.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void logSnapshot() {
|
public void logSnapshot() {
|
||||||
LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
|
LauncherAppState.getInstance(mContext).getModel().enqueueModelUpdateTask(
|
||||||
new SnapshotWorker());
|
new SnapshotWorker());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +166,7 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
private static class StatsCompatLogger implements StatsLogger {
|
private static class StatsCompatLogger implements StatsLogger {
|
||||||
|
|
||||||
private static final ItemInfo DEFAULT_ITEM_INFO = new ItemInfo();
|
private static final ItemInfo DEFAULT_ITEM_INFO = new ItemInfo();
|
||||||
|
|
||||||
private ItemInfo mItemInfo = DEFAULT_ITEM_INFO;
|
private ItemInfo mItemInfo = DEFAULT_ITEM_INFO;
|
||||||
private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
|
private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
|
||||||
private OptionalInt mRank = OptionalInt.empty();
|
private OptionalInt mRank = OptionalInt.empty();
|
||||||
|
@ -253,36 +245,35 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mItemInfo.container < 0) {
|
LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
|
||||||
// Item is not within a folder. Write to StatsLog in same thread.
|
if (mItemInfo.container < 0 || appState == null) {
|
||||||
write(event, mInstanceId, applyOverwrites(mItemInfo.buildProto()), mSrcState,
|
// Write log on the model thread so that logs do not go out of order
|
||||||
mDstState);
|
// (for eg: drop comes after drag)
|
||||||
|
Executors.MODEL_EXECUTOR.execute(
|
||||||
|
() -> write(event, applyOverwrites(mItemInfo.buildProto())));
|
||||||
} else {
|
} else {
|
||||||
// Item is inside the folder, fetch folder info in a BG thread
|
// Item is inside the folder, fetch folder info in a BG thread
|
||||||
// and then write to StatsLog.
|
// and then write to StatsLog.
|
||||||
LauncherAppState.getInstance(sContext).getModel().enqueueModelUpdateTask(
|
appState.getModel().enqueueModelUpdateTask(
|
||||||
new BaseModelUpdateTask() {
|
new BaseModelUpdateTask() {
|
||||||
@Override
|
@Override
|
||||||
public void execute(LauncherAppState app, BgDataModel dataModel,
|
public void execute(LauncherAppState app, BgDataModel dataModel,
|
||||||
AllAppsList apps) {
|
AllAppsList apps) {
|
||||||
FolderInfo folderInfo = dataModel.folders.get(mItemInfo.container);
|
FolderInfo folderInfo = dataModel.folders.get(mItemInfo.container);
|
||||||
write(event, mInstanceId,
|
write(event, applyOverwrites(mItemInfo.buildProto(folderInfo)));
|
||||||
applyOverwrites(mItemInfo.buildProto(folderInfo)),
|
|
||||||
mSrcState, mDstState);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LauncherAtom.ItemInfo applyOverwrites(LauncherAtom.ItemInfo atomInfo) {
|
private LauncherAtom.ItemInfo applyOverwrites(LauncherAtom.ItemInfo atomInfo) {
|
||||||
LauncherAtom.ItemInfo.Builder itemInfoBuilder =
|
LauncherAtom.ItemInfo.Builder itemInfoBuilder = atomInfo.toBuilder();
|
||||||
(LauncherAtom.ItemInfo.Builder) atomInfo.toBuilder();
|
|
||||||
|
|
||||||
mRank.ifPresent(itemInfoBuilder::setRank);
|
mRank.ifPresent(itemInfoBuilder::setRank);
|
||||||
mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo);
|
mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo);
|
||||||
|
|
||||||
if (mFromState.isPresent() || mToState.isPresent() || mEditText.isPresent()) {
|
if (mFromState.isPresent() || mToState.isPresent() || mEditText.isPresent()) {
|
||||||
FolderIcon.Builder folderIconBuilder = (FolderIcon.Builder) itemInfoBuilder
|
FolderIcon.Builder folderIconBuilder = itemInfoBuilder
|
||||||
.getFolderIcon()
|
.getFolderIcon()
|
||||||
.toBuilder();
|
.toBuilder();
|
||||||
mFromState.ifPresent(folderIconBuilder::setFromLabelState);
|
mFromState.ifPresent(folderIconBuilder::setFromLabelState);
|
||||||
|
@ -293,8 +284,11 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
return itemInfoBuilder.build();
|
return itemInfoBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void write(EventEnum event, InstanceId instanceId, LauncherAtom.ItemInfo atomInfo,
|
@WorkerThread
|
||||||
int srcState, int dstState) {
|
private void write(EventEnum event, LauncherAtom.ItemInfo atomInfo) {
|
||||||
|
InstanceId instanceId = mInstanceId;
|
||||||
|
int srcState = mSrcState;
|
||||||
|
int dstState = mDstState;
|
||||||
if (IS_VERBOSE) {
|
if (IS_VERBOSE) {
|
||||||
String name = (event instanceof Enum) ? ((Enum) event).name() :
|
String name = (event instanceof Enum) ? ((Enum) event).name() :
|
||||||
event.getId() + "";
|
event.getId() + "";
|
||||||
|
@ -307,6 +301,10 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
atomInfo));
|
atomInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (StatsLogConsumer consumer : LOGS_CONSUMER) {
|
||||||
|
consumer.consume(event, atomInfo);
|
||||||
|
}
|
||||||
|
|
||||||
SysUiStatsLog.write(
|
SysUiStatsLog.write(
|
||||||
SysUiStatsLog.LAUNCHER_EVENT,
|
SysUiStatsLog.LAUNCHER_EVENT,
|
||||||
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
|
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
|
||||||
|
@ -446,7 +444,16 @@ public class StatsLogCompatManager extends StatsLogManager {
|
||||||
return "ALLAPPS";
|
return "ALLAPPS";
|
||||||
default:
|
default:
|
||||||
return "INVALID";
|
return "INVALID";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to get stats log while it is dispatched to the system
|
||||||
|
*/
|
||||||
|
public interface StatsLogConsumer {
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
void consume(EventEnum event, LauncherAtom.ItemInfo atomInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,6 @@ import androidx.annotation.Nullable;
|
||||||
import com.android.launcher3.LauncherSettings.Favorites;
|
import com.android.launcher3.LauncherSettings.Favorites;
|
||||||
import com.android.launcher3.logging.InstanceId;
|
import com.android.launcher3.logging.InstanceId;
|
||||||
import com.android.launcher3.logging.InstanceIdSequence;
|
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.ItemInfo;
|
||||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||||
import com.android.launcher3.touch.ItemClickHandler;
|
import com.android.launcher3.touch.ItemClickHandler;
|
||||||
|
@ -154,8 +153,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
|
||||||
|
|
||||||
public abstract ActivityOptions getActivityLaunchOptions(View v);
|
public abstract ActivityOptions getActivityLaunchOptions(View v);
|
||||||
|
|
||||||
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
|
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item) {
|
||||||
@Nullable String sourceContainer) {
|
|
||||||
if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
|
if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
|
||||||
Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
|
||||||
return false;
|
return false;
|
||||||
|
@ -176,17 +174,13 @@ public abstract class BaseDraggingActivity extends BaseActivity
|
||||||
&& !((WorkspaceItemInfo) item).isPromise();
|
&& !((WorkspaceItemInfo) item).isPromise();
|
||||||
if (isShortcut) {
|
if (isShortcut) {
|
||||||
// Shortcuts need some special checks due to legacy reasons.
|
// Shortcuts need some special checks due to legacy reasons.
|
||||||
startShortcutIntentSafely(intent, optsBundle, item, sourceContainer);
|
startShortcutIntentSafely(intent, optsBundle, item);
|
||||||
} else if (user == null || user.equals(Process.myUserHandle())) {
|
} else if (user == null || user.equals(Process.myUserHandle())) {
|
||||||
// Could be launching some bookkeeping activity
|
// Could be launching some bookkeeping activity
|
||||||
startActivity(intent, optsBundle);
|
startActivity(intent, optsBundle);
|
||||||
AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
|
|
||||||
Process.myUserHandle(), sourceContainer);
|
|
||||||
} else {
|
} else {
|
||||||
getSystemService(LauncherApps.class).startMainActivity(
|
getSystemService(LauncherApps.class).startMainActivity(
|
||||||
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
|
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
|
||||||
AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(), user,
|
|
||||||
sourceContainer);
|
|
||||||
}
|
}
|
||||||
getUserEventDispatcher().logAppLaunch(v, intent, user);
|
getUserEventDispatcher().logAppLaunch(v, intent, user);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
|
@ -206,8 +200,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
|
||||||
.log(LAUNCHER_APP_LAUNCH_TAP);
|
.log(LAUNCHER_APP_LAUNCH_TAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info,
|
private void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
|
||||||
@Nullable String sourceContainer) {
|
|
||||||
try {
|
try {
|
||||||
StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
|
StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
|
||||||
try {
|
try {
|
||||||
|
@ -221,8 +214,6 @@ public abstract class BaseDraggingActivity extends BaseActivity
|
||||||
String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
|
String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
|
||||||
String packageName = intent.getPackage();
|
String packageName = intent.getPackage();
|
||||||
startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
|
startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
|
||||||
AppLaunchTracker.INSTANCE.get(this).onStartShortcut(packageName, id, info.user,
|
|
||||||
sourceContainer);
|
|
||||||
} else {
|
} else {
|
||||||
// Could be launching some bookkeeping activity
|
// Could be launching some bookkeeping activity
|
||||||
startActivity(intent, optsBundle);
|
startActivity(intent, optsBundle);
|
||||||
|
|
|
@ -814,7 +814,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||||
|
|
||||||
if (grantResults.length > 0
|
if (grantResults.length > 0
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
startActivitySafely(v, intent, null, null);
|
startActivitySafely(v, intent, null);
|
||||||
} else {
|
} else {
|
||||||
// TODO: Show a snack bar with link to settings
|
// TODO: Show a snack bar with link to settings
|
||||||
Toast.makeText(this, getString(R.string.msg_no_phone_permission,
|
Toast.makeText(this, getString(R.string.msg_no_phone_permission,
|
||||||
|
@ -1862,13 +1862,12 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
|
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
|
||||||
@Nullable String sourceContainer) {
|
|
||||||
if (!hasBeenResumed()) {
|
if (!hasBeenResumed()) {
|
||||||
// Workaround an issue where the WM launch animation is clobbered when finishing the
|
// Workaround an issue where the WM launch animation is clobbered when finishing the
|
||||||
// recents animation into launcher. Defer launching the activity until Launcher is
|
// recents animation into launcher. Defer launching the activity until Launcher is
|
||||||
// next resumed.
|
// next resumed.
|
||||||
addOnResumeCallback(() -> startActivitySafely(v, intent, item, sourceContainer));
|
addOnResumeCallback(() -> startActivitySafely(v, intent, item));
|
||||||
if (mOnDeferredActivityLaunchCallback != null) {
|
if (mOnDeferredActivityLaunchCallback != null) {
|
||||||
mOnDeferredActivityLaunchCallback.run();
|
mOnDeferredActivityLaunchCallback.run();
|
||||||
mOnDeferredActivityLaunchCallback = null;
|
mOnDeferredActivityLaunchCallback = null;
|
||||||
|
@ -1876,7 +1875,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean success = super.startActivitySafely(v, intent, item, sourceContainer);
|
boolean success = super.startActivitySafely(v, intent, item);
|
||||||
if (success && v instanceof BubbleTextView) {
|
if (success && v instanceof BubbleTextView) {
|
||||||
// This is set to the view that launched the activity that navigated the user away
|
// This is set to the view that launched the activity that navigated the user away
|
||||||
// from launcher. Since there is no callback for when the activity has finished
|
// from launcher. Since there is no callback for when the activity has finished
|
||||||
|
|
|
@ -39,7 +39,7 @@ import com.android.launcher3.dragndrop.DragOptions;
|
||||||
import com.android.launcher3.logging.FileLog;
|
import com.android.launcher3.logging.FileLog;
|
||||||
import com.android.launcher3.logging.LoggerUtils;
|
import com.android.launcher3.logging.LoggerUtils;
|
||||||
import com.android.launcher3.logging.StatsLogManager;
|
import com.android.launcher3.logging.StatsLogManager;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
|
||||||
import com.android.launcher3.model.data.ItemInfo;
|
import com.android.launcher3.model.data.ItemInfo;
|
||||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||||
|
@ -218,13 +218,16 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
|
||||||
public void onDrop(DragObject d, DragOptions options) {
|
public void onDrop(DragObject d, DragOptions options) {
|
||||||
// Defer onComplete
|
// Defer onComplete
|
||||||
d.dragSource = new DeferredOnComplete(d.dragSource, getContext());
|
d.dragSource = new DeferredOnComplete(d.dragSource, getContext());
|
||||||
|
|
||||||
super.onDrop(d, options);
|
super.onDrop(d, options);
|
||||||
|
StatsLogger logger = mStatsLogManager.logger().withInstanceId(d.logInstanceId);
|
||||||
|
if (d.originalDragInfo != null) {
|
||||||
|
logger.withItemInfo(d.originalDragInfo);
|
||||||
|
}
|
||||||
if (mCurrentAccessibilityAction == UNINSTALL) {
|
if (mCurrentAccessibilityAction == UNINSTALL) {
|
||||||
mStatsLogManager.logger().withInstanceId(d.logInstanceId)
|
logger.log(LAUNCHER_ITEM_DROPPED_ON_UNINSTALL);
|
||||||
.log(LAUNCHER_ITEM_DROPPED_ON_UNINSTALL);
|
|
||||||
} else if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
|
} else if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
|
||||||
mStatsLogManager.logger().withInstanceId(d.logInstanceId)
|
logger.log(LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST);
|
||||||
.log(LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,8 +286,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
|
if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
|
||||||
AppLaunchTracker.INSTANCE.get(getContext()).onDismissApp(info.getTargetComponent(),
|
// We sent the log event, nothing else left to do
|
||||||
info.user, AppLaunchTracker.CONTAINER_PREDICTIONS);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// else: mCurrentAccessibilityAction == UNINSTALL
|
// else: mCurrentAccessibilityAction == UNINSTALL
|
||||||
|
|
|
@ -41,7 +41,6 @@ import com.android.launcher3.BaseDraggingActivity;
|
||||||
import com.android.launcher3.BubbleTextView;
|
import com.android.launcher3.BubbleTextView;
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
|
import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
|
||||||
import com.android.launcher3.model.data.AppInfo;
|
import com.android.launcher3.model.data.AppInfo;
|
||||||
import com.android.launcher3.util.PackageManagerHelper;
|
import com.android.launcher3.util.PackageManagerHelper;
|
||||||
|
|
||||||
|
@ -270,7 +269,7 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.
|
||||||
View searchMarketView = mLayoutInflater.inflate(R.layout.all_apps_search_market,
|
View searchMarketView = mLayoutInflater.inflate(R.layout.all_apps_search_market,
|
||||||
parent, false);
|
parent, false);
|
||||||
searchMarketView.setOnClickListener(v -> mLauncher.startActivitySafely(
|
searchMarketView.setOnClickListener(v -> mLauncher.startActivitySafely(
|
||||||
v, mMarketSearchIntent, null, AppLaunchTracker.CONTAINER_SEARCH));
|
v, mMarketSearchIntent, null));
|
||||||
return new ViewHolder(searchMarketView);
|
return new ViewHolder(searchMarketView);
|
||||||
case VIEW_TYPE_ALL_APPS_DIVIDER:
|
case VIEW_TYPE_ALL_APPS_DIVIDER:
|
||||||
return new ViewHolder(mLayoutInflater.inflate(
|
return new ViewHolder(mLayoutInflater.inflate(
|
||||||
|
|
|
@ -28,7 +28,6 @@ import android.widget.TextView.OnEditorActionListener;
|
||||||
import com.android.launcher3.BaseDraggingActivity;
|
import com.android.launcher3.BaseDraggingActivity;
|
||||||
import com.android.launcher3.ExtendedEditText;
|
import com.android.launcher3.ExtendedEditText;
|
||||||
import com.android.launcher3.Utilities;
|
import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.model.AppLaunchTracker;
|
|
||||||
import com.android.launcher3.util.ComponentKey;
|
import com.android.launcher3.util.ComponentKey;
|
||||||
import com.android.launcher3.util.PackageManagerHelper;
|
import com.android.launcher3.util.PackageManagerHelper;
|
||||||
|
|
||||||
|
@ -112,8 +111,8 @@ public class AllAppsSearchBarController
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return mLauncher.startActivitySafely(v,
|
return mLauncher.startActivitySafely(v,
|
||||||
PackageManagerHelper.getMarketSearchIntent(mLauncher, query), null,
|
PackageManagerHelper.getMarketSearchIntent(mLauncher, query), null
|
||||||
AppLaunchTracker.CONTAINER_SEARCH);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package com.android.launcher3.logging;
|
package com.android.launcher3.logging;
|
||||||
|
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
|
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_CLOSE_DOWN;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_CLOSE_DOWN;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_OPEN_UP;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_OPEN_UP;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
|
||||||
|
@ -23,8 +22,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
|
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
|
||||||
import com.android.launcher3.logger.LauncherAtom.FromState;
|
import com.android.launcher3.logger.LauncherAtom.FromState;
|
||||||
|
@ -403,19 +400,6 @@ public class StatsLogManager implements ResourceBasedOverride {
|
||||||
return mgr;
|
return mgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Log an event with ranked-choice information along with package. Does nothing if event.getId()
|
|
||||||
* <= 0.
|
|
||||||
*
|
|
||||||
* @param rankingEvent an enum implementing EventEnum interface.
|
|
||||||
* @param instanceId An identifier obtained from an InstanceIdSequence.
|
|
||||||
* @param packageName the package name of the relevant app, if known (null otherwise).
|
|
||||||
* @param position the position picked.
|
|
||||||
*/
|
|
||||||
public void log(EventEnum rankingEvent, InstanceId instanceId, @Nullable String packageName,
|
|
||||||
int position) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs snapshot, or impression of the current workspace.
|
* Logs snapshot, or impression of the current workspace.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,13 +17,7 @@ package com.android.launcher3.model;
|
||||||
|
|
||||||
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
|
import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.launcher3.R;
|
import com.android.launcher3.R;
|
||||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
|
||||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||||
import com.android.launcher3.util.ResourceBasedOverride;
|
import com.android.launcher3.util.ResourceBasedOverride;
|
||||||
|
|
||||||
|
@ -32,28 +26,8 @@ import com.android.launcher3.util.ResourceBasedOverride;
|
||||||
*/
|
*/
|
||||||
public class AppLaunchTracker implements ResourceBasedOverride {
|
public class AppLaunchTracker implements ResourceBasedOverride {
|
||||||
|
|
||||||
/**
|
|
||||||
* Derived from LauncherEvent proto.
|
|
||||||
* TODO: Use proper descriptive constants
|
|
||||||
*/
|
|
||||||
public static final String CONTAINER_DEFAULT = Integer.toString(ContainerType.WORKSPACE);
|
|
||||||
public static final String CONTAINER_ALL_APPS = Integer.toString(ContainerType.ALLAPPS);
|
|
||||||
public static final String CONTAINER_PREDICTIONS = Integer.toString(ContainerType.PREDICTION);
|
|
||||||
public static final String CONTAINER_SEARCH = Integer.toString(ContainerType.SEARCHRESULT);
|
|
||||||
public static final String CONTAINER_OVERVIEW = Integer.toString(ContainerType.OVERVIEW);
|
|
||||||
|
|
||||||
|
|
||||||
public static final MainThreadInitializedObject<AppLaunchTracker> INSTANCE =
|
public static final MainThreadInitializedObject<AppLaunchTracker> INSTANCE =
|
||||||
forOverride(AppLaunchTracker.class, R.string.app_launch_tracker_class);
|
forOverride(AppLaunchTracker.class, R.string.app_launch_tracker_class);
|
||||||
|
|
||||||
public void onStartShortcut(String packageName, String shortcutId, UserHandle user,
|
|
||||||
@Nullable String container) { }
|
|
||||||
|
|
||||||
public void onStartApp(ComponentName componentName, UserHandle user,
|
|
||||||
@Nullable String container) { }
|
|
||||||
|
|
||||||
public void onDismissApp(ComponentName componentName, UserHandle user,
|
|
||||||
@Nullable String container){}
|
|
||||||
|
|
||||||
public void onReturnedToHome() { }
|
public void onReturnedToHome() { }
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ import com.android.launcher3.logger.LauncherAtom.SettingsContainer;
|
||||||
import com.android.launcher3.logger.LauncherAtom.ShortcutsContainer;
|
import com.android.launcher3.logger.LauncherAtom.ShortcutsContainer;
|
||||||
import com.android.launcher3.logger.LauncherAtom.TaskSwitcherContainer;
|
import com.android.launcher3.logger.LauncherAtom.TaskSwitcherContainer;
|
||||||
import com.android.launcher3.model.ModelWriter;
|
import com.android.launcher3.model.ModelWriter;
|
||||||
|
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||||
import com.android.launcher3.util.ContentWriter;
|
import com.android.launcher3.util.ContentWriter;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -285,6 +286,13 @@ public class ItemInfo {
|
||||||
.orElse(LauncherAtom.Application.newBuilder()));
|
.orElse(LauncherAtom.Application.newBuilder()));
|
||||||
break;
|
break;
|
||||||
case ITEM_TYPE_DEEP_SHORTCUT:
|
case ITEM_TYPE_DEEP_SHORTCUT:
|
||||||
|
itemBuilder
|
||||||
|
.setShortcut(nullableComponent
|
||||||
|
.map(component -> LauncherAtom.Shortcut.newBuilder()
|
||||||
|
.setShortcutName(component.flattenToShortString())
|
||||||
|
.setShortcutId(ShortcutKey.fromItemInfo(this).getId()))
|
||||||
|
.orElse(LauncherAtom.Shortcut.newBuilder()));
|
||||||
|
break;
|
||||||
case ITEM_TYPE_SHORTCUT:
|
case ITEM_TYPE_SHORTCUT:
|
||||||
itemBuilder
|
itemBuilder
|
||||||
.setShortcut(nullableComponent
|
.setShortcut(nullableComponent
|
||||||
|
|
|
@ -174,7 +174,7 @@ public abstract class SystemShortcut<T extends BaseDraggingActivity> extends Ite
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Intent intent = new PackageManagerHelper(view.getContext()).getMarketIntent(
|
Intent intent = new PackageManagerHelper(view.getContext()).getMarketIntent(
|
||||||
mItemInfo.getTargetComponent().getPackageName());
|
mItemInfo.getTargetComponent().getPackageName());
|
||||||
mTarget.startActivitySafely(view, intent, mItemInfo, null);
|
mTarget.startActivitySafely(view, intent, mItemInfo);
|
||||||
AbstractFloatingView.closeAllOpenViews(mTarget);
|
AbstractFloatingView.closeAllOpenViews(mTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
*/
|
*/
|
||||||
package com.android.launcher3.secondarydisplay;
|
package com.android.launcher3.secondarydisplay;
|
||||||
|
|
||||||
import static com.android.launcher3.model.AppLaunchTracker.CONTAINER_ALL_APPS;
|
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
|
@ -327,7 +325,7 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
|
||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
throw new IllegalArgumentException("Input must have a valid intent");
|
throw new IllegalArgumentException("Input must have a valid intent");
|
||||||
}
|
}
|
||||||
startActivitySafely(v, intent, item, CONTAINER_ALL_APPS);
|
startActivitySafely(v, intent, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package com.android.launcher3.touch;
|
||||||
import static com.android.launcher3.Launcher.REQUEST_BIND_PENDING_APPWIDGET;
|
import static com.android.launcher3.Launcher.REQUEST_BIND_PENDING_APPWIDGET;
|
||||||
import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET;
|
import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET;
|
||||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
|
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
|
||||||
import static com.android.launcher3.model.AppLaunchTracker.CONTAINER_ALL_APPS;
|
|
||||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_BY_PUBLISHER;
|
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_BY_PUBLISHER;
|
||||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
|
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
|
||||||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_QUIET_USER;
|
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_QUIET_USER;
|
||||||
|
@ -37,8 +36,6 @@ import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.launcher3.BubbleTextView;
|
import com.android.launcher3.BubbleTextView;
|
||||||
import com.android.launcher3.Launcher;
|
import com.android.launcher3.Launcher;
|
||||||
import com.android.launcher3.LauncherAppWidgetProviderInfo;
|
import com.android.launcher3.LauncherAppWidgetProviderInfo;
|
||||||
|
@ -72,13 +69,9 @@ public class ItemClickHandler {
|
||||||
/**
|
/**
|
||||||
* Instance used for click handling on items
|
* Instance used for click handling on items
|
||||||
*/
|
*/
|
||||||
public static final OnClickListener INSTANCE = getInstance(null);
|
public static final OnClickListener INSTANCE = ItemClickHandler::onClick;
|
||||||
|
|
||||||
public static final OnClickListener getInstance(String sourceContainer) {
|
private static void onClick(View v) {
|
||||||
return v -> onClick(v, sourceContainer);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void onClick(View v, String sourceContainer) {
|
|
||||||
// Make sure that rogue clicks don't get through while allapps is launching, or after the
|
// Make sure that rogue clicks don't get through while allapps is launching, or after the
|
||||||
// view has detached (it's possible for this to happen if the view is removed mid touch).
|
// view has detached (it's possible for this to happen if the view is removed mid touch).
|
||||||
if (v.getWindowToken() == null) return;
|
if (v.getWindowToken() == null) return;
|
||||||
|
@ -88,14 +81,14 @@ public class ItemClickHandler {
|
||||||
|
|
||||||
Object tag = v.getTag();
|
Object tag = v.getTag();
|
||||||
if (tag instanceof WorkspaceItemInfo) {
|
if (tag instanceof WorkspaceItemInfo) {
|
||||||
onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer);
|
onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher);
|
||||||
} else if (tag instanceof FolderInfo) {
|
} else if (tag instanceof FolderInfo) {
|
||||||
if (v instanceof FolderIcon) {
|
if (v instanceof FolderIcon) {
|
||||||
onClickFolderIcon(v);
|
onClickFolderIcon(v);
|
||||||
}
|
}
|
||||||
} else if (tag instanceof AppInfo) {
|
} else if (tag instanceof AppInfo) {
|
||||||
startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher,
|
startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher
|
||||||
sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer);
|
);
|
||||||
} else if (tag instanceof LauncherAppWidgetInfo) {
|
} else if (tag instanceof LauncherAppWidgetInfo) {
|
||||||
if (v instanceof PendingAppWidgetHostView) {
|
if (v instanceof PendingAppWidgetHostView) {
|
||||||
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
|
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
|
||||||
|
@ -191,7 +184,7 @@ public class ItemClickHandler {
|
||||||
|
|
||||||
// Fallback to using custom market intent.
|
// Fallback to using custom market intent.
|
||||||
Intent intent = new PackageManagerHelper(launcher).getMarketIntent(packageName);
|
Intent intent = new PackageManagerHelper(launcher).getMarketIntent(packageName);
|
||||||
launcher.startActivitySafely(v, intent, item, null);
|
launcher.startActivitySafely(v, intent, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -199,8 +192,7 @@ public class ItemClickHandler {
|
||||||
*
|
*
|
||||||
* @param v The view that was clicked. Must be a tagged with a {@link WorkspaceItemInfo}.
|
* @param v The view that was clicked. Must be a tagged with a {@link WorkspaceItemInfo}.
|
||||||
*/
|
*/
|
||||||
public static void onClickAppShortcut(View v, WorkspaceItemInfo shortcut, Launcher launcher,
|
public static void onClickAppShortcut(View v, WorkspaceItemInfo shortcut, Launcher launcher) {
|
||||||
@Nullable String sourceContainer) {
|
|
||||||
if (shortcut.isDisabled()) {
|
if (shortcut.isDisabled()) {
|
||||||
final int disabledFlags = shortcut.runtimeStatusFlags
|
final int disabledFlags = shortcut.runtimeStatusFlags
|
||||||
& WorkspaceItemInfo.FLAG_DISABLED_MASK;
|
& WorkspaceItemInfo.FLAG_DISABLED_MASK;
|
||||||
|
@ -241,11 +233,10 @@ public class ItemClickHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start activities
|
// Start activities
|
||||||
startAppShortcutOrInfoActivity(v, shortcut, launcher, sourceContainer);
|
startAppShortcutOrInfoActivity(v, shortcut, launcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher,
|
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
|
||||||
@Nullable String sourceContainer) {
|
|
||||||
TestLogging.recordEvent(
|
TestLogging.recordEvent(
|
||||||
TestProtocol.SEQUENCE_MAIN, "start: startAppShortcutOrInfoActivity");
|
TestProtocol.SEQUENCE_MAIN, "start: startAppShortcutOrInfoActivity");
|
||||||
Intent intent;
|
Intent intent;
|
||||||
|
@ -274,6 +265,6 @@ public class ItemClickHandler {
|
||||||
// Preload the icon to reduce latency b/w swapping the floating view with the original.
|
// Preload the icon to reduce latency b/w swapping the floating view with the original.
|
||||||
FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
|
FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
|
||||||
}
|
}
|
||||||
launcher.startActivitySafely(v, intent, item, sourceContainer);
|
launcher.startActivitySafely(v, intent, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,7 +220,7 @@ public class OptionsPopupView extends ArrowPopup
|
||||||
if (!TextUtils.isEmpty(pickerPackage)) {
|
if (!TextUtils.isEmpty(pickerPackage)) {
|
||||||
intent.setPackage(pickerPackage);
|
intent.setPackage(pickerPackage);
|
||||||
}
|
}
|
||||||
return launcher.startActivitySafely(v, intent, dummyInfo(intent), null);
|
return launcher.startActivitySafely(v, intent, dummyInfo(intent));
|
||||||
}
|
}
|
||||||
|
|
||||||
static WorkspaceItemInfo dummyInfo(Intent intent) {
|
static WorkspaceItemInfo dummyInfo(Intent intent) {
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2019 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.systemui.plugins;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
|
|
||||||
import com.android.systemui.plugins.annotations.ProvidesInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugin interface which sends app launch events.
|
|
||||||
*/
|
|
||||||
@ProvidesInterface(action = AppLaunchEventsPlugin.ACTION, version = AppLaunchEventsPlugin.VERSION)
|
|
||||||
public interface AppLaunchEventsPlugin extends Plugin {
|
|
||||||
String ACTION = "com.android.systemui.action.PLUGIN_APP_EVENTS";
|
|
||||||
int VERSION = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives onStartShortcut event from
|
|
||||||
* {@link com.android.launcher3.appprediction.PredictionAppTracker}.
|
|
||||||
*/
|
|
||||||
void onStartShortcut(String packageName, String shortcutId, UserHandle user, String container);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives onStartApp event from
|
|
||||||
* {@link com.android.launcher3.appprediction.PredictionAppTracker}.
|
|
||||||
*/
|
|
||||||
void onStartApp(ComponentName componentName, UserHandle user, String container);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives onDismissApp event from
|
|
||||||
* {@link com.android.launcher3.appprediction.PredictionAppTracker}.
|
|
||||||
*/
|
|
||||||
void onDismissApp(ComponentName componentName, UserHandle user, String container);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives onReturnedToHome event from
|
|
||||||
* {@link com.android.launcher3.appprediction.PredictionAppTracker}.
|
|
||||||
*/
|
|
||||||
void onReturnedToHome();
|
|
||||||
}
|
|
Loading…
Reference in New Issue