Merge "Initial draft of smart folder logging to clearcut pipeline." into ub-launcher3-master
This commit is contained in:
committed by
Android (Google) Code Review
commit
f40c579524
+2
-1
@@ -32,7 +32,7 @@ android_library {
|
||||
}
|
||||
|
||||
java_library_static {
|
||||
name: "launcher-log-protos-lite",
|
||||
name: "launcher_log_protos_lite",
|
||||
srcs: [
|
||||
"protos/*.proto",
|
||||
"proto_overrides/*.proto",
|
||||
@@ -45,4 +45,5 @@ java_library_static {
|
||||
"proto_overrides",
|
||||
],
|
||||
},
|
||||
static_libs: ["libprotobuf-java-lite"],
|
||||
}
|
||||
|
||||
+11
-3
@@ -48,7 +48,9 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \
|
||||
androidx.preference_preference \
|
||||
iconloader_base
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
LauncherPluginLib \
|
||||
launcher_log_protos_lite
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
$(call all-proto-files-under, protos) \
|
||||
@@ -144,7 +146,10 @@ LOCAL_USE_AAPT2 := true
|
||||
LOCAL_AAPT2_ONLY := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
SystemUISharedLib \
|
||||
launcherprotosnano \
|
||||
launcher_log_protos_lite
|
||||
ifneq (,$(wildcard frameworks/base))
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
else
|
||||
@@ -213,7 +218,10 @@ include $(CLEAR_VARS)
|
||||
LOCAL_USE_AAPT2 := true
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
SystemUISharedLib \
|
||||
launcherprotosnano \
|
||||
launcher_log_protos_lite
|
||||
ifneq (,$(wildcard frameworks/base))
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
else
|
||||
|
||||
@@ -58,6 +58,35 @@ message Target {
|
||||
optional TipType tip_type = 17;
|
||||
optional int32 search_query_length = 18;
|
||||
optional bool is_work_app = 19;
|
||||
optional FromFolderLabelState from_folder_label_state = 20;
|
||||
optional ToFolderLabelState to_folder_label_state = 21;
|
||||
|
||||
// Note: proto does not support duplicate enum values, even if they belong to different enum type.
|
||||
// Hence "FROM" and "TO" prefix added.
|
||||
enum FromFolderLabelState{
|
||||
FROM_FOLDER_LABEL_STATE_UNSPECIFIED = 0;
|
||||
FROM_EMPTY = 1;
|
||||
FROM_CUSTOM = 2;
|
||||
FROM_SUGGESTED = 3;
|
||||
}
|
||||
|
||||
enum ToFolderLabelState{
|
||||
TO_FOLDER_LABEL_STATE_UNSPECIFIED = 0;
|
||||
TO_SUGGESTION0_WITH_VALID_PRIMARY = 1;
|
||||
TO_SUGGESTION1_WITH_VALID_PRIMARY = 2;
|
||||
TO_SUGGESTION1_WITH_EMPTY_PRIMARY = 3;
|
||||
TO_SUGGESTION2_WITH_VALID_PRIMARY = 4;
|
||||
TO_SUGGESTION2_WITH_EMPTY_PRIMARY = 5;
|
||||
TO_SUGGESTION3_WITH_VALID_PRIMARY = 6;
|
||||
TO_SUGGESTION3_WITH_EMPTY_PRIMARY = 7;
|
||||
TO_EMPTY_WITH_VALID_SUGGESTIONS = 8;
|
||||
TO_EMPTY_WITH_EMPTY_SUGGESTIONS = 9;
|
||||
TO_EMPTY_WITH_SUGGESTIONS_DISABLED = 10;
|
||||
TO_CUSTOM_WITH_VALID_SUGGESTIONS = 11;
|
||||
TO_CUSTOM_WITH_EMPTY_SUGGESTIONS = 12;
|
||||
TO_CUSTOM_WITH_SUGGESTIONS_DISABLED = 13;
|
||||
UNCHANGED = 14;
|
||||
}
|
||||
}
|
||||
|
||||
// Used to define what type of item a Target would represent.
|
||||
@@ -141,7 +170,8 @@ message Action {
|
||||
AUTOMATED = 1;
|
||||
COMMAND = 2;
|
||||
TIP = 3;
|
||||
// SOFT_KEYBOARD, HARD_KEYBOARD, ASSIST
|
||||
SOFT_KEYBOARD = 4;
|
||||
// HARD_KEYBOARD, ASSIST
|
||||
}
|
||||
|
||||
enum Touch {
|
||||
|
||||
@@ -16,9 +16,23 @@
|
||||
|
||||
package com.android.launcher3.folder;
|
||||
|
||||
import static android.text.TextUtils.isEmpty;
|
||||
|
||||
import static androidx.core.util.Preconditions.checkNotNull;
|
||||
|
||||
import static com.android.launcher3.FolderInfo.FLAG_MANUAL_FOLDER_NAME;
|
||||
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
|
||||
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_CUSTOM;
|
||||
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_EMPTY;
|
||||
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_FOLDER_LABEL_STATE_UNSPECIFIED;
|
||||
import static com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState.FROM_SUGGESTED;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Arrays.stream;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -75,22 +89,24 @@ import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.logging.LoggerUtils;
|
||||
import com.android.launcher3.pageindicators.PageIndicatorDots;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
|
||||
import com.android.launcher3.userevent.LauncherLogProto.Action;
|
||||
import com.android.launcher3.userevent.LauncherLogProto.ContainerType;
|
||||
import com.android.launcher3.userevent.LauncherLogProto.ItemType;
|
||||
import com.android.launcher3.userevent.LauncherLogProto.LauncherEvent;
|
||||
import com.android.launcher3.userevent.LauncherLogProto.Target;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
import com.android.launcher3.views.ClipPathView;
|
||||
import com.android.launcher3.widget.PendingAddShortcutInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* Represents a set of icons chosen by the user or generated by the system.
|
||||
@@ -188,6 +204,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
@Thunk int mScrollHintDir = SCROLL_NONE;
|
||||
@Thunk int mCurrentScrollDir = SCROLL_NONE;
|
||||
|
||||
private String mPreviousLabel;
|
||||
private boolean mIsPreviousLabelSuggested;
|
||||
|
||||
/**
|
||||
* Used to inflate the Workspace from XML.
|
||||
*
|
||||
@@ -302,7 +321,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
public void startEditingFolderName() {
|
||||
post(() -> {
|
||||
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
|
||||
if (TextUtils.isEmpty(mFolderName.getText())) {
|
||||
if (isEmpty(mFolderName.getText())) {
|
||||
FolderNameInfo[] nameInfos =
|
||||
(FolderNameInfo[]) mInfo.suggestedFolderNames.getParcelableArrayExtra(
|
||||
FolderInfo.EXTRA_FOLDER_SUGGESTIONS);
|
||||
@@ -326,7 +345,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
}
|
||||
|
||||
mInfo.title = newTitle;
|
||||
mInfo.setOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME, mFolderName.isEnteredCompose(),
|
||||
mInfo.setOption(FLAG_MANUAL_FOLDER_NAME, mFolderName.isEnteredCompose(),
|
||||
mLauncher.getModelWriter());
|
||||
mFolderIcon.onTitleChanged(newTitle);
|
||||
mLauncher.getModelWriter().updateItemInDatabase(mInfo);
|
||||
@@ -337,7 +356,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
// suggested, apply different hint.
|
||||
mFolderName.setHint("");
|
||||
} else {
|
||||
if (TextUtils.isEmpty(mInfo.title)) {
|
||||
if (isEmpty(mInfo.title)) {
|
||||
mFolderName.setHint(R.string.folder_hint_text);
|
||||
mFolderName.setText("");
|
||||
} else {
|
||||
@@ -425,8 +444,10 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
mItemsInvalidated = true;
|
||||
mInfo.addListener(this);
|
||||
|
||||
if (!TextUtils.isEmpty(mInfo.title)) {
|
||||
if (!isEmpty(mInfo.title)) {
|
||||
mFolderName.setText(mInfo.title);
|
||||
mPreviousLabel = mInfo.title.toString();
|
||||
mIsPreviousLabelSuggested = !mInfo.hasOption(FLAG_MANUAL_FOLDER_NAME);
|
||||
mFolderName.setHint(null);
|
||||
} else {
|
||||
mFolderName.setText("");
|
||||
@@ -452,8 +473,8 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
|
||||
mInfo.suggestedFolderNames = new Intent().putExtra(FolderInfo.EXTRA_FOLDER_SUGGESTIONS,
|
||||
nameInfos);
|
||||
if (TextUtils.isEmpty(mFolderName.getText().toString())
|
||||
&& !mInfo.hasOption(FolderInfo.FLAG_MANUAL_FOLDER_NAME)) {
|
||||
if (isEmpty(mFolderName.getText().toString())
|
||||
&& !mInfo.hasOption(FLAG_MANUAL_FOLDER_NAME)) {
|
||||
showLabelSuggestion(nameInfos);
|
||||
}
|
||||
}
|
||||
@@ -469,14 +490,14 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
}
|
||||
// Open the Folder and Keyboard when the first or second suggestion is valid non-empty
|
||||
// string.
|
||||
boolean shouldOpen = nameInfos.length > 0 && nameInfos[0] != null && !TextUtils.isEmpty(
|
||||
boolean shouldOpen = nameInfos.length > 0 && nameInfos[0] != null && !isEmpty(
|
||||
nameInfos[0].getLabel())
|
||||
|| nameInfos.length > 1 && nameInfos[1] != null && !TextUtils.isEmpty(
|
||||
|| nameInfos.length > 1 && nameInfos[1] != null && !isEmpty(
|
||||
nameInfos[1].getLabel());
|
||||
CharSequence firstLabel = nameInfos[0].getLabel();
|
||||
|
||||
if (shouldOpen) {
|
||||
if (!TextUtils.isEmpty(firstLabel)) {
|
||||
if (!isEmpty(firstLabel)) {
|
||||
mFolderName.setHint("");
|
||||
mFolderName.setText(firstLabel);
|
||||
mInfo.title = firstLabel;
|
||||
@@ -484,7 +505,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
animateOpen(mInfo.contents, 0, true);
|
||||
mFolderName.showKeyboard();
|
||||
mFolderName.displayCompletions(
|
||||
Arrays.asList(nameInfos).subList(1, nameInfos.length).stream()
|
||||
asList(nameInfos).subList(1, nameInfos.length).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(s -> s.getLabel().toString())
|
||||
.collect(Collectors.toList()));
|
||||
@@ -636,9 +657,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
|
||||
if (!skipUserEventLog) {
|
||||
mLauncher.getUserEventDispatcher().logActionOnItem(
|
||||
Touch.TAP,
|
||||
Direction.NONE,
|
||||
ItemType.FOLDER_ICON, mInfo.cellX, mInfo.cellY);
|
||||
LauncherLogProto.Action.Touch.TAP,
|
||||
LauncherLogProto.Action.Direction.NONE,
|
||||
LauncherLogProto.ItemType.FOLDER_ICON, mInfo.cellX, mInfo.cellY);
|
||||
}
|
||||
|
||||
|
||||
@@ -1420,6 +1441,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
if (hasFocus) {
|
||||
startEditingFolderName();
|
||||
} else {
|
||||
logEditFolderLabel();
|
||||
mFolderName.dispatchBackKey();
|
||||
}
|
||||
}
|
||||
@@ -1433,11 +1455,12 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
|
||||
public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
|
||||
LauncherLogProto.Target targetParent) {
|
||||
target.gridX = info.cellX;
|
||||
target.gridY = info.cellY;
|
||||
target.pageIndex = mContent.getCurrentPage();
|
||||
targetParent.containerType = ContainerType.FOLDER;
|
||||
targetParent.containerType = LauncherLogProto.ContainerType.FOLDER;
|
||||
}
|
||||
|
||||
private class OnScrollHintListener implements OnAlarmListener {
|
||||
@@ -1535,7 +1558,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
|
||||
@Override
|
||||
public int getLogContainerType() {
|
||||
return ContainerType.FOLDER;
|
||||
return LauncherLogProto.ContainerType.FOLDER;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1570,7 +1593,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
}
|
||||
} else {
|
||||
mLauncher.getUserEventDispatcher().logActionTapOutside(
|
||||
LoggerUtils.newContainerTarget(ContainerType.FOLDER));
|
||||
LoggerUtils.newContainerTarget(LauncherLogProto.ContainerType.FOLDER));
|
||||
close(true);
|
||||
return true;
|
||||
}
|
||||
@@ -1600,4 +1623,112 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
super.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private void logEditFolderLabel() {
|
||||
LauncherEvent launcherEvent = LauncherEvent.newBuilder()
|
||||
.setAction(Action.newBuilder().setType(Action.Type.SOFT_KEYBOARD))
|
||||
.addSrcTarget(newEditTextTargetBuilder()
|
||||
.setFromFolderLabelState(getFromFolderLabelState())
|
||||
.setToFolderLabelState(getToFolderLabelState()))
|
||||
.addSrcTarget(newFolderTargetBuilder())
|
||||
.addSrcTarget(newParentContainerTarget())
|
||||
.build();
|
||||
mLauncher.getUserEventDispatcher().logLauncherEvent(launcherEvent);
|
||||
mPreviousLabel = mFolderName.getText().toString();
|
||||
mIsPreviousLabelSuggested = !mInfo.hasOption(FLAG_MANUAL_FOLDER_NAME);
|
||||
}
|
||||
|
||||
private Target.FromFolderLabelState getFromFolderLabelState() {
|
||||
return mPreviousLabel == null
|
||||
? FROM_FOLDER_LABEL_STATE_UNSPECIFIED
|
||||
: mPreviousLabel.isEmpty()
|
||||
? FROM_EMPTY
|
||||
: mIsPreviousLabelSuggested
|
||||
? FROM_SUGGESTED
|
||||
: FROM_CUSTOM;
|
||||
}
|
||||
|
||||
private Target.ToFolderLabelState getToFolderLabelState() {
|
||||
String newLabel =
|
||||
checkNotNull(mFolderName.getText().toString(),
|
||||
"Expected valid folder label, but found null");
|
||||
|
||||
Optional<String[]> suggestedLabels = Optional.ofNullable(
|
||||
(FolderNameInfo[]) mInfo.suggestedFolderNames
|
||||
.getParcelableArrayExtra(FolderInfo.EXTRA_FOLDER_SUGGESTIONS))
|
||||
.map(folderNameInfoArray ->
|
||||
stream(folderNameInfoArray)
|
||||
.map(FolderNameInfo::getLabel)
|
||||
.map(CharSequence::toString)
|
||||
.toArray(String[]::new));
|
||||
|
||||
|
||||
int accepted_suggestion_index = suggestedLabels
|
||||
.map(folderNameInfoArray ->
|
||||
IntStream.range(0, folderNameInfoArray.length)
|
||||
.filter(index -> newLabel.equalsIgnoreCase(
|
||||
folderNameInfoArray[index]))
|
||||
.findFirst()
|
||||
.orElse(-1)
|
||||
).orElse(-1);
|
||||
|
||||
boolean hasValidPrimary = suggestedLabels
|
||||
.map(labels -> labels.length > 0 && !isEmpty(labels[0]))
|
||||
.orElse(false);
|
||||
String primarySuffix = hasValidPrimary
|
||||
? "_WITH_VALID_PRIMARY"
|
||||
: "_WITH_EMPTY_PRIMARY";
|
||||
|
||||
boolean isEmptySuggestions = suggestedLabels
|
||||
.map(labels -> stream(labels).allMatch(TextUtils::isEmpty))
|
||||
.orElse(true);
|
||||
boolean isSuggestionsEnabled = FeatureFlags.FOLDER_NAME_SUGGEST.get();
|
||||
String suggestionsSuffix = isSuggestionsEnabled
|
||||
? isEmptySuggestions
|
||||
? "_WITH_EMPTY_SUGGESTIONS"
|
||||
: "_WITH_VALID_SUGGESTIONS"
|
||||
: "_WITH_SUGGESTIONS_DISABLED";
|
||||
|
||||
return newLabel.equals(mPreviousLabel)
|
||||
? Target.ToFolderLabelState.UNCHANGED
|
||||
: newLabel.isEmpty()
|
||||
? Target.ToFolderLabelState.valueOf("TO_EMPTY" + suggestionsSuffix)
|
||||
: accepted_suggestion_index >= 0
|
||||
? Target.ToFolderLabelState.valueOf("TO_SUGGESTION"
|
||||
+ accepted_suggestion_index
|
||||
+ primarySuffix)
|
||||
: Target.ToFolderLabelState.valueOf("TO_CUSTOM" + suggestionsSuffix);
|
||||
}
|
||||
|
||||
|
||||
private Target.Builder newEditTextTargetBuilder() {
|
||||
return Target.newBuilder().setType(Target.Type.ITEM).setItemType(ItemType.EDITTEXT);
|
||||
}
|
||||
|
||||
private Target.Builder newFolderTargetBuilder() {
|
||||
return Target.newBuilder()
|
||||
.setType(Target.Type.CONTAINER)
|
||||
.setContainerType(ContainerType.FOLDER)
|
||||
.setPageIndex(mInfo.screenId)
|
||||
.setGridX(mInfo.cellX)
|
||||
.setGridY(mInfo.cellY)
|
||||
.setCardinality(mInfo.contents.size());
|
||||
}
|
||||
|
||||
private Target.Builder newParentContainerTarget() {
|
||||
Target.Builder builder = Target.newBuilder().setType(Target.Type.CONTAINER);
|
||||
|
||||
switch (mInfo.container) {
|
||||
case CONTAINER_HOTSEAT:
|
||||
return builder.setContainerType(ContainerType.HOTSEAT);
|
||||
case CONTAINER_DESKTOP:
|
||||
return builder.setContainerType(ContainerType.WORKSPACE);
|
||||
default:
|
||||
throw new AssertionError(String
|
||||
.format("Expected container to be either %s or %s but found %s.",
|
||||
CONTAINER_HOTSEAT,
|
||||
CONTAINER_DESKTOP,
|
||||
mInfo.container));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +69,7 @@ import java.util.UUID;
|
||||
public class UserEventDispatcher implements ResourceBasedOverride {
|
||||
|
||||
private static final String TAG = "UserEvent";
|
||||
private static final boolean IS_VERBOSE =
|
||||
FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
|
||||
private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.USEREVENT);
|
||||
private static final String UUID_STORAGE = "uuid";
|
||||
|
||||
public static UserEventDispatcher newInstance(Context context,
|
||||
@@ -372,6 +371,25 @@ public class UserEventDispatcher implements ResourceBasedOverride {
|
||||
dispatchUserEvent(event, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs proto lite version of LauncherEvent object to clearcut.
|
||||
*/
|
||||
public void logLauncherEvent(
|
||||
com.android.launcher3.userevent.LauncherLogProto.LauncherEvent launcherEvent) {
|
||||
|
||||
if (mPreviousHomeGesture) {
|
||||
mPreviousHomeGesture = false;
|
||||
}
|
||||
mAppOrTaskLaunch = false;
|
||||
launcherEvent.toBuilder()
|
||||
.setElapsedContainerMillis(SystemClock.uptimeMillis() - mElapsedContainerMillis)
|
||||
.setElapsedSessionMillis(SystemClock.uptimeMillis() - mElapsedSessionMillis).build();
|
||||
if (!IS_VERBOSE) {
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, launcherEvent.toString());
|
||||
}
|
||||
|
||||
public void logDeepShortcutsOpen(View icon) {
|
||||
LogContainerProvider provider = StatsLogUtils.getLaunchProviderRecursive(icon);
|
||||
if (icon == null || !(icon.getTag() instanceof ItemInfo || provider == null)) {
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
|
||||
androidx.test.rules \
|
||||
androidx.test.uiautomator_uiautomator \
|
||||
mockito-target-minus-junit4 \
|
||||
launcher-log-protos-lite
|
||||
launcher_log_protos_lite
|
||||
|
||||
ifneq (,$(wildcard frameworks/base))
|
||||
LOCAL_PRIVATE_PLATFORM_APIS := true
|
||||
|
||||
Reference in New Issue
Block a user