Revert "Revert "Merge commit '8d14dbe041199d611839140f1c9285fd4174e9f4' ...""
This reverts commit 087a9e39b663dade90d8dfd74300e42575649b87.
Change-Id: I05b17a6e4aaaef6de3c2fa26aad45a39eb2833f9
diff --git a/Android.mk b/Android.mk
index 25f5412..349a134 100644
--- a/Android.mk
+++ b/Android.mk
@@ -36,18 +36,12 @@
launcher_log_protos_lite
LOCAL_SRC_FILES := \
- $(call all-proto-files-under, protos) \
- $(call all-proto-files-under, proto_overrides) \
$(call all-java-files-under, src_build_config) \
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/
-LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java
-
LOCAL_SDK_VERSION := current
LOCAL_MIN_SDK_VERSION := 26
LOCAL_MODULE := Launcher3CommonDepsLib
@@ -135,7 +129,6 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
SystemUI-statsd \
SystemUISharedLib \
- launcherprotosnano \
launcher_log_protos_lite
ifneq (,$(wildcard frameworks/base))
LOCAL_PRIVATE_PLATFORM_APIS := true
@@ -203,7 +196,6 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
SystemUI-statsd \
SystemUISharedLib \
- launcherprotosnano \
launcher_log_protos_lite
ifneq (,$(wildcard frameworks/base))
LOCAL_PRIVATE_PLATFORM_APIS := true
diff --git a/build.gradle b/build.gradle
index 534ca65..28a05d5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -82,7 +82,6 @@
manifest.srcFile 'AndroidManifest-common.xml'
proto {
srcDir 'protos/'
- srcDir 'proto_overrides/'
}
}
@@ -150,7 +149,6 @@
implementation "androidx.preference:preference:${ANDROID_X_VERSION}"
implementation project(':IconLoader')
withQuickstepImplementation project(':SharedLibWrapper')
- implementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/libs", include: 'launcher_protos.jar')
// Recents lib dependency
withQuickstepImplementation fileTree(dir: "${FRAMEWORK_PREBUILTS_DIR}/quickstep/libs", include: 'sysui_shared.jar')
@@ -171,20 +169,16 @@
protobuf {
// Configure the protoc executable
protoc {
- artifact = 'com.google.protobuf:protoc:3.0.0'
-
- generateProtoTasks {
- all().each { task ->
- task.builtins {
- remove java
- javanano {
- option "java_package=launcher_log_extension.proto|com.android.launcher3.userevent.nano"
- option "java_package=launcher_log.proto|com.android.launcher3.userevent.nano"
- option "java_package=launcher_dump.proto|com.android.launcher3.model.nano"
- option "enum_style=java"
- }
+ artifact = "com.google.protobuf:protoc:${protocVersion}"
+ }
+ generateProtoTasks {
+ all().each { task ->
+ task.builtins {
+ remove java
+ java {
+ option "lite"
}
}
}
}
-}
+}
\ No newline at end of file
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
deleted file mode 100644
index 9423cb2..0000000
--- a/protos/launcher_log.proto
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-syntax = "proto2";
-
-import "launcher_log_extension.proto";
-
-option java_package = "com.android.launcher3.userevent";
-option java_outer_classname = "LauncherLogProto";
-
-package userevent;
-
-message Target {
- enum Type {
- NONE = 0;
- ITEM = 1;
- CONTROL = 2;
- CONTAINER = 3;
- }
-
- optional Type type = 1;
-
- // For container type and item type
- // Used mainly for ContainerType.FOLDER, ItemType.*
- optional int32 page_index = 2;
- optional int32 rank = 3;
- optional int32 grid_x = 4;
- optional int32 grid_y = 5;
-
- // For container types only
- optional ContainerType container_type = 6;
- optional int32 cardinality = 7;
-
- // For control types only
- optional ControlType control_type = 8;
-
- // For item types only
- optional ItemType item_type = 9;
- optional int32 package_name_hash = 10;
- optional int32 component_hash = 11; // Used for ItemType.WIDGET
- optional int32 intent_hash = 12; // Used for ItemType.SHORTCUT
- optional int32 span_x = 13 [default = 1];// Used for ItemType.WIDGET
- optional int32 span_y = 14 [default = 1];// Used for ItemType.WIDGET
- optional int32 predictedRank = 15;
- optional TargetExtension extension = 16;
- 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 [deprecated = true];
- TO_EMPTY_WITH_VALID_PRIMARY = 15;
- TO_EMPTY_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY = 16;
- TO_EMPTY_WITH_EMPTY_SUGGESTIONS = 9;
- TO_EMPTY_WITH_SUGGESTIONS_DISABLED = 10;
- TO_CUSTOM_WITH_VALID_SUGGESTIONS = 11 [deprecated = true];
- TO_CUSTOM_WITH_VALID_PRIMARY = 17;
- TO_CUSTOM_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY = 18;
- 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.
-enum ItemType {
- DEFAULT_ITEMTYPE = 0;
- APP_ICON = 1;
- SHORTCUT = 2;
- WIDGET = 3;
- FOLDER_ICON = 4;
- DEEPSHORTCUT = 5;
- SEARCHBOX = 6;
- EDITTEXT = 7;
- NOTIFICATION = 8;
- TASK = 9; // Each page of Recents UI (QuickStep)
- WEB_APP = 10;
- TASK_ICON = 11;
-}
-
-// Used to define what type of container a Target would represent.
-enum ContainerType {
- DEFAULT_CONTAINERTYPE = 0;
- WORKSPACE = 1;
- HOTSEAT = 2;
- FOLDER = 3;
- ALLAPPS = 4;
- WIDGETS = 5;
- OVERVIEW = 6; // Zoomed out workspace (without QuickStep)
- PREDICTION = 7;
- SEARCHRESULT = 8;
- DEEPSHORTCUTS = 9;
- PINITEM = 10; // confirmation screen
- NAVBAR = 11;
- TASKSWITCHER = 12; // Recents UI Container (QuickStep)
- APP = 13; // Foreground activity is another app (QuickStep)
- TIP = 14; // Onboarding texts (QuickStep)
- OTHER_LAUNCHER_APP = 15;
-}
-
-// Used to define what type of control a Target would represent.
-enum ControlType {
- DEFAULT_CONTROLTYPE = 0;
- ALL_APPS_BUTTON = 1;
- WIDGETS_BUTTON = 2;
- WALLPAPER_BUTTON = 3;
- SETTINGS_BUTTON = 4;
- REMOVE_TARGET = 5;
- UNINSTALL_TARGET = 6;
- APPINFO_TARGET = 7;
- RESIZE_HANDLE = 8;
- VERTICAL_SCROLL = 9;
- HOME_INTENT = 10; // Deprecated, use enum Command instead
- BACK_BUTTON = 11;
- QUICK_SCRUB_BUTTON = 12;
- CLEAR_ALL_BUTTON = 13;
- CANCEL_TARGET = 14;
- TASK_PREVIEW = 15;
- SPLIT_SCREEN_TARGET = 16;
- REMOTE_ACTION_SHORTCUT = 17;
- APP_USAGE_SETTINGS = 18;
- BACK_GESTURE = 19;
- UNDO = 20;
- DISMISS_PREDICTION = 21;
- HYBRID_HOTSEAT_ACCEPTED = 22;
- HYBRID_HOTSEAT_CANCELED = 23;
- OVERVIEW_ACTIONS_SHARE_BUTTON = 24;
- OVERVIEW_ACTIONS_SCREENSHOT_BUTTON = 25;
- OVERVIEW_ACTIONS_SELECT_BUTTON = 26;
- SELECT_MODE_CLOSE_BUTTON = 27;
- SELECT_MODE_ITEM = 28;
-}
-
-enum TipType {
- DEFAULT_NONE = 0;
- BOUNCE = 1;
- SWIPE_UP_TEXT = 2;
- QUICK_SCRUB_TEXT = 3;
- PREDICTION_TEXT = 4;
- DWB_TOAST = 5;
- HYBRID_HOTSEAT = 6;
-}
-
-// Used to define the action component of the LauncherEvent.
-message Action {
- enum Type {
- TOUCH = 0;
- AUTOMATED = 1;
- COMMAND = 2;
- TIP = 3;
- SOFT_KEYBOARD = 4;
- // HARD_KEYBOARD, ASSIST
- }
-
- enum Touch {
- TAP = 0;
- LONGPRESS = 1;
- DRAGDROP = 2;
- SWIPE = 3;
- FLING = 4;
- PINCH = 5;
- SWIPE_NOOP = 6;
- }
-
- enum Direction {
- NONE = 0;
- UP = 1;
- DOWN = 2;
- LEFT = 3;
- RIGHT = 4;
- UPRIGHT = 5;
- UPLEFT = 6;
- }
- enum Command {
- HOME_INTENT = 0;
- BACK = 1;
- ENTRY = 2; // Indicates entry to one of Launcher container type target
- // not using the HOME_INTENT
- CANCEL = 3; // Indicates that a confirmation screen was cancelled
- CONFIRM = 4; // Indicates thata confirmation screen was accepted
- STOP = 5; // Indicates onStop() was called (screen time out, power off)
- RECENTS_BUTTON = 6; // Indicates that Recents button was pressed
- RESUME = 7; // Indicates onResume() was called
- }
-
- optional Type type = 1;
- optional Touch touch = 2;
- optional Direction dir = 3;
- optional Command command = 4;
- // Log if the action was performed on outside of the container
- optional bool is_outside = 5;
- optional bool is_state_change = 6;
-}
-
-//
-// Context free grammar of typical user interaction:
-// Action (Touch) + Target
-// Action (Touch) + Target + Target
-//
-message LauncherEvent {
- required Action action = 1;
- // List of targets that touch actions can be operated on.
- repeated Target src_target = 2;
- repeated Target dest_target = 3;
-
- optional int64 action_duration_millis = 4;
- optional int64 elapsed_container_millis = 5;
- optional int64 elapsed_session_millis = 6;
-
- optional bool is_in_multi_window_mode = 7 [deprecated = true];
- optional bool is_in_landscape_mode = 8 [deprecated = true];
-
- optional LauncherEventExtension extension = 9;
-}
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index 43bf0ea..52475df 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -13,7 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.quickstep.interaction.RootSandboxLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground">
@@ -93,11 +94,11 @@
style="@style/TextAppearance.GestureTutorial.Feedback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_above="@id/gesture_tutorial_fragment_action_button"
+ android:layout_below="@id/gesture_tutorial_fragment_titles_container"
android:layout_centerHorizontal="true"
android:layout_marginStart="@dimen/gesture_tutorial_feedback_margin_start_end"
android:layout_marginEnd="@dimen/gesture_tutorial_feedback_margin_start_end"
- android:layout_marginBottom="10dp"/>
+ android:layout_marginTop="40dp"/>
<!-- android:stateListAnimator="@null" removes shadow and normal on click behavior (increase
of elevation and shadow) which is replaced by ripple effect in android:foreground -->
@@ -126,4 +127,4 @@
android:background="@null"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:stateListAnimator="@null"/>
-</RelativeLayout>
\ No newline at end of file
+</com.android.quickstep.interaction.RootSandboxLayout>
\ No newline at end of file
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 86120e3..4b45b10 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -149,6 +149,21 @@
<!-- Feedback shown during interactive parts of Assistant gesture tutorial when the gesture doesn't go far enough. [CHAR LIMIT=100] -->
<string name="assistant_gesture_feedback_swipe_not_long_enough" translatable="false">Try swiping further</string>
+ <!-- Title shown in sandbox mode part of gesture tutorial. [CHAR LIMIT=30] -->
+ <string name="sandbox_mode_title" translatable="false">Sandbox Mode</string>
+ <!-- Subtitle shown in sandbox mode part of gesture tutorial. [CHAR LIMIT=60] -->
+ <string name="sandbox_mode_subtitle" translatable="false">Try any navigation gesture</string>
+ <!-- Feedback shown in sandbox mode when the back gesture is successfully issued. [CHAR LIMIT=60] -->
+ <string name="sandbox_mode_back_gesture_feedback_successful" translatable="false">Back gesture successful</string>
+ <!-- Feedback shown in sandbox mode when the assistant gesture is a successfully issued. [CHAR LIMIT=60] -->
+ <string name="sandbox_mode_assistant_gesture_feedback_successful" translatable="false">Assistant gesture successful</string>
+ <!-- Feedback shown in sandbox mode when the home gesture is a successfully issued. [CHAR LIMIT=60] -->
+ <string name="sandbox_mode_home_gesture_feedback_successful" translatable="false">Home gesture successful</string>
+ <!-- Feedback shown in sandbox mode when the overview gesture is a successfully issued. [CHAR LIMIT=60] -->
+ <string name="sandbox_mode_overview_gesture_feedback_successful" translatable="false">Overview gesture successful</string>
+ <!-- Feedback shown in sandbox mode when the back gesture swipe is too far from the edge. [CHAR LIMIT=60] -->
+ <string name="sandbox_mode_back_gesture_feedback_swipe_too_far_from_edge" translatable="false">Make sure you swipe from the left/right edge of the screen</string>
+
<!-- Title shown on the confirmation screen after successful gesture. [CHAR LIMIT=30] -->
<string name="gesture_tutorial_confirm_title" translatable="false">All set</string>
<!-- Button text shown on a button on the confirm screen to leave the tutorial. [CHAR LIMIT=14] -->
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index bc3b4ab..44d43c6 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -22,6 +22,8 @@
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
+
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.app.ActivityOptions;
@@ -319,4 +321,10 @@
public void setHintUserWillBeActive() {
addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
}
+
+ @Override
+ public void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ InteractionJankMonitorWrapper.init(getWindow().getDecorView());
+ }
}
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index b35b33c..5c8463c 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -34,8 +34,7 @@
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@TargetApi(Build.VERSION_CODES.P)
-public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat,
- WrappedAnimationRunnerImpl {
+public abstract class LauncherAnimationRunner implements RemoteAnimationRunnerCompat {
private static final String TAG = "LauncherAnimationRunner";
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index b53e834..057c0f4 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -66,6 +66,7 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.shortcuts.DeepShortcutView;
@@ -81,6 +82,7 @@
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat;
@@ -795,6 +797,36 @@
== PackageManager.PERMISSION_GRANTED;
}
+ private void addCujInstrumentation(Animator anim, int cuj, String transition) {
+ if (Trace.isEnabled()) {
+ anim.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ Trace.beginAsyncSection(transition, 0);
+ InteractionJankMonitorWrapper.begin(cuj);
+ super.onAnimationStart(animation);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ InteractionJankMonitorWrapper.cancel(cuj);
+ }
+
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ InteractionJankMonitorWrapper.end(cuj);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ Trace.endAsyncSection(TRANSITION_OPEN_LAUNCHER, 0);
+ }
+ });
+ }
+ }
+
/**
* Remote animation runner for animation from the app to Launcher, including recents.
*/
@@ -859,21 +891,9 @@
// is initialized.
if (launcherIsATargetWithMode(appTargets, MODE_OPENING)
|| mLauncher.isForceInvisible()) {
- if (Trace.isEnabled()) {
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- Trace.beginAsyncSection(TRANSITION_OPEN_LAUNCHER, 0);
- super.onAnimationStart(animation);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- Trace.endAsyncSection(TRANSITION_OPEN_LAUNCHER, 0);
- }
- });
- }
+ addCujInstrumentation(
+ anim, InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME,
+ TRANSITION_OPEN_LAUNCHER);
// Only register the content animation for cancellation when state changes
mLauncher.getStateManager().setCurrentAnimation(anim);
@@ -942,25 +962,12 @@
launcherClosing);
}
- if (Trace.isEnabled()) {
- final String section =
- launchingFromRecents
- ? TRANSITION_LAUNCH_FROM_RECENTS : TRANSITION_LAUNCH_FROM_ICON;
-
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- Trace.beginAsyncSection(section, 0);
- super.onAnimationStart(animation);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- Trace.endAsyncSection(section, 0);
- }
- });
- }
+ addCujInstrumentation(anim,
+ launchingFromRecents
+ ? InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_RECENTS
+ : InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON,
+ launchingFromRecents
+ ? TRANSITION_LAUNCH_FROM_RECENTS : TRANSITION_LAUNCH_FROM_ICON);
if (launcherClosing) {
anim.addListener(mForceInvisibleListener);
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index d3c4c3d..5b066c6 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -16,11 +16,8 @@
package com.android.launcher3.appprediction;
-import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.logging.LoggerUtils.newTarget;
import android.annotation.TargetApi;
import android.content.Context;
@@ -43,7 +40,6 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsSectionDecorator;
import com.android.launcher3.allapps.FloatingHeaderRow;
@@ -53,13 +49,11 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.keyboard.FocusIndicatorHelper;
import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper;
-import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.Themes;
import com.android.quickstep.AnimatedFloat;
@@ -68,7 +62,7 @@
@TargetApi(Build.VERSION_CODES.P)
public class PredictionRowView extends LinearLayout implements
- LogContainerProvider, OnDeviceProfileChangeListener, FloatingHeaderRow {
+ OnDeviceProfileChangeListener, FloatingHeaderRow {
private static final IntProperty<PredictionRowView> TEXT_ALPHA =
new IntProperty<PredictionRowView>("textAlpha") {
@@ -271,29 +265,6 @@
mParent.onHeightUpdated();
}
- @Override
- public void fillInLogContainerData(ItemInfo childInfo, LauncherLogProto.Target child,
- ArrayList<LauncherLogProto.Target> parents) {
- for (int i = 0; i < mPredictedApps.size(); i++) {
- ItemInfoWithIcon appInfo = mPredictedApps.get(i);
- if (appInfo == childInfo) {
- child.predictedRank = i;
- break;
- }
- }
- parents.add(newContainerTarget(LauncherLogProto.ContainerType.PREDICTION));
-
- // include where the prediction is coming this used to be Launcher#modifyUserEvent
- LauncherLogProto.Target parent = newTarget(LauncherLogProto.Target.Type.CONTAINER);
- LauncherState state = mLauncher.getStateManager().getState();
- if (state == LauncherState.ALL_APPS) {
- parent.containerType = LauncherLogProto.ContainerType.ALLAPPS;
- } else if (state == OVERVIEW) {
- parent.containerType = LauncherLogProto.ContainerType.TASKSWITCHER;
- }
- parents.add(parent);
- }
-
public void setTextAlpha(int textAlpha) {
mIconLastSetTextAlpha = textAlpha;
if (getAlpha() < 1 && textAlpha > 0) {
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 151a113..3807350 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -55,7 +55,6 @@
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.views.ArrowTipView;
import com.android.launcher3.views.Snackbar;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index bce73cd..a2e3bdf 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -16,6 +16,7 @@
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
import android.content.Context;
@@ -23,7 +24,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.allapps.AllAppsContainerView;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
* Definition for AllApps state
@@ -40,7 +40,7 @@
};
public AllAppsState(int id) {
- super(id, ContainerType.ALLAPPS, STATE_FLAGS);
+ super(id, LAUNCHER_STATE_ALLAPPS, STATE_FLAGS);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 8ff05f2..4b4f955 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -15,12 +15,13 @@
*/
package com.android.launcher3.uioverrides.states;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+
import android.content.Context;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.Launcher;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -33,7 +34,7 @@
| FLAG_WORKSPACE_INACCESSIBLE | FLAG_NON_INTERACTIVE | FLAG_CLOSE_POPUPS;
public BackgroundAppState(int id) {
- this(id, LauncherLogProto.ContainerType.TASKSWITCHER);
+ this(id, LAUNCHER_STATE_BACKGROUND);
}
protected BackgroundAppState(int id, int logContainer) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index fc0dcd5..41c689d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -15,13 +15,14 @@
*/
package com.android.launcher3.uioverrides.states;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
+
import android.content.Context;
import android.graphics.Rect;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.views.RecentsView;
/**
@@ -34,7 +35,7 @@
FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_WORKSPACE_INACCESSIBLE;
public OverviewModalTaskState(int id) {
- super(id, ContainerType.OVERVIEW, STATE_FLAGS);
+ super(id, LAUNCHER_STATE_OVERVIEW, STATE_FLAGS);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index bbe7821..525ff58 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -16,6 +16,7 @@
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.SysUINavigationMode.hideShelfInTwoButtonLandscape;
import static com.android.quickstep.SysUINavigationMode.removeShelfFromOverview;
@@ -29,7 +30,6 @@
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -51,7 +51,7 @@
}
protected OverviewState(int id, int stateFlags) {
- this(id, ContainerType.TASKSWITCHER, stateFlags);
+ this(id, LAUNCHER_STATE_OVERVIEW, stateFlags);
}
protected OverviewState(int id, int logContainer, int stateFlags) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index 2c7373e..51e72da 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -15,8 +15,9 @@
*/
package com.android.launcher3.uioverrides.states;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+
import com.android.launcher3.Launcher;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
/**
* State to indicate we are about to launch a recent task. Note that this state is only used when
@@ -26,7 +27,7 @@
public class QuickSwitchState extends BackgroundAppState {
public QuickSwitchState(int id) {
- super(id, LauncherLogProto.ContainerType.APP);
+ super(id, LAUNCHER_STATE_BACKGROUND);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
index bef191e..7a0f634 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/LandscapeEdgeSwipeController.java
@@ -12,8 +12,6 @@
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.quickstep.SystemUiProxy;
/**
@@ -46,11 +44,6 @@
}
@Override
- protected int getLogContainerTypeForNormalState(MotionEvent ev) {
- return LauncherLogProto.ContainerType.NAVBAR;
- }
-
- @Override
protected float getShiftRange() {
return mLauncher.getDragLayer().getWidth();
}
@@ -65,13 +58,8 @@
}
@Override
- protected int getDirectionForLog() {
- return mLauncher.getDeviceProfile().isSeascape() ? Direction.RIGHT : Direction.LEFT;
- }
-
- @Override
- protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
- super.onSwipeInteractionCompleted(targetState, logAction);
+ protected void onSwipeInteractionCompleted(LauncherState targetState) {
+ super.onSwipeInteractionCompleted(targetState);
if (mStartState == NORMAL && targetState == OVERVIEW) {
SystemUiProxy.INSTANCE.get(mLauncher).onOverviewShown(true, TAG);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index 7616844..d210bc6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -45,12 +45,9 @@
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.OverviewScrim;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.AssistantUtilities;
@@ -211,7 +208,6 @@
@Override
public void onDragEnd(float velocity) {
boolean fling = mSwipeDetector.isFling(velocity);
- final int logAction = fling ? Touch.FLING : Touch.SWIPE;
float progress = mCurrentAnimation.getProgressFraction();
float interpolatedProgress = PULLBACK_INTERPOLATOR.getInterpolation(progress);
boolean success = interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS
@@ -230,7 +226,7 @@
() -> onSwipeInteractionCompleted(mEndState));
}
if (mStartState != mEndState) {
- // TODO: add to WW log
+ logHomeGesture();
}
AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(mLauncher);
if (topOpenView != null) {
@@ -255,17 +251,10 @@
AccessibilityManagerCompat.sendStateEventToTest(mLauncher, targetState.ordinal);
}
- private void logStateChange(int startContainerType, int logAction) {
- mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
- LauncherLogProto.Action.Direction.UP,
- mSwipeDetector.getDownX(), mSwipeDetector.getDownY(),
- LauncherLogProto.ContainerType.NAVBAR,
- startContainerType,
- mEndState.containerType,
- mLauncher.getWorkspace().getCurrentPage());
+ private void logHomeGesture() {
mLauncher.getStatsLogManager().logger()
- .withSrcState(StatsLogManager.containerTypeToAtomState(mStartState.containerType))
- .withDstState(StatsLogManager.containerTypeToAtomState(mEndState.containerType))
+ .withSrcState(mStartState.statsLogOrdinal)
+ .withDstState(mEndState.statsLogOrdinal)
.log(LAUNCHER_HOME_GESTURE);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index c78d474..2a3bdbf 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -49,7 +49,6 @@
import com.android.launcher3.graphics.OverviewScrim;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AnimatorControllerWithResistance;
@@ -207,7 +206,7 @@
private void maybeSwipeInteractionToOverviewComplete() {
if (mReachedOverview && mDetector.isSettlingState()) {
- onSwipeInteractionCompleted(OVERVIEW, Touch.SWIPE);
+ onSwipeInteractionCompleted(OVERVIEW);
}
}
@@ -251,7 +250,7 @@
private void goToOverviewOrHomeOnDragEnd(float velocity) {
boolean goToHomeInsteadOfOverview = !mMotionPauseDetector.isPaused();
if (goToHomeInsteadOfOverview) {
- new OverviewToHomeAnim(mLauncher, ()-> onSwipeInteractionCompleted(NORMAL, Touch.FLING))
+ new OverviewToHomeAnim(mLauncher, ()-> onSwipeInteractionCompleted(NORMAL))
.animateWithVelocity(velocity);
}
if (mReachedOverview) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index a6a3497..f378848 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -57,13 +57,9 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.graphics.OverviewScrim;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.BaseSwipeDetector;
import com.android.launcher3.touch.BothAxesSwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.AnimatedFloat;
@@ -287,7 +283,6 @@
boolean horizontalFling = mSwipeDetector.isFling(velocity.x);
boolean verticalFling = mSwipeDetector.isFling(velocity.y);
boolean noFling = !horizontalFling && !verticalFling;
- int logAction = noFling ? Touch.SWIPE : Touch.FLING;
if (mMotionPauseDetector.isPaused() && noFling) {
cancelAnimations();
@@ -298,7 +293,7 @@
overviewAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- onAnimationToStateCompleted(OVERVIEW, logAction);
+ onAnimationToStateCompleted(OVERVIEW);
}
});
overviewAnim.start();
@@ -393,7 +388,7 @@
}
nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
- mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState, logAction));
+ mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState));
cancelAnimations();
xOverviewAnim.start();
@@ -401,27 +396,17 @@
nonOverviewAnim.start();
}
- private void onAnimationToStateCompleted(LauncherState targetState, int logAction) {
- mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
- getDirectionForLog(), mSwipeDetector.getDownX(), mSwipeDetector.getDownY(),
- LauncherLogProto.ContainerType.NAVBAR,
- mStartState.containerType,
- targetState.containerType,
- mLauncher.getWorkspace().getCurrentPage());
+ private void onAnimationToStateCompleted(LauncherState targetState) {
mLauncher.getStatsLogManager().logger()
.withSrcState(LAUNCHER_STATE_HOME)
- .withDstState(StatsLogManager.containerTypeToAtomState(targetState.containerType))
- .log(getLauncherAtomEvent(mStartState.containerType, targetState.containerType,
+ .withDstState(targetState.statsLogOrdinal)
+ .log(getLauncherAtomEvent(mStartState.statsLogOrdinal, targetState.statsLogOrdinal,
targetState.ordinal > mStartState.ordinal
? LAUNCHER_UNKNOWN_SWIPEUP
: LAUNCHER_UNKNOWN_SWIPEDOWN));
mLauncher.getStateManager().goToState(targetState, false, this::clearState);
}
- private int getDirectionForLog() {
- return Utilities.isRtl(mLauncher.getResources()) ? Direction.LEFT : Direction.RIGHT;
- }
-
private void cancelAnimations() {
if (mNonOverviewAnim != null) {
mNonOverviewAnim.getAnimationPlayer().cancel();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java
index 9091168..45e5e2f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/OverviewToAllAppsTouchController.java
@@ -25,7 +25,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.views.RecentsView;
@@ -73,9 +72,4 @@
}
return fromState;
}
-
- @Override
- protected int getLogContainerTypeForNormalState(MotionEvent ev) {
- return LauncherLogProto.ContainerType.WORKSPACE;
- }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index 059a703..037d988 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -48,8 +48,6 @@
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.uioverrides.states.OverviewState;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.LayoutUtils;
@@ -172,11 +170,6 @@
return fromState;
}
- @Override
- protected int getLogContainerTypeForNormalState(MotionEvent ev) {
- return isTouchOverHotseat(mLauncher, ev) ? ContainerType.HOTSEAT : ContainerType.WORKSPACE;
- }
-
private StateAnimationConfig getNormalToOverviewAnimation() {
mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR;
@@ -285,7 +278,7 @@
private void cancelPendingAnim() {
if (mPendingAnimation != null) {
- mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation.finish(false);
mPendingAnimation = null;
}
}
@@ -320,8 +313,8 @@
}
@Override
- protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
- super.onSwipeInteractionCompleted(targetState, logAction);
+ protected void onSwipeInteractionCompleted(LauncherState targetState) {
+ super.onSwipeInteractionCompleted(targetState);
if (mStartState == NORMAL && targetState == OVERVIEW) {
SystemUiProxy.INSTANCE.get(mLauncher).onOverviewShown(true, TAG);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index c643858..b8c2030 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
@@ -41,8 +42,6 @@
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
@@ -92,14 +91,14 @@
@Override
public void onDragStart(boolean start, float startDisplacement) {
super.onDragStart(start, startDisplacement);
- mStartContainerType = LauncherLogProto.ContainerType.NAVBAR;
+ mStartContainerType = LAUNCHER_STATE_BACKGROUND;
ActivityManagerWrapper.getInstance()
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
}
@Override
- protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
- super.onSwipeInteractionCompleted(targetState, logAction);
+ protected void onSwipeInteractionCompleted(LauncherState targetState) {
+ super.onSwipeInteractionCompleted(targetState);
}
@Override
@@ -153,14 +152,4 @@
protected float getShiftRange() {
return mLauncher.getDeviceProfile().widthPx / 2f;
}
-
- @Override
- protected int getLogContainerTypeForNormalState(MotionEvent ev) {
- return LauncherLogProto.ContainerType.NAVBAR;
- }
-
- @Override
- protected int getDirectionForLog() {
- return Utilities.isRtl(mLauncher.getResources()) ? Direction.LEFT : Direction.RIGHT;
- }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
index 16bd9ed..fe69c9b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
@@ -15,10 +15,12 @@
*/
package com.android.launcher3.uioverrides.touchcontrollers;
+import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
-import static android.view.MotionEvent.ACTION_CANCEL;
+
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN;
import android.graphics.PointF;
import android.util.SparseArray;
@@ -31,12 +33,9 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-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.util.TouchController;
-
import com.android.quickstep.SystemUiProxy;
+
import java.io.PrintWriter;
/**
@@ -133,9 +132,8 @@
int action = ev.getAction();
if (action == ACTION_UP || action == ACTION_CANCEL) {
dispatchTouchEvent(ev);
- mLauncher.getUserEventDispatcher().logActionOnContainer(action == ACTION_UP ?
- Touch.FLING : Touch.SWIPE, Direction.DOWN, ContainerType.WORKSPACE,
- mLauncher.getWorkspace().getCurrentPage());
+ mLauncher.getStatsLogManager().logger()
+ .log(LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN);
setWindowSlippery(false);
return true;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index df6194d..186caf6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -36,7 +36,6 @@
import com.android.launcher3.touch.BaseSwipeDetector;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.FlingBlockCheck;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
@@ -203,7 +202,7 @@
mCurrentAnimation.setPlayFraction(0);
}
if (mPendingAnimation != null) {
- mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation.finish(false);
mPendingAnimation = null;
}
@@ -285,7 +284,6 @@
public void onDragEnd(float velocity) {
boolean fling = mDetector.isFling(velocity);
final boolean goingToEnd;
- final int logAction;
boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
if (blockedFling) {
fling = false;
@@ -294,11 +292,9 @@
float progress = mCurrentAnimation.getProgressFraction();
float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress();
if (fling) {
- logAction = Touch.FLING;
boolean goingUp = orientationHandler.isGoingUp(velocity, mIsRtl);
goingToEnd = goingUp == mCurrentAnimationIsGoingUp;
} else {
- logAction = Touch.SWIPE;
goingToEnd = interpolatedProgress > SUCCESS_TRANSITION_PROGRESS;
}
long animationDuration = BaseSwipeDetector.calculateDuration(
@@ -307,14 +303,14 @@
animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity);
}
- mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd, logAction));
+ mCurrentAnimation.setEndAction(() -> onCurrentAnimationEnd(goingToEnd));
mCurrentAnimation.startWithVelocity(mActivity, goingToEnd,
velocity, mEndDisplacement, animationDuration);
}
- private void onCurrentAnimationEnd(boolean wasSuccess, int logAction) {
+ private void onCurrentAnimationEnd(boolean wasSuccess) {
if (mPendingAnimation != null) {
- mPendingAnimation.finish(wasSuccess, logAction);
+ mPendingAnimation.finish(wasSuccess);
mPendingAnimation = null;
}
clearState();
@@ -326,7 +322,7 @@
mTaskBeingDragged = null;
mCurrentAnimation = null;
if (mPendingAnimation != null) {
- mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation.finish(false);
mPendingAnimation = null;
}
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 5fc9cca..91d4c64 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -76,12 +76,8 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.testing.TestProtocol;
-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.util.TraceHelper;
import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.WindowBounds;
@@ -104,6 +100,7 @@
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputConsumerController;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.TaskInfoCompat;
@@ -222,8 +219,7 @@
private boolean mPassedOverviewThreshold;
private boolean mGestureStarted;
- private int mLogAction = Touch.SWIPE;
- private int mLogDirection = Direction.UP;
+ private boolean mLogDirectionUpOrLeft = true;
private PointF mDownPos;
private boolean mIsLikelyToStartNewTask;
@@ -441,9 +437,13 @@
mOnDeferredActivityLaunch);
mGestureState.runOnceAtState(STATE_END_TARGET_SET,
- () -> mDeviceState.getRotationTouchHelper().
- onEndTargetCalculated(mGestureState.getEndTarget(),
- mActivityInterface));
+ () -> {
+ mDeviceState.getRotationTouchHelper()
+ .onEndTargetCalculated(mGestureState.getEndTarget(),
+ mActivityInterface);
+
+ mRecentsView.onGestureEndTargetCalculated(mGestureState.getEndTarget());
+ });
notifyGestureStartedAsync();
}
@@ -745,7 +745,6 @@
public void onGestureCancelled() {
updateDisplacement(0);
mStateCallback.setStateOnUiThread(STATE_GESTURE_COMPLETED);
- mLogAction = Touch.SWIPE_NOOP;
handleNormalGestureEnd(0, false, new PointF(), true /* isCancel */);
}
@@ -761,13 +760,11 @@
boolean isFling = mGestureStarted && !mIsMotionPaused
&& Math.abs(endVelocity) > flingThreshold;
mStateCallback.setStateOnUiThread(STATE_GESTURE_COMPLETED);
-
- mLogAction = isFling ? Touch.FLING : Touch.SWIPE;
boolean isVelocityVertical = Math.abs(velocity.y) > Math.abs(velocity.x);
if (isVelocityVertical) {
- mLogDirection = velocity.y < 0 ? Direction.UP : Direction.DOWN;
+ mLogDirectionUpOrLeft = velocity.y < 0;
} else {
- mLogDirection = velocity.x < 0 ? Direction.LEFT : Direction.RIGHT;
+ mLogDirectionUpOrLeft = velocity.x < 0;
}
mDownPos = downPos;
handleNormalGestureEnd(endVelocity, isFling, velocity, false /* isCancel */);
@@ -979,8 +976,7 @@
break;
case LAST_TASK:
case NEW_TASK:
- event = (mLogDirection == Direction.LEFT)
- ? LAUNCHER_QUICKSWITCH_LEFT
+ event = mLogDirectionUpOrLeft ? LAUNCHER_QUICKSWITCH_LEFT
: LAUNCHER_QUICKSWITCH_RIGHT;
break;
default:
@@ -988,12 +984,10 @@
}
StatsLogger logger = StatsLogManager.newInstance(mContext).logger()
.withSrcState(LAUNCHER_STATE_BACKGROUND)
- .withDstState(StatsLogManager.containerTypeToAtomState(endTarget.containerType));
+ .withDstState(endTarget.containerType);
if (targetTask != null) {
logger.withItemInfo(targetTask.getItemInfo());
}
- logger.log(event);
-
DeviceProfile dp = mDp;
if (dp == null || mDownPos == null) {
@@ -1003,12 +997,8 @@
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);
+ // TODO: set correct container using the pageIndex
+ logger.log(event);
}
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
@@ -1204,10 +1194,12 @@
anim.addOnUpdateListener((r, p) -> {
updateSysUiFlags(Math.max(p, mCurrentShift.value));
});
+ final int cuj = InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME;
anim.addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationStart(Animator animation) {
Trace.beginAsyncSection(TRANSITION_OPEN_LAUNCHER, 0);
+ InteractionJankMonitorWrapper.begin(cuj);
if (mActivity != null) {
removeLiveTileOverlay();
}
@@ -1221,6 +1213,13 @@
// Make sure recents is in its final state
maybeUpdateRecentsAttachedState(false);
mActivityInterface.onSwipeUpToHomeComplete(mDeviceState);
+ InteractionJankMonitorWrapper.end(cuj);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ super.onAnimationCancel(animation);
+ InteractionJankMonitorWrapper.cancel(cuj);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 8b108ac..d35e270 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -152,11 +152,6 @@
public abstract void onExitOverview(RotationTouchHelper deviceState,
Runnable exitRunnable);
- /**
- * Used for containerType in {@link com.android.launcher3.logging.UserEventDispatcher}
- */
- public abstract int getContainerType();
-
public abstract boolean isInLiveTileMode();
public abstract void onLaunchTaskFailed();
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 3898f0b..2885abf 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -28,7 +28,6 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
@@ -145,15 +144,6 @@
}
@Override
- public int getContainerType() {
- RecentsActivity activity = getCreatedActivity();
- boolean visible = activity != null && activity.isStarted() && activity.hasWindowFocus();
- return visible
- ? LauncherLogProto.ContainerType.OTHER_LAUNCHER_APP
- : LauncherLogProto.ContainerType.APP;
- }
-
- @Override
public boolean isInLiveTileMode() {
return false;
}
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 00b5eb9..9c23c83 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -15,6 +15,9 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import android.annotation.TargetApi;
@@ -23,7 +26,6 @@
import android.os.Build;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -44,13 +46,13 @@
* Defines the end targets of a gesture and the associated state.
*/
public enum GestureEndTarget {
- HOME(true, ContainerType.WORKSPACE, false),
+ HOME(true, LAUNCHER_STATE_HOME, false),
- RECENTS(true, ContainerType.TASKSWITCHER, true),
+ RECENTS(true, LAUNCHER_STATE_OVERVIEW, true),
- NEW_TASK(false, ContainerType.APP, true),
+ NEW_TASK(false, LAUNCHER_STATE_BACKGROUND, true),
- LAST_TASK(false, ContainerType.APP, true);
+ LAST_TASK(false, LAUNCHER_STATE_BACKGROUND, true);
GestureEndTarget(boolean isLauncher, int containerType,
boolean recentsAttachedToAppWindow) {
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 036d473..98b8455 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -44,7 +44,6 @@
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
@@ -208,10 +207,6 @@
return false;
}
- launcher.getUserEventDispatcher().logActionCommand(
- LauncherLogProto.Action.Command.RECENTS_BUTTON,
- getContainerType(),
- LauncherLogProto.ContainerType.TASKSWITCHER);
launcher.getStateManager().goToState(OVERVIEW,
launcher.getStateManager().shouldAnimateStateChange(), onCompleteCallback);
return true;
@@ -253,13 +248,6 @@
}
@Override
- public int getContainerType() {
- final Launcher launcher = getVisibleLauncher();
- return launcher != null ? launcher.getStateManager().getState().containerType
- : LauncherLogProto.ContainerType.APP;
- }
-
- @Override
public boolean isInLiveTileMode() {
Launcher launcher = getCreatedActivity();
return launcher != null && launcher.getStateManager().getState() == OVERVIEW &&
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 8613687..30edf36 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -30,7 +30,6 @@
import androidx.annotation.BinderThread;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.views.RecentsView;
@@ -47,7 +46,6 @@
private final Context mContext;
private final RecentsAnimationDeviceState mDeviceState;
- private final RecentsModel mRecentsModel;
private final OverviewComponentObserver mOverviewComponentObserver;
private long mLastToggleTime;
@@ -56,7 +54,6 @@
OverviewComponentObserver observer) {
mContext = context;
mDeviceState = deviceState;
- mRecentsModel = RecentsModel.INSTANCE.get(mContext);
mOverviewComponentObserver = observer;
}
@@ -150,7 +147,6 @@
private final AppToOverviewAnimationProvider<T> mAnimationProvider;
private final long mToggleClickedTime = SystemClock.uptimeMillis();
- private boolean mUserEventLogged;
private ActivityInitListener mListener;
public RecentsActivityCommand() {
@@ -160,7 +156,7 @@
ActivityManagerWrapper.getInstance().getRunningTask(), mDeviceState);
// Preload the plan
- mRecentsModel.getTasks(null);
+ RecentsModel.INSTANCE.get(mContext).getTasks(null);
}
@Override
@@ -212,13 +208,6 @@
private boolean onActivityReady(Boolean wasVisible) {
final T activity = mActivityInterface.getCreatedActivity();
- if (!mUserEventLogged) {
- activity.getUserEventDispatcher().logActionCommand(
- LauncherLogProto.Action.Command.RECENTS_BUTTON,
- mActivityInterface.getContainerType(),
- LauncherLogProto.ContainerType.TASKSWITCHER);
- mUserEventLogged = true;
- }
return mAnimationProvider.onActivityReady(activity, wasVisible);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 6f2f9fb..2f55f14 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -41,7 +41,10 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.LauncherAnimationRunner.AnimationResult;
import com.android.launcher3.R;
+import com.android.launcher3.WrappedAnimationRunnerImpl;
+import com.android.launcher3.WrappedLauncherAnimationRunner;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -87,6 +90,9 @@
private StateManager<RecentsState> mStateManager;
+ // Strong refs to runners which are cleared when the activity is destroyed
+ private WrappedAnimationRunnerImpl mActivityLaunchAnimationRunner;
+
/**
* Init drag layer and overview panel views.
*/
@@ -118,7 +124,6 @@
* etc.)
*/
protected void onHandleConfigChanged() {
- mUserEventDispatcher = null;
initDeviceProfile();
AbstractFloatingView.closeOpenViews(this, true,
@@ -170,8 +175,11 @@
}
final TaskView taskView = (TaskView) v;
- RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mUiHandler,
- true /* startAtFrontOfQueue */) {
+ mActivityLaunchAnimationRunner = new WrappedAnimationRunnerImpl() {
+ @Override
+ public Handler getHandler() {
+ return mUiHandler;
+ }
@Override
public void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
@@ -182,8 +190,10 @@
result.setAnimation(anim, RecentsActivity.this);
}
};
+ final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner<>(
+ mActivityLaunchAnimationRunner, true /* startAtFrontOfQueue */);
return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
- runner, RECENTS_LAUNCH_DURATION,
+ wrapper, RECENTS_LAUNCH_DURATION,
RECENTS_LAUNCH_DURATION - STATUS_BAR_TRANSITION_DURATION
- STATUS_BAR_TRANSITION_PRE_DELAY));
}
@@ -288,6 +298,7 @@
protected void onDestroy() {
super.onDestroy();
ACTIVITY_TRACKER.onActivityDestroyed(this);
+ mActivityLaunchAnimationRunner = null;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 6c302ae..d47217b 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -18,7 +18,6 @@
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.createAndStartNewLooper;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
import android.annotation.TargetApi;
@@ -26,11 +25,11 @@
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.os.Build;
-import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
import com.android.launcher3.icons.IconProvider;
+import com.android.launcher3.util.Executors.SimpleThreadFactory;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -40,6 +39,8 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
import java.util.function.Consumer;
/**
@@ -52,6 +53,9 @@
public static final MainThreadInitializedObject<RecentsModel> INSTANCE =
new MainThreadInitializedObject<>(RecentsModel::new);
+ private static final Executor RECENTS_MODEL_EXECUTOR = Executors.newSingleThreadExecutor(
+ new SimpleThreadFactory("TaskThumbnailIconCache-", THREAD_PRIORITY_BACKGROUND));
+
private final List<TaskVisualsChangeListener> mThumbnailChangeListeners = new ArrayList<>();
private final Context mContext;
@@ -61,12 +65,10 @@
private RecentsModel(Context context) {
mContext = context;
- Looper looper =
- createAndStartNewLooper("TaskThumbnailIconCache", THREAD_PRIORITY_BACKGROUND);
mTaskList = new RecentTasksList(MAIN_EXECUTOR,
new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance());
- mIconCache = new TaskIconCache(context, looper);
- mThumbnailCache = new TaskThumbnailCache(context, looper);
+ mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR);
+ mThumbnailCache = new TaskThumbnailCache(context, RECENTS_MODEL_EXECUTOR);
ActivityManagerWrapper.getInstance().registerTaskStackListener(this);
IconProvider.registerIconChangeListener(context,
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 7ff799e..65e89cf 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.FastBitmapDrawable.newIcon;
import static com.android.launcher3.uioverrides.QuickstepLauncher.GO_LOW_RAM_RECENTS_ENABLED;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.app.ActivityManager.TaskDescription;
import android.content.Context;
@@ -27,8 +26,6 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
-import android.os.Handler;
-import android.os.Looper;
import android.os.UserHandle;
import android.util.SparseArray;
import android.view.accessibility.AccessibilityManager;
@@ -37,12 +34,11 @@
import com.android.launcher3.FastBitmapDrawable;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.util.Preconditions;
+import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.TaskKeyLruCache;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
@@ -50,6 +46,7 @@
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.shared.system.TaskDescriptionCompat;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
@@ -57,7 +54,7 @@
*/
public class TaskIconCache {
- private final Handler mBackgroundHandler;
+ private final Executor mBgExecutor;
private final AccessibilityManager mAccessibilityManager;
private final Context mContext;
@@ -65,9 +62,9 @@
private final SparseArray<BitmapInfo> mDefaultIcons = new SparseArray<>();
private final IconProvider mIconProvider;
- public TaskIconCache(Context context, Looper backgroundLooper) {
+ public TaskIconCache(Context context, Executor bgExecutor) {
mContext = context;
- mBackgroundHandler = new Handler(backgroundLooper);
+ mBgExecutor = bgExecutor;
mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
Resources res = context.getResources();
@@ -83,31 +80,27 @@
* @param callback The callback to receive the task after its data has been populated.
* @return A cancelable handle to the request
*/
- public IconLoadRequest updateIconInBackground(Task task, Consumer<Task> callback) {
+ public CancellableTask updateIconInBackground(Task task, Consumer<Task> callback) {
Preconditions.assertUIThread();
if (task.icon != null) {
// Nothing to load, the icon is already loaded
callback.accept(task);
return null;
}
-
- IconLoadRequest request = new IconLoadRequest(mBackgroundHandler) {
+ CancellableTask<TaskCacheEntry> request = new CancellableTask<TaskCacheEntry>() {
@Override
- public void run() {
- TaskCacheEntry entry = getCacheEntry(task);
- if (isCanceled()) {
- // We don't call back to the provided callback in this case
- return;
- }
- MAIN_EXECUTOR.execute(() -> {
- task.icon = entry.icon;
- task.titleDescription = entry.contentDescription;
- callback.accept(task);
- onEnd();
- });
+ public TaskCacheEntry getResultOnBg() {
+ return getCacheEntry(task);
+ }
+
+ @Override
+ public void handleResult(TaskCacheEntry result) {
+ task.icon = result.icon;
+ task.titleDescription = result.contentDescription;
+ callback.accept(task);
}
};
- Utilities.postAsyncCallback(mBackgroundHandler, request);
+ mBgExecutor.execute(request);
return request;
}
@@ -120,9 +113,8 @@
}
void invalidateCacheEntries(String pkg, UserHandle handle) {
- Utilities.postAsyncCallback(mBackgroundHandler,
- () -> mIconCache.removeAll(key ->
- pkg.equals(key.getPackageName()) && handle.getIdentifier() == key.userId));
+ mBgExecutor.execute(() -> mIconCache.removeAll(key ->
+ pkg.equals(key.getPackageName()) && handle.getIdentifier() == key.userId));
}
@WorkerThread
@@ -208,12 +200,6 @@
}
}
- public static abstract class IconLoadRequest extends HandlerRunnable {
- IconLoadRequest(Handler handler) {
- super(handler, null);
- }
- }
-
private static class TaskCacheEntry {
public Drawable icon;
public String contentDescription = "";
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 2b55b80..65bb0f3 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -21,7 +21,6 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_SELECTIONS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_SPLIT_SCREEN_TAP;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
import android.app.Activity;
import android.app.ActivityOptions;
@@ -39,7 +38,6 @@
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.popup.SystemShortcut.AppInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.InstantAppResolver;
import com.android.quickstep.views.RecentsView;
@@ -228,8 +226,6 @@
@Override
protected boolean onActivityStarted(BaseDraggingActivity activity) {
- activity.getUserEventDispatcher().logActionOnControl(TAP,
- LauncherLogProto.ControlType.SPLIT_SCREEN_TARGET);
return true;
}
};
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index 2b7a8ec..a8a0219 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -15,17 +15,12 @@
*/
package com.android.quickstep;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
import android.content.Context;
import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.util.Preconditions;
+import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.TaskKeyLruCache;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
@@ -33,11 +28,12 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import java.util.ArrayList;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
public class TaskThumbnailCache {
- private final Handler mBackgroundHandler;
+ private final Executor mBgExecutor;
private final int mCacheSize;
private final TaskKeyLruCache<ThumbnailData> mCache;
@@ -94,8 +90,8 @@
}
}
- public TaskThumbnailCache(Context context, Looper backgroundLooper) {
- mBackgroundHandler = new Handler(backgroundLooper);
+ public TaskThumbnailCache(Context context, Executor bgExecutor) {
+ mBgExecutor = bgExecutor;
mHighResLoadingState = new HighResLoadingState(context);
Resources res = context.getResources();
@@ -130,7 +126,7 @@
* @param callback The callback to receive the task after its data has been populated.
* @return A cancelable handle to the request
*/
- public ThumbnailLoadRequest updateThumbnailInBackground(
+ public CancellableTask updateThumbnailInBackground(
Task task, Consumer<ThumbnailData> callback) {
Preconditions.assertUIThread();
@@ -142,14 +138,13 @@
return null;
}
-
return updateThumbnailInBackground(task.key, !mHighResLoadingState.isEnabled(), t -> {
task.thumbnail = t;
callback.accept(t);
});
}
- private ThumbnailLoadRequest updateThumbnailInBackground(TaskKey key, boolean lowResolution,
+ private CancellableTask updateThumbnailInBackground(TaskKey key, boolean lowResolution,
Consumer<ThumbnailData> callback) {
Preconditions.assertUIThread();
@@ -160,26 +155,20 @@
return null;
}
- ThumbnailLoadRequest request = new ThumbnailLoadRequest(mBackgroundHandler,
- lowResolution) {
+ CancellableTask<ThumbnailData> request = new CancellableTask<ThumbnailData>() {
@Override
- public void run() {
- ThumbnailData thumbnail = ActivityManagerWrapper.getInstance().getTaskThumbnail(
+ public ThumbnailData getResultOnBg() {
+ return ActivityManagerWrapper.getInstance().getTaskThumbnail(
key.id, lowResolution);
+ }
- MAIN_EXECUTOR.execute(() -> {
- if (isCanceled()) {
- // We don't call back to the provided callback in this case
- return;
- }
-
- mCache.put(key, thumbnail);
- callback.accept(thumbnail);
- onEnd();
- });
+ @Override
+ public void handleResult(ThumbnailData result) {
+ mCache.put(key, result);
+ callback.accept(result);
}
};
- Utilities.postAsyncCallback(mBackgroundHandler, request);
+ mBgExecutor.execute(request);
return request;
}
@@ -218,15 +207,6 @@
return mEnableTaskSnapshotPreloading && mHighResLoadingState.mVisible;
}
- public static abstract class ThumbnailLoadRequest extends HandlerRunnable {
- public final boolean mLowResolution;
-
- ThumbnailLoadRequest(Handler handler, boolean lowResolution) {
- super(handler, null);
- mLowResolution = lowResolution;
- }
- }
-
/**
* @return Whether device supports low-res thumbnails. Low-res files are an optimization
* for faster load times of snapshots. Devices can optionally disable low-res files so that
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index df93e0b..3e05b07 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -20,6 +20,7 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
+import static com.android.launcher3.config.FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
@@ -687,7 +688,7 @@
final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
return new OtherActivityInputConsumer(this, mDeviceState, mTaskAnimationManager,
gestureState, shouldDefer, this::onConsumerInactive,
- mInputMonitorCompat, disableHorizontalSwipe, factory);
+ mInputMonitorCompat, mInputEventReceiver, disableHorizontalSwipe, factory);
}
private InputConsumer createDeviceLockedInputConsumer(GestureState gestureState) {
@@ -709,8 +710,10 @@
if (activity.getRootView().hasWindowFocus()
|| previousGestureState.isRunningAnimationToLauncher()
- || (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
- && forceOverviewInputConsumer)) {
+ || (ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
+ && forceOverviewInputConsumer)
+ || (ENABLE_QUICKSTEP_LIVE_TILE.get())
+ && gestureState.getActivityInterface().isInLiveTileMode()) {
return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
false /* startingInActivityBounds */);
} else {
@@ -734,6 +737,8 @@
private void reset() {
mConsumer = mUncheckedConsumer = mResetGestureInputConsumer;
mGestureState = DEFAULT_STATE;
+ // By default, use batching of the input events
+ mInputEventReceiver.setBatchingEnabled(true);
}
private void preloadOverview(boolean fromInit) {
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index f5f5259..8f2356c 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep.fallback;
+import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
@@ -27,6 +28,7 @@
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.quickstep.FallbackActivityInterface;
+import com.android.quickstep.GestureState;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
@@ -74,14 +76,14 @@
}
/**
- * When the gesture ends and recents view become interactive, we also remove the temporary
+ * When the gesture ends and we're going to recents view, we also remove the temporary
* invisible tile added for the home task. This also pushes the remaining tiles back
* to the center.
*/
@Override
- public void onGestureAnimationEnd() {
- super.onGestureAnimationEnd();
- if (mHomeTaskInfo != null) {
+ public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
+ super.onGestureEndTargetCalculated(endTarget);
+ if (mHomeTaskInfo != null && endTarget == RECENTS) {
TaskView tv = getTaskView(mHomeTaskInfo.taskId);
if (tv != null) {
PendingAnimation pa = createTaskDismissAnimation(tv, true, false, 150);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index 89e6931..580e4ec 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -25,12 +25,6 @@
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.Utilities.squaredHypot;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPLEFT;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction.UPRIGHT;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.FLING;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.SWIPE;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.SWIPE_NOOP;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.NAVBAR;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -47,7 +41,6 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
@@ -80,7 +73,6 @@
private float mTimeFraction;
private long mDragTime;
private float mLastProgress;
- private int mDirection;
private BaseActivityInterface mActivityInterface;
private final float mDragDistThreshold;
@@ -197,8 +189,6 @@
if (mState != STATE_DELEGATE_ACTIVE && !mLaunchedAssistant) {
ValueAnimator animator = ValueAnimator.ofFloat(mLastProgress, 0)
.setDuration(RETRACT_ANIMATION_DURATION_MS);
- UserEventDispatcher.newInstance(mContext).logActionOnContainer(
- SWIPE_NOOP, mDirection, NAVBAR);
animator.addUpdateListener(valueAnimator -> {
float progress = (float) valueAnimator.getAnimatedValue();
SystemUiProxy.INSTANCE.get(mContext).onAssistantProgress(progress);
@@ -223,7 +213,7 @@
mLastProgress = Math.min(mDistance * 1f / mDragDistThreshold, 1) * mTimeFraction;
if (mDistance >= mDragDistThreshold && mTimeFraction >= 1) {
SystemUiProxy.INSTANCE.get(mContext).onAssistantGestureCompletion(0);
- startAssistantInternal(SWIPE);
+ startAssistantInternal();
Bundle args = new Bundle();
args.putInt(OPA_BUNDLE_TRIGGER, OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE);
@@ -236,10 +226,7 @@
}
}
- private void startAssistantInternal(int gestureType) {
- UserEventDispatcher.newInstance(mContext)
- .logActionOnContainer(gestureType, mDirection, NAVBAR);
-
+ private void startAssistantInternal() {
BaseDraggingActivity launcherActivity = mActivityInterface.getCreatedActivity();
if (launcherActivity != null) {
launcherActivity.getRootView().performHapticFeedback(
@@ -253,7 +240,6 @@
*/
private boolean isValidAssistantGestureAngle(float deltaX, float deltaY) {
float angle = (float) Math.toDegrees(Math.atan2(deltaY, deltaX));
- mDirection = angle > 90 ? UPLEFT : UPRIGHT;
// normalize so that angle is measured clockwise from horizontal in the bottom right corner
// and counterclockwise from horizontal in the bottom left corner
@@ -272,7 +258,7 @@
mLastProgress = 1;
SystemUiProxy.INSTANCE.get(mContext).onAssistantGestureCompletion(
(float) Math.sqrt(velocityX * velocityX + velocityY * velocityY));
- startAssistantInternal(FLING);
+ startAssistantInternal();
Bundle args = new Bundle();
args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_GESTURE);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index b1a1133..35dbee9 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -67,6 +67,7 @@
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputMonitorCompat;
import java.util.function.Consumer;
@@ -92,6 +93,7 @@
private RecentsAnimationCallbacks mActiveCallbacks;
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
private final InputMonitorCompat mInputMonitorCompat;
+ private final InputEventReceiver mInputEventReceiver;
private final BaseActivityInterface mActivityInterface;
private final AbsSwipeUpHandler.Factory mHandlerFactory;
@@ -135,8 +137,8 @@
public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState,
boolean isDeferredDownTarget, Consumer<OtherActivityInputConsumer> onCompleteCallback,
- InputMonitorCompat inputMonitorCompat, boolean disableHorizontalSwipe,
- Factory handlerFactory) {
+ InputMonitorCompat inputMonitorCompat, InputEventReceiver inputEventReceiver,
+ boolean disableHorizontalSwipe, Factory handlerFactory) {
super(base);
mDeviceState = deviceState;
mNavBarPosition = mDeviceState.getNavBarPosition();
@@ -154,6 +156,7 @@
mOnCompleteCallback = onCompleteCallback;
mVelocityTracker = VelocityTracker.obtain();
mInputMonitorCompat = inputMonitorCompat;
+ mInputEventReceiver = inputEventReceiver;
boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning();
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
@@ -215,6 +218,9 @@
switch (ev.getActionMasked()) {
case ACTION_DOWN: {
+ // Until we detect the gesture, handle events as we receive them
+ mInputEventReceiver.setBatchingEnabled(false);
+
Object traceToken = TraceHelper.INSTANCE.beginSection(DOWN_EVT,
FLAG_CHECK_FOR_RACE_CONDITIONS);
mActivePointerId = ev.getPointerId(0);
@@ -351,6 +357,8 @@
}
TestLogging.recordEvent(TestProtocol.SEQUENCE_PILFER, "pilferPointers");
mInputMonitorCompat.pilferPointers();
+ // Once we detect the gesture, we can enable batching to reduce further updates
+ mInputEventReceiver.setBatchingEnabled(true);
mActivityInterface.closeOverlay();
ActivityManagerWrapper.getInstance().closeSystemWindows(
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
index 1c77a05..924b32c 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewWithoutFocusInputConsumer.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep.inputconsumers;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
@@ -27,9 +28,6 @@
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.RecentsAnimationDeviceState;
@@ -82,17 +80,12 @@
mContext.startActivity(mGestureState.getHomeIntent());
ActiveGestureLog.INSTANCE.addLog("startQuickstep");
BaseActivity activity = BaseDraggingActivity.fromContext(mContext);
- int pageIndex = -1; // This number doesn't reflect workspace page index.
- // It only indicates that launcher client screen was shown.
- int containerType = (mGestureState != null && mGestureState.getEndTarget() != null)
+ int state = (mGestureState != null && mGestureState.getEndTarget() != null)
? mGestureState.getEndTarget().containerType
- : LauncherLogProto.ContainerType.WORKSPACE;
- activity.getUserEventDispatcher().logActionOnContainer(
- wasFling ? Touch.FLING : Touch.SWIPE, Direction.UP, containerType, pageIndex);
- activity.getUserEventDispatcher().setPreviousHomeGesture(true);
+ : LAUNCHER_STATE_HOME;
activity.getStatsLogManager().logger()
- .withSrcState(LAUNCHER_STATE_HOME)
- .withDstState(LAUNCHER_STATE_HOME)
+ .withSrcState(LAUNCHER_STATE_BACKGROUND)
+ .withDstState(state)
.withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
.setWorkspace(
LauncherAtom.WorkspaceContainer.newBuilder()
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
index 70181fb..16886ec 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
@@ -24,7 +24,7 @@
/** Shows the Home gesture interactive tutorial. */
public class AssistantGestureTutorialFragment extends TutorialFragment {
@Override
- int getHandAnimationResId() {
+ Integer getHandAnimationResId() {
return R.drawable.assistant_gesture;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index bef50ea..41db684 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -24,7 +24,7 @@
/** Shows the Back gesture interactive tutorial. */
public class BackGestureTutorialFragment extends TutorialFragment {
@Override
- int getHandAnimationResId() {
+ Integer getHandAnimationResId() {
return R.drawable.back_gesture;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
index e4b348e..9489bac 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
@@ -143,6 +143,10 @@
return false;
}
+ boolean onInterceptTouch(MotionEvent motionEvent) {
+ return isWithinTouchRegion((int) motionEvent.getX(), (int) motionEvent.getY());
+ }
+
private boolean isWithinTouchRegion(int x, int y) {
// Disallow if too far from the edge
if (x > mEdgeWidth + mLeftInset && x < (mDisplaySize.x - mEdgeWidth - mRightInset)) {
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index e2a9d12..63595a5 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -21,7 +21,7 @@
/** Shows the Home gesture interactive tutorial. */
public class HomeGestureTutorialFragment extends TutorialFragment {
@Override
- int getHandAnimationResId() {
+ Integer getHandAnimationResId() {
return R.drawable.home_gesture;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index f897ecc..d1b0a70 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -250,6 +250,12 @@
return intercepted;
}
+ boolean onInterceptTouch(MotionEvent event) {
+ return mAssistantLeftRegion.contains(event.getX(), event.getY())
+ || mAssistantRightRegion.contains(event.getX(), event.getY())
+ || event.getY() >= mDisplaySize.y - mBottomGestureHeight;
+ }
+
protected void onMotionPauseDetected() {
VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index 3357b70..93200bb 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -21,7 +21,7 @@
/** Shows the Overview gesture interactive tutorial. */
public class OverviewGestureTutorialFragment extends TutorialFragment {
@Override
- int getHandAnimationResId() {
+ Integer getHandAnimationResId() {
return R.drawable.overview_gesture;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
new file mode 100644
index 0000000..db1afc2
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.RelativeLayout;
+
+import androidx.fragment.app.FragmentManager;
+
+/** Root layout that TutorialFragment uses to intercept motion events. */
+public class RootSandboxLayout extends RelativeLayout {
+ public RootSandboxLayout(Context context) {
+ super(context);
+ }
+
+ public RootSandboxLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public RootSandboxLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent motionEvent) {
+ return ((TutorialFragment) FragmentManager.findFragment(this))
+ .onInterceptTouch(motionEvent);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java b/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java
new file mode 100644
index 0000000..80ffe66
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxLauncherRenderer.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import android.content.Context;
+import android.view.View;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.graphics.LauncherPreviewRenderer;
+
+/** Renders a fake Launcher for use in the Sandbox. */
+class SandboxLauncherRenderer extends LauncherPreviewRenderer {
+ SandboxLauncherRenderer(Context context, InvariantDeviceProfile idp, boolean migrated) {
+ super(context, idp, migrated);
+ }
+
+ @Override
+ public boolean shouldShowRealLauncherPreview() {
+ return false;
+ }
+
+ @Override
+ public boolean shouldShowQsb() {
+ return false;
+ }
+
+ @Override
+ public View.OnLongClickListener getWorkspaceChildOnLongClickListener() {
+ return null;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
new file mode 100644
index 0000000..d54efc5
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialController.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import android.graphics.PointF;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.R;
+import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
+import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
+
+/** A {@link TutorialController} for the Sandbox Mode. */
+public class SandboxModeTutorialController extends SwipeUpGestureTutorialController {
+
+ SandboxModeTutorialController(SandboxModeTutorialFragment fragment, TutorialType tutorialType) {
+ super(fragment, tutorialType);
+ }
+
+ @Nullable
+ @Override
+ Integer getTitleStringId() {
+ return R.string.sandbox_mode_title;
+ }
+
+ @Nullable
+ @Override
+ Integer getSubtitleStringId() {
+ return R.string.sandbox_mode_subtitle;
+ }
+
+ @Nullable
+ @Override
+ Integer getActionButtonStringId() {
+ return R.string.gesture_tutorial_action_button_label_done;
+ }
+
+ @Override
+ void onActionButtonClicked(View button) {
+ mTutorialFragment.closeTutorial();
+ }
+
+ @Override
+ public void onBackGestureAttempted(BackGestureResult result) {
+ switch (result) {
+ case BACK_COMPLETED_FROM_LEFT:
+ case BACK_COMPLETED_FROM_RIGHT:
+ showRippleEffect(null);
+ showFeedback(R.string.sandbox_mode_back_gesture_feedback_successful);
+ break;
+ case BACK_CANCELLED_FROM_RIGHT:
+ showFeedback(R.string.back_gesture_feedback_cancelled_right_edge);
+ break;
+ case BACK_CANCELLED_FROM_LEFT:
+ showFeedback(R.string.back_gesture_feedback_cancelled_left_edge);
+ break;
+ case BACK_NOT_STARTED_TOO_FAR_FROM_EDGE:
+ showFeedback(R.string.sandbox_mode_back_gesture_feedback_swipe_too_far_from_edge);
+ break;
+ }
+ }
+
+ @Override
+ public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
+ switch (result) {
+ case ASSISTANT_COMPLETED:
+ showRippleEffect(null);
+ showFeedback(R.string.sandbox_mode_assistant_gesture_feedback_successful);
+ break;
+ case HOME_GESTURE_COMPLETED:
+ animateFakeTaskViewHome(finalVelocity, () -> {
+ showFeedback(R.string.sandbox_mode_home_gesture_feedback_successful);
+ });
+ break;
+ case OVERVIEW_GESTURE_COMPLETED:
+ fadeOutFakeTaskView(true, () -> {
+ showFeedback(R.string.sandbox_mode_overview_gesture_feedback_successful);
+ });
+ break;
+ case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
+ case HOME_OR_OVERVIEW_CANCELLED:
+ case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
+ case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE:
+ showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge);
+ break;
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
new file mode 100644
index 0000000..955a2f7
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.interaction;
+
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.quickstep.interaction.TutorialController.TutorialType;
+
+/** Shows the general navigation gesture sandbox environment. */
+public class SandboxModeTutorialFragment extends TutorialFragment {
+
+ @Override
+ TutorialController createController(TutorialType type) {
+ return new SandboxModeTutorialController(this, type);
+ }
+
+ @Override
+ Class<? extends TutorialController> getControllerClass() {
+ return SandboxModeTutorialController.class;
+ }
+
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && mTutorialController != null) {
+ mTutorialController.setRippleHotspot(motionEvent.getX(), motionEvent.getY());
+ }
+ return super.onTouch(view, motionEvent);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 73f1f8c..2198ade 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -47,11 +47,12 @@
final TextView mTitleTextView;
final TextView mSubtitleTextView;
final TextView mFeedbackView;
+ final View mLauncherView;
final ClipIconView mFakeIconView;
final View mFakeTaskView;
final View mRippleView;
final RippleDrawable mRippleDrawable;
- final TutorialHandAnimation mHandCoachingAnimation;
+ @Nullable final TutorialHandAnimation mHandCoachingAnimation;
final ImageView mHandCoachingView;
final Button mActionTextButton;
final Button mActionButton;
@@ -68,6 +69,7 @@
mTitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_title_view);
mSubtitleTextView = rootView.findViewById(R.id.gesture_tutorial_fragment_subtitle_view);
mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
+ mLauncherView = tutorialFragment.getLauncherView();
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
mFakeTaskView = rootView.findViewById(R.id.gesture_tutorial_fake_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
@@ -143,13 +145,16 @@
void onActionTextButtonClicked(View button) {}
void showHandCoachingAnimation() {
- if (isComplete()) {
+ if (isComplete() || mHandCoachingAnimation == null) {
return;
}
mHandCoachingAnimation.startLoopedAnimation(mTutorialType);
}
void hideHandCoachingAnimation() {
+ if (mHandCoachingAnimation == null) {
+ return;
+ }
mHandCoachingAnimation.stop();
mHandCoachingView.setVisibility(View.INVISIBLE);
}
@@ -162,8 +167,10 @@
if (isComplete()) {
hideHandCoachingAnimation();
+ mLauncherView.setVisibility(View.INVISIBLE);
} else {
showHandCoachingAnimation();
+ mLauncherView.setVisibility(View.VISIBLE);
}
}
@@ -206,7 +213,8 @@
return mTutorialType == TutorialType.BACK_NAVIGATION_COMPLETE
|| mTutorialType == TutorialType.HOME_NAVIGATION_COMPLETE
|| mTutorialType == TutorialType.OVERVIEW_NAVIGATION_COMPLETE
- || mTutorialType == TutorialType.ASSISTANT_COMPLETE;
+ || mTutorialType == TutorialType.ASSISTANT_COMPLETE
+ || mTutorialType == TutorialType.SANDBOX_MODE;
}
/** Denotes the type of the tutorial. */
@@ -219,6 +227,7 @@
OVERVIEW_NAVIGATION,
OVERVIEW_NAVIGATION_COMPLETE,
ASSISTANT,
- ASSISTANT_COMPLETE
+ ASSISTANT_COMPLETE,
+ SANDBOX_MODE
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 9a8264d..f297d5a 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -31,6 +31,7 @@
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -42,9 +43,10 @@
TutorialType mTutorialType;
@Nullable TutorialController mTutorialController = null;
View mRootView;
- TutorialHandAnimation mHandCoachingAnimation;
+ @Nullable TutorialHandAnimation mHandCoachingAnimation = null;
EdgeBackGestureHandler mEdgeBackGestureHandler;
NavBarGestureHandler mNavBarGestureHandler;
+ private View mLauncherView;
public static TutorialFragment newInstance(TutorialType tutorialType) {
TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
@@ -74,13 +76,17 @@
case ASSISTANT:
case ASSISTANT_COMPLETE:
return new AssistantGestureTutorialFragment();
+ case SANDBOX_MODE:
+ return new SandboxModeTutorialFragment();
default:
Log.e(LOG_TAG, "Failed to find an appropriate fragment for " + tutorialType.name());
}
return null;
}
- abstract int getHandAnimationResId();
+ @Nullable Integer getHandAnimationResId() {
+ return null;
+ }
abstract TutorialController createController(TutorialType type);
@@ -114,8 +120,14 @@
return insets;
});
mRootView.setOnTouchListener(this);
- mHandCoachingAnimation = new TutorialHandAnimation(getContext(), mRootView,
- getHandAnimationResId());
+ Integer handAnimationResId = getHandAnimationResId();
+ if (handAnimationResId != null) {
+ mHandCoachingAnimation =
+ new TutorialHandAnimation(getContext(), mRootView, handAnimationResId);
+ }
+ InvariantDeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(getContext());
+ mLauncherView = new SandboxLauncherRenderer(getContext(), dp, true).getRenderedView();
+ ((ViewGroup) mRootView).addView(mLauncherView, 0);
return mRootView;
}
@@ -128,16 +140,25 @@
@Override
public void onPause() {
super.onPause();
- mHandCoachingAnimation.stop();
+
+ if (mHandCoachingAnimation != null) {
+ mHandCoachingAnimation.stop();
+ }
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
- // Note: Using logical or to ensure both functions get called.
+ // Note: Using logical-or to ensure both functions get called.
return mEdgeBackGestureHandler.onTouch(view, motionEvent)
| mNavBarGestureHandler.onTouch(view, motionEvent);
}
+ boolean onInterceptTouch(MotionEvent motionEvent) {
+ // Note: Using logical-or to ensure both functions get called.
+ return mEdgeBackGestureHandler.onInterceptTouch(motionEvent)
+ | mNavBarGestureHandler.onInterceptTouch(motionEvent);
+ }
+
void onAttachedToWindow() {
mEdgeBackGestureHandler.setViewGroupParent((ViewGroup) getRootView());
}
@@ -168,7 +189,11 @@
return mRootView;
}
- TutorialHandAnimation getHandAnimation() {
+ View getLauncherView() {
+ return mLauncherView;
+ }
+
+ @Nullable TutorialHandAnimation getHandAnimation() {
return mHandCoachingAnimation;
}
diff --git a/quickstep/src/com/android/quickstep/util/CancellableTask.java b/quickstep/src/com/android/quickstep/util/CancellableTask.java
new file mode 100644
index 0000000..a6e2e81
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/CancellableTask.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.util;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
+
+/**
+ * Utility class to executore a task on background and post the result on UI thread
+ */
+public abstract class CancellableTask<T> implements Runnable {
+
+ private boolean mCancelled = false;
+
+ @Override
+ public final void run() {
+ if (mCancelled) {
+ return;
+ }
+ T result = getResultOnBg();
+ if (mCancelled) {
+ return;
+ }
+ MAIN_EXECUTOR.execute(() -> {
+ if (mCancelled) {
+ return;
+ }
+ handleResult(result);
+ });
+ }
+
+ /**
+ * Called on the worker thread to process the request. The return object is passed to
+ * {@link #handleResult(Object)}
+ */
+ @WorkerThread
+ public abstract T getResultOnBg();
+
+ /**
+ * Called on the UI thread to handle the final result.
+ * @param result
+ */
+ @UiThread
+ public abstract void handleResult(T result);
+
+ /**
+ * Cancels the request. If it is called before {@link #handleResult(Object)}, that method
+ * will not be called
+ */
+ public void cancel() {
+ mCancelled = true;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
index 4a298d3..1031c5b 100644
--- a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
+++ b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
@@ -18,8 +18,10 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
+import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
@@ -110,7 +112,7 @@
boolean isLayoutNaturalToLauncher = recentsView.getPagedOrientationHandler()
.isLayoutNaturalToLauncher();
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, isLayoutNaturalToLauncher
- ? DEACCEL : FINAL_FRAME);
+ ? clampToProgress(FAST_OUT_SLOW_IN, 0, 0.75f) : FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, INSTANT);
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index df9b0cf..de44e07 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -23,7 +23,6 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
-import static com.android.launcher3.logging.LoggerUtils.extractObjectNameAndAddress;
import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
@@ -72,6 +71,7 @@
private static final String TAG = "RecentsOrientedState";
private static final boolean DEBUG = false;
+ private static final String DELIMITER_DOT = "\\.";
private ContentObserver mSystemAutoRotateObserver = new ContentObserver(new Handler()) {
@Override
@@ -534,4 +534,13 @@
? idp.landscapeProfile
: idp.portraitProfile;
}
+
+ /**
+ * String conversion for only the helpful parts of {@link Object#toString()} method
+ * @param stringToExtract "foo.bar.baz.MyObject@1234"
+ * @return "MyObject@1234"
+ */
+ private static String extractObjectNameAndAddress(String stringToExtract) {
+ return stringToExtract.substring(stringToExtract.lastIndexOf(DELIMITER_DOT));
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
index 04308c8..19c6588 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
@@ -21,6 +21,8 @@
import android.os.Handler;
import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.LauncherAnimationRunner.AnimationResult;
+import com.android.launcher3.WrappedAnimationRunnerImpl;
import com.android.launcher3.WrappedLauncherAnimationRunner;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
@@ -28,14 +30,17 @@
public abstract class RemoteAnimationProvider {
- LauncherAnimationRunner mAnimationRunner;
+ WrappedAnimationRunnerImpl mAnimationRunner;
public abstract AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets);
ActivityOptions toActivityOptions(Handler handler, long duration, Context context) {
- mAnimationRunner = new LauncherAnimationRunner(handler,
- false /* startAtFrontOfQueue */) {
+ mAnimationRunner = new WrappedAnimationRunnerImpl() {
+ @Override
+ public Handler getHandler() {
+ return handler;
+ }
@Override
public void onCreateAnimation(RemoteAnimationTargetCompat[] appTargets,
@@ -45,7 +50,6 @@
};
final LauncherAnimationRunner wrapper = new WrappedLauncherAnimationRunner(
mAnimationRunner, false /* startAtFrontOfQueue */);
-
return ActivityOptionsCompat.makeRemoteAnimation(
new RemoteAnimationAdapterCompat(wrapper, duration, 0));
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 903e87a..3a54bd6 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -278,7 +278,6 @@
int start = mOrientationState.getOrientationHandler()
.getPrimaryValue(mTaskRect.left, mTaskRect.top);
mScrollState.screenCenter = start + mScrollState.scroll + mScrollState.halfPageSize;
- mScrollState.pageParentScale = recentsViewScale.value;
mScrollState.updateInterpolation(start);
mCurveScale = TaskView.getCurveScaleForInterpolation(mScrollState.linearInterpolation);
}
@@ -297,9 +296,9 @@
mMatrix.postTranslate(insets.left, insets.top);
mMatrix.postScale(scale, scale);
- // Apply TaskView matrix: translate, scale, scroll
- mMatrix.postTranslate(mTaskRect.left, mTaskRect.top + mOffsetY);
+ // Apply TaskView matrix: scale, translate, scroll
mMatrix.postScale(mCurveScale, mCurveScale, taskWidth / 2, taskHeight / 2);
+ mMatrix.postTranslate(mTaskRect.left, mTaskRect.top + mOffsetY);
mOrientationState.getOrientationHandler().set(
mMatrix, MATRIX_POST_TRANSLATE, mScrollState.scroll);
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index b06d4bc..95bde80 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -42,7 +42,6 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.systemui.shared.recents.model.Task;
import java.time.Duration;
@@ -217,8 +216,8 @@
view, 0, 0,
view.getWidth(), view.getHeight());
activity.startActivity(intent, options.toBundle());
- activity.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP,
- LauncherLogProto.ControlType.APP_USAGE_SETTINGS, view);
+
+ // TODO: add WW logging on the app usage settings click.
} catch (ActivityNotFoundException e) {
Log.e(TAG, "Failed to open app usage settings for task "
+ mTask.getTopComponent().getPackageName(), e);
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index b338bd0..52a7466 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -36,7 +36,6 @@
import android.widget.FrameLayout;
import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateListener;
@@ -177,14 +176,8 @@
@Override
protected boolean shouldStealTouchFromSiblingsBelow(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- // Allow touches to go through to the hotseat.
- Hotseat hotseat = mActivity.getHotseat();
- boolean touchingHotseat = hotseat.isShown()
- && mActivity.getDragLayer().isEventOverView(hotseat, ev, this);
- return !touchingHotseat;
- }
- return super.shouldStealTouchFromSiblingsBelow(ev);
+ return mActivity.getStateManager().getState().overviewUi
+ && super.shouldStealTouchFromSiblingsBelow(ev);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 2a6c9e9..b8e07cb 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -54,7 +54,6 @@
HIDDEN_UNSUPPORTED_NAVIGATION,
HIDDEN_NON_ZERO_ROTATION,
HIDDEN_NO_TASKS,
- HIDDEN_GESTURE_RUNNING,
HIDDEN_NO_RECENTS})
@Retention(RetentionPolicy.SOURCE)
public @interface ActionsHiddenFlags { }
@@ -62,8 +61,7 @@
public static final int HIDDEN_UNSUPPORTED_NAVIGATION = 1 << 0;
public static final int HIDDEN_NON_ZERO_ROTATION = 1 << 1;
public static final int HIDDEN_NO_TASKS = 1 << 2;
- public static final int HIDDEN_GESTURE_RUNNING = 1 << 3;
- public static final int HIDDEN_NO_RECENTS = 1 << 4;
+ public static final int HIDDEN_NO_RECENTS = 1 << 3;
@IntDef(flag = true, value = {
DISABLED_SCROLLING,
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 0362377..7a8e11d 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -35,16 +35,14 @@
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_CLEAR_ALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
-import static com.android.quickstep.views.OverviewActionsView.HIDDEN_GESTURE_RUNNING;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
@@ -109,7 +107,6 @@
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.PagedOrientationHandler.CurveProperties;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.MultiValueAlpha;
@@ -118,6 +115,7 @@
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.ViewPool;
import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.GestureState;
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.RecentsModel;
@@ -1129,7 +1127,6 @@
setEnableDrawingLiveTile(false);
setRunningTaskHidden(true);
setRunningTaskIconScaledDown(true);
- mActionsView.updateHiddenFlags(HIDDEN_GESTURE_RUNNING, true);
}
/**
@@ -1183,7 +1180,14 @@
}
/**
- * Called when a gesture from an app has finished.
+ * Called when a gesture from an app has finished, and an end target has been determined.
+ */
+ public void onGestureEndTargetCalculated(GestureState.GestureEndTarget endTarget) {
+
+ }
+
+ /**
+ * Called when a gesture from an app has finished, and the animation to the target has ended.
*/
public void onGestureAnimationEnd() {
if (mOrientationState.setGestureActive(false)) {
@@ -1322,7 +1326,6 @@
}
private void animateActionsViewIn() {
- mActionsView.updateHiddenFlags(HIDDEN_GESTURE_RUNNING, false);
ObjectAnimator anim = ObjectAnimator.ofFloat(
mActionsView.getVisibilityAlpha(), MultiValueAlpha.VALUE, 0, 1);
anim.setDuration(TaskView.SCALE_ICON_DURATION);
@@ -1407,13 +1410,12 @@
* Updates linearInterpolation for the provided child position
*/
public void updateInterpolation(float childStart) {
- float scaledHalfPageSize = halfPageSize / pageParentScale;
- float pageCenter = childStart + scaledHalfPageSize;
+ float pageCenter = childStart + halfPageSize;
float distanceFromScreenCenter = screenCenter - pageCenter;
// How far the page has to move from the center to be offscreen, taking into account
// the EDGE_SCALE_DOWN_FACTOR that will be applied at that position.
float distanceToReachEdge = halfScreenSize
- + scaledHalfPageSize * (1 - TaskView.EDGE_SCALE_DOWN_FACTOR);
+ + halfPageSize * (1 - TaskView.EDGE_SCALE_DOWN_FACTOR);
linearInterpolation = Math.min(1,
Math.abs(distanceFromScreenCenter) / distanceToReachEdge);
}
@@ -1459,7 +1461,7 @@
public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView,
boolean shouldRemoveTask, long duration) {
if (mPendingAnimation != null) {
- mPendingAnimation.finish(false, Touch.SWIPE);
+ mPendingAnimation.finish(false);
}
PendingAnimation anim = new PendingAnimation(duration);
@@ -1621,7 +1623,7 @@
protected void runDismissAnimation(PendingAnimation pendingAnim) {
AnimatorPlaybackController controller = pendingAnim.createPlaybackController();
controller.dispatchOnStart();
- controller.setEndAction(() -> pendingAnim.finish(true, Touch.SWIPE));
+ controller.setEndAction(() -> pendingAnim.finish(true));
controller.getAnimationPlayer().setInterpolator(FAST_OUT_SLOW_IN);
controller.start();
}
@@ -1634,7 +1636,7 @@
@SuppressWarnings("unused")
private void dismissAllTasks(View view) {
runDismissAnimation(createAllTasksDismissAnimation(DISMISS_TASK_DURATION));
- mActivity.getUserEventDispatcher().logActionOnControl(TAP, CLEAR_ALL_BUTTON);
+ mActivity.getStatsLogManager().logger().log(LAUNCHER_TASK_CLEAR_ALL);
}
private void dismissCurrentTask() {
@@ -2159,7 +2161,12 @@
tv.notifyTaskLaunchFailed(TAG);
}
};
- tv.launchTask(false, onLaunchResult, getHandler());
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ finishRecentsAnimation(false /* toRecents */, null);
+ onLaunchResult.accept(true /* success */);
+ } else {
+ tv.launchTask(false, onLaunchResult, getHandler());
+ }
Task task = tv.getTask();
if (task != null) {
mActivity.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index d47eba6..4aff7e3 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -16,6 +16,7 @@
package com.android.quickstep.views;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA;
import android.animation.Animator;
@@ -229,7 +230,16 @@
menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp);
- menuOptionView.setOnClickListener(menuOption);
+ menuOptionView.setOnClickListener(view -> {
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ RecentsView recentsView = mTaskView.getRecentsView();
+ recentsView.switchToScreenshot(null,
+ () -> recentsView.finishRecentsAnimation(true /* toRecents */,
+ () -> menuOption.onClick(view)));
+ } else {
+ menuOption.onClick(view);
+ }
+ });
mOptionLayout.addView(menuOptionView);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 321821b..3d6d423 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -73,15 +73,11 @@
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.TransformingTouchDelegate;
import com.android.launcher3.util.ViewPool.Reusable;
@@ -90,6 +86,7 @@
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskUtils;
+import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.TaskCornerRadius;
import com.android.quickstep.views.RecentsView.PageCallbacks;
@@ -189,8 +186,8 @@
private boolean mShowScreenshot;
// The current background requests to load the task thumbnail and icon
- private TaskThumbnailCache.ThumbnailLoadRequest mThumbnailLoadRequest;
- private TaskIconCache.IconLoadRequest mIconLoadRequest;
+ private CancellableTask mThumbnailLoadRequest;
+ private CancellableTask mIconLoadRequest;
// Order in which the footers appear. Lower order appear below higher order.
public static final int INDEX_DIGITAL_WELLBEING_TOAST = 0;
@@ -220,6 +217,7 @@
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
if (isRunningTask()) {
+ // TODO: Replace this animation with createRecentsWindowAnimator
createLaunchAnimationForRunningTask().start();
} else {
launchTask(true /* animate */);
@@ -365,10 +363,7 @@
final PendingAnimation pendingAnimation = getRecentsView().createTaskLaunchAnimation(
this, RECENTS_LAUNCH_DURATION, TOUCH_RESPONSE_INTERPOLATOR);
AnimatorPlaybackController currentAnimation = pendingAnimation.createPlaybackController();
- currentAnimation.setEndAction(() -> {
- pendingAnimation.finish(true, Touch.SWIPE);
- launchTask(false);
- });
+ currentAnimation.setEndAction(() -> pendingAnimation.finish(true));
return currentAnimation;
}
@@ -391,20 +386,6 @@
public void launchTask(boolean animate, boolean freezeTaskList, Consumer<Boolean> resultCallback,
Handler resultCallbackHandler) {
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- if (isRunningTask()) {
- getRecentsView().finishRecentsAnimation(false /* toRecents */,
- () -> resultCallbackHandler.post(() -> resultCallback.accept(true)));
- } else {
- launchTaskInternal(animate, freezeTaskList, resultCallback, resultCallbackHandler);
- }
- } else {
- launchTaskInternal(animate, freezeTaskList, resultCallback, resultCallbackHandler);
- }
- }
-
- private void launchTaskInternal(boolean animate, boolean freezeTaskList,
- Consumer<Boolean> resultCallback, Handler resultCallbackHandler) {
if (mTask != null) {
final ActivityOptions opts;
TestLogging.recordEvent(
@@ -481,15 +462,13 @@
}
}
- private boolean showTaskMenu(int action) {
+ private boolean showTaskMenu() {
if (!getRecentsView().isClearAllHidden()) {
getRecentsView().snapToPage(getRecentsView().indexOfChild(this));
} else {
mMenuView = TaskMenuView.showForTask(this);
mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
.log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS);
- UserEventDispatcher.newInstance(getContext()).logActionOnItem(action, Direction.NONE,
- LauncherLogProto.ItemType.TASK_ICON);
if (mMenuView != null) {
mMenuView.addOnAttachStateChangeListener(mTaskMenuStateListener);
}
@@ -500,10 +479,10 @@
private void setIcon(Drawable icon) {
if (icon != null) {
mIconView.setDrawable(icon);
- mIconView.setOnClickListener(v -> showTaskMenu(Touch.TAP));
+ mIconView.setOnClickListener(v -> showTaskMenu());
mIconView.setOnLongClickListener(v -> {
requestDisallowInterceptTouchEvent(true);
- return showTaskMenu(Touch.LONGPRESS);
+ return showTaskMenu();
});
} else {
mIconView.setDrawable(null);
diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index ccfa3fc..2a7da7e 100644
--- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -3,6 +3,8 @@
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
+import static com.android.launcher3.util.rule.TestStabilityRule.UNBUNDLED_POSTSUBMIT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -11,12 +13,12 @@
import android.app.PendingIntent;
import android.app.usage.UsageStatsManager;
import android.content.Intent;
-import android.os.Build;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.Launcher;
+import com.android.launcher3.util.rule.TestStabilityRule;
import com.android.quickstep.views.DigitalWellBeingToast;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -34,9 +36,6 @@
@Test
public void testToast() throws Exception {
- // b/150303529
- if (Build.MODEL.contains("Cuttlefish")) return;
-
startAppFast(CALCULATOR_PACKAGE);
final UsageStatsManager usageStatsManager =
diff --git a/res/layout/search_result_icon_row.xml b/res/layout/search_result_icon_row.xml
new file mode 100644
index 0000000..5ecc0c2
--- /dev/null
+++ b/res/layout/search_result_icon_row.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.launcher3.views.SearchResultIconRow xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ style="@style/BaseIcon"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding"
+ android:gravity="start|center_vertical"
+ android:textAlignment="viewStart"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="16sp"
+ android:padding="@dimen/dynamic_grid_edge_margin"
+ launcher:iconDisplay="hero_app"
+ launcher:layoutHorizontal="true"
+ >
+
+</com.android.launcher3.views.SearchResultIconRow>
\ No newline at end of file
diff --git a/res/layout/search_result_shortcut.xml b/res/layout/search_result_shortcut.xml
deleted file mode 100644
index c350c97..0000000
--- a/res/layout/search_result_shortcut.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.views.SearchResultShortcut xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:padding="@dimen/dynamic_grid_edge_margin">
-
- <com.android.launcher3.BubbleTextView
- android:id="@+id/bubble_text"
- style="@style/BaseIcon"
- android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding"
- android:gravity="start|center_vertical"
- android:textAlignment="viewStart"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="16sp"
- android:layout_height="wrap_content"
- launcher:iconDisplay="hero_app"
- launcher:layoutHorizontal="true" />
-
- <View
- android:id="@+id/icon"
- android:layout_width="@dimen/deep_shortcut_icon_size"
- android:layout_height="@dimen/deep_shortcut_icon_size"
- android:layout_gravity="start|center_vertical"
- android:background="@drawable/ic_deepshortcut_placeholder" />
-
-</com.android.launcher3.views.SearchResultShortcut>
\ No newline at end of file
diff --git a/res/layout/search_result_suggest.xml b/res/layout/search_result_suggest.xml
new file mode 100644
index 0000000..c5d96f0
--- /dev/null
+++ b/res/layout/search_result_suggest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.launcher3.views.SearchResultSuggestRow xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/TextHeadline"
+ android:id="@+id/section_title"
+ android:background="?android:attr/selectableItemBackground"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_vertical"
+ android:padding="4dp"
+ android:minHeight="48dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="14sp">
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextTitle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingStart="8dp"
+ android:layout_marginBottom="4dp"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="14sp" />
+
+</com.android.launcher3.views.SearchResultSuggestRow>
\ No newline at end of file
diff --git a/res/layout/search_result_thumbnail.xml b/res/layout/search_result_thumbnail.xml
new file mode 100644
index 0000000..0cc5a29
--- /dev/null
+++ b/res/layout/search_result_thumbnail.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.launcher3.views.ThumbnailSearchResultView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="125dp"
+ android:layout_height="125dp"/>
\ No newline at end of file
diff --git a/res/values/config.xml b/res/values/config.xml
index 325b62f..46b8c23 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -59,7 +59,6 @@
<bool name="hotseat_transpose_layout_with_orientation">true</bool>
<!-- Various classes overriden by projects/build flavors. -->
- <string name="user_event_dispatcher_class" translatable="false"></string>
<string name="folder_name_provider_class" translatable="false"></string>
<string name="stats_log_manager_class" translatable="false"></string>
<string name="app_transition_manager_class" translatable="false"></string>
diff --git a/robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java b/robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java
index 0ca5ce6..baae2a6 100644
--- a/robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java
+++ b/robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java
@@ -21,7 +21,6 @@
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
import android.content.Context;
import android.os.UserManager;
@@ -30,8 +29,6 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.allapps.AllAppsPagedView;
import com.android.launcher3.allapps.AllAppsRecyclerView;
-import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.shadows.ShadowOverrides;
import com.android.launcher3.util.LauncherLayoutBuilder;
import com.android.launcher3.util.LauncherModelHelper;
@@ -69,8 +66,6 @@
mModelHelper = new LauncherModelHelper();
mTargetContext = RuntimeEnvironment.application;
mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
- ShadowOverrides.setProvider(UserEventDispatcher.class,
- c -> mock(UserEventDispatcher.class));
Settings.Global.putFloat(mTargetContext.getContentResolver(),
Settings.Global.WINDOW_ANIMATION_SCALE, 0);
diff --git a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
index d330d10..957ae77 100644
--- a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
+++ b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
@@ -20,7 +20,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import static org.mockito.Mockito.mock;
import android.content.Context;
import android.os.SystemClock;
@@ -36,8 +35,6 @@
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.FolderPagedView;
-import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.shadows.ShadowOverrides;
import com.android.launcher3.util.LauncherLayoutBuilder;
import com.android.launcher3.util.LauncherLayoutBuilder.FolderBuilder;
import com.android.launcher3.util.LauncherModelHelper;
@@ -70,8 +67,6 @@
mModelHelper = new LauncherModelHelper();
mTargetContext = RuntimeEnvironment.application;
mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
- ShadowOverrides.setProvider(UserEventDispatcher.class,
- c -> mock(UserEventDispatcher.class));
Settings.Global.putFloat(mTargetContext.getContentResolver(),
Settings.Global.WINDOW_ANIMATION_SCALE, 0);
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 310c306..5e50e27 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -37,8 +37,6 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
@@ -82,7 +80,6 @@
new ArrayList<>();
protected DeviceProfile mDeviceProfile;
- protected UserEventDispatcher mUserEventDispatcher;
protected StatsLogManager mStatsLogManager;
protected SystemUiController mSystemUiController;
@@ -144,8 +141,6 @@
return mDeviceProfile;
}
- public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {}
-
public final StatsLogManager getStatsLogManager() {
if (mStatsLogManager == null) {
mStatsLogManager = StatsLogManager.newInstance(this);
@@ -153,13 +148,6 @@
return mStatsLogManager;
}
- public final UserEventDispatcher getUserEventDispatcher() {
- if (mUserEventDispatcher == null) {
- mUserEventDispatcher = UserEventDispatcher.newInstance(this);
- }
- return mUserEventDispatcher;
- }
-
public SystemUiController getSystemUiController() {
if (mSystemUiController == null) {
mSystemUiController = new SystemUiController(getWindow());
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 06bb263..1e5a9e4 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -23,6 +23,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
@@ -30,6 +31,8 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -43,6 +46,8 @@
import android.view.ViewDebug;
import android.widget.TextView;
+import androidx.core.graphics.ColorUtils;
+
import com.android.launcher3.Launcher.OnResumeCallback;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.dot.DotInfo;
@@ -50,6 +55,7 @@
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.graphics.IconShape;
+import com.android.launcher3.graphics.PlaceHolderIconDrawable;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.IconCache.IconLoadRequest;
@@ -59,6 +65,7 @@
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.model.data.PromiseAppInfo;
+import com.android.launcher3.model.data.RemoteActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.views.ActivityContext;
@@ -84,6 +91,8 @@
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
+ private static final int ICON_UPDATE_ANIMATION_DURATION = 375;
+
private float mScaleForReorderBounce = 1f;
private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
@@ -292,6 +301,14 @@
verifyHighRes();
}
+ /**
+ * Apply label and tag using a {@link RemoteActionItemInfo}
+ */
+ public void applyFromRemoteActionInfo(RemoteActionItemInfo remoteActionItemInfo) {
+ applyIconAndLabel(remoteActionItemInfo);
+ setTag(remoteActionItemInfo);
+ }
+
private void applyIconAndLabel(ItemInfoWithIcon info) {
FastBitmapDrawable iconDrawable = newIcon(getContext(), info);
mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
@@ -636,11 +653,14 @@
mDisableRelayout = mIcon != null;
icon.setBounds(0, 0, mIconSize, mIconSize);
- if (mLayoutHorizontal) {
- setCompoundDrawablesRelative(icon, null, null, null);
- } else {
- setCompoundDrawables(null, icon, null, null);
+
+ updateIcon(icon);
+
+ // If the current icon is a placeholder color, animate its update.
+ if (mIcon != null && mIcon instanceof PlaceHolderIconDrawable) {
+ animateIconUpdate((PlaceHolderIconDrawable) mIcon, icon);
}
+
mDisableRelayout = false;
}
@@ -670,6 +690,8 @@
mActivity.invalidateParent(info);
} else if (info instanceof PackageItemInfo) {
applyFromItemInfoWithIcon((PackageItemInfo) info);
+ } else if (info instanceof RemoteActionItemInfo) {
+ applyFromRemoteActionInfo((RemoteActionItemInfo) info);
}
mDisableRelayout = false;
@@ -776,4 +798,33 @@
((FastBitmapDrawable) mIcon).setScale(1f);
}
}
+
+ private void updateIcon(Drawable newIcon) {
+ if (mLayoutHorizontal) {
+ setCompoundDrawablesRelative(newIcon, null, null, null);
+ } else {
+ setCompoundDrawables(null, newIcon, null, null);
+ }
+ }
+
+ private static void animateIconUpdate(PlaceHolderIconDrawable oldIcon, Drawable newIcon) {
+ int placeholderColor = oldIcon.mPaint.getColor();
+ int originalAlpha = Color.alpha(placeholderColor);
+
+ ValueAnimator iconUpdateAnimation = ValueAnimator.ofInt(originalAlpha, 0);
+ iconUpdateAnimation.setDuration(ICON_UPDATE_ANIMATION_DURATION);
+ iconUpdateAnimation.addUpdateListener(valueAnimator -> {
+ int newAlpha = (int) valueAnimator.getAnimatedValue();
+ int newColor = ColorUtils.setAlphaComponent(placeholderColor, newAlpha);
+
+ newIcon.setColorFilter(new PorterDuffColorFilter(newColor, Mode.SRC_ATOP));
+ });
+ iconUpdateAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ newIcon.setColorFilter(null);
+ }
+ });
+ iconUpdateAnimation.start();
+ }
}
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 09827d6..df005e6 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -47,7 +47,6 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
@@ -395,6 +394,4 @@
TextUtils.TruncateAt.END);
return !mText.equals(displayedText);
}
-
- public abstract Target getDropTargetForLogging();
}
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 1cd201f..2809bd5 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -323,11 +323,8 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (mTouchHelper != null
- || (mInterceptTouchListener != null && mInterceptTouchListener.onTouch(this, ev))) {
- return true;
- }
- return false;
+ return mTouchHelper != null
+ || (mInterceptTouchListener != null && mInterceptTouchListener.onTouch(this, ev));
}
public void enableHardwareLayer(boolean hasLayer) {
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 2857497..cc119c9 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -18,8 +18,7 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_CANCEL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_REMOVE;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.UNDO;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNDO;
import android.content.Context;
import android.text.TextUtils;
@@ -28,22 +27,19 @@
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.views.Snackbar;
public class DeleteDropTarget extends ButtonDropTarget {
private final StatsLogManager mStatsLogManager;
- private int mControlType = ControlType.DEFAULT_CONTROLTYPE;
+ private StatsLogManager.LauncherEvent mLauncherEvent;
public DeleteDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -115,8 +111,8 @@
* Set mControlType depending on the drag item.
*/
private void setControlTypeBasedOnDragSource(ItemInfo item) {
- mControlType = item.id != ItemInfo.NO_ID ? ControlType.REMOVE_TARGET
- : ControlType.CANCEL_TARGET;
+ mLauncherEvent = item.id != ItemInfo.NO_ID ? LAUNCHER_ITEM_DROPPED_ON_REMOVE
+ : LAUNCHER_ITEM_DROPPED_ON_CANCEL;
}
@Override
@@ -127,8 +123,7 @@
}
super.onDrop(d, options);
mStatsLogManager.logger().withInstanceId(d.logInstanceId)
- .log(mControlType == ControlType.REMOVE_TARGET ? LAUNCHER_ITEM_DROPPED_ON_REMOVE
- : LAUNCHER_ITEM_DROPPED_ON_CANCEL);
+ .log(mLauncherEvent);
}
@Override
@@ -141,7 +136,7 @@
Runnable onUndoClicked = () -> {
mLauncher.setPageToBindSynchronously(itemPage);
modelWriter.abortDelete();
- mLauncher.getUserEventDispatcher().logActionOnControl(TAP, UNDO);
+ mLauncher.getStatsLogManager().logger().log(LAUNCHER_UNDO);
};
Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
modelWriter::commitDelete, onUndoClicked);
@@ -161,11 +156,4 @@
mLauncher.getDragLayer()
.announceForAccessibility(getContext().getString(R.string.item_removed));
}
-
- @Override
- public Target getDropTargetForLogging() {
- Target t = LoggerUtils.newTarget(Target.Type.CONTROL);
- t.controlType = mControlType;
- return t;
- }
}
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index d3b86de..139d4a8 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -33,6 +33,8 @@
import android.graphics.drawable.Drawable;
import android.util.Property;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.graphics.PlaceHolderIconDrawable;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
@@ -54,6 +56,8 @@
protected Bitmap mBitmap;
protected final int mIconColor;
+ @Nullable private ColorFilter mColorFilter;
+
private boolean mIsPressed;
private boolean mIsDisabled;
private float mDisabledAlpha = 1f;
@@ -115,7 +119,8 @@
@Override
public void setColorFilter(ColorFilter cf) {
- // No op
+ mColorFilter = cf;
+ updateFilter();
}
@Override
@@ -265,7 +270,7 @@
* Updates the paint to reflect the current brightness and saturation.
*/
protected void updateFilter() {
- mPaint.setColorFilter(mIsDisabled ? getDisabledColorFilter() : null);
+ mPaint.setColorFilter(mIsDisabled ? getDisabledColorFilter() : mColorFilter);
invalidateSelf();
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 51f3819..6547b53 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -16,8 +16,6 @@
package com.android.launcher3;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -27,14 +25,10 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
-import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-
-import java.util.ArrayList;
-
-public class Hotseat extends CellLayout implements LogContainerProvider, Insettable {
+/**
+ * View class that represents the bottom row of the home screen.
+ */
+public class Hotseat extends CellLayout implements Insettable {
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
@@ -79,15 +73,6 @@
}
@Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- child.rank = childInfo.rank;
- child.gridX = childInfo.cellX;
- child.gridY = childInfo.cellY;
- parents.add(newContainerTarget(LauncherLogProto.ContainerType.HOTSEAT));
- }
-
- @Override
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
DeviceProfile grid = mActivity.getDeviceProfile();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4c5224b..ab8d7a5 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,6 +18,7 @@
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
@@ -36,11 +37,10 @@
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ONRESUME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ONSTOP;
-import static com.android.launcher3.logging.StatsLogManager.containerTypeToAtomState;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_ACTIVITY_PAUSED;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_DRAG_AND_DROP;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_LOADER_RUNNING;
@@ -70,6 +70,7 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -89,9 +90,10 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.OvershootInterpolator;
+import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.CallSuper;
@@ -118,13 +120,13 @@
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.folder.FolderGridOrganizer;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.keyboard.CustomActionsPopup;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.model.ModelUtils;
@@ -152,9 +154,6 @@
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.ActivityResultInfo;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.ComponentKey;
@@ -270,6 +269,8 @@
private static final int APPS_VIEW_ALPHA_CHANNEL_INDEX = 1;
private static final int SCRIM_VIEW_ALPHA_CHANNEL_INDEX = 0;
+ private static final int THEME_CROSS_FADE_ANIMATION_DURATION = 375;
+
private LauncherAppTransitionManager mAppTransitionManager;
private Configuration mOldConfig;
@@ -401,6 +402,7 @@
inflateRootView(R.layout.launcher);
setupViews();
+ crossFadeWithPreviousAppearance();
mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);
mAppTransitionManager = LauncherAppTransitionManager.newInstance(this);
@@ -477,7 +479,7 @@
() -> getStateManager().goToState(NORMAL));
if (Utilities.ATLEAST_R) {
- getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
+ getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
}
mLifecycleRegistry = new LifecycleRegistry(this);
@@ -555,7 +557,6 @@
}
private void onIdpChanged(InvariantDeviceProfile idp) {
- mUserEventDispatcher = null;
initDeviceProfile(idp);
dispatchDeviceProfileChanged();
@@ -911,7 +912,7 @@
mOverlayManager.onActivityStopped(this);
}
- logStopAndResume(Action.Command.STOP);
+ logStopAndResume(false /* isResume */);
mAppWidgetHost.setListenIfResumed(false);
NotificationListener.removeNotificationsChangedListener();
}
@@ -933,7 +934,7 @@
@Override
@CallSuper
protected void onDeferredResumed() {
- logStopAndResume(Action.Command.RESUME);
+ logStopAndResume(true /* isResume */);
// Process any items that were added while Launcher was away.
ItemInstallQueue.INSTANCE.get(this)
@@ -950,32 +951,28 @@
protected void handlePendingActivityRequest() { }
- private void logStopAndResume(int command) {
+ private void logStopAndResume(boolean isResume) {
if (mPendingExecutor != null) return;
int pageIndex = mWorkspace.isOverlayShown() ? -1 : mWorkspace.getCurrentPage();
- int containerType = mStateManager.getState().containerType;
+ int statsLogOrdinal = mStateManager.getState().statsLogOrdinal;
StatsLogManager.EventEnum event;
StatsLogManager.StatsLogger logger = getStatsLogManager().logger();
- if (command == Action.Command.RESUME) {
+ if (isResume) {
logger.withSrcState(LAUNCHER_STATE_BACKGROUND)
- .withDstState(containerTypeToAtomState(mStateManager.getState().containerType));
+ .withDstState(mStateManager.getState().statsLogOrdinal);
event = LAUNCHER_ONRESUME;
} else { /* command == Action.Command.STOP */
- logger.withSrcState(containerTypeToAtomState(mStateManager.getState().containerType))
+ logger.withSrcState(mStateManager.getState().statsLogOrdinal)
.withDstState(LAUNCHER_STATE_BACKGROUND);
event = LAUNCHER_ONSTOP;
}
- if (containerType == ContainerType.WORKSPACE && mWorkspace != null) {
- getUserEventDispatcher().logActionCommand(command,
- containerType, -1, pageIndex);
+ if (statsLogOrdinal == LAUNCHER_STATE_HOME && mWorkspace != null) {
logger.withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
.setWorkspace(
LauncherAtom.WorkspaceContainer.newBuilder()
.setPageIndex(pageIndex)).build());
- } else {
- getUserEventDispatcher().logActionCommand(command, containerType, -1);
}
logger.log(event);
}
@@ -1365,6 +1362,18 @@
closeContextMenu();
}
+ @Override
+ public Object onRetainNonConfigurationInstance() {
+ int width = mDragLayer.getWidth();
+ int height = mDragLayer.getHeight();
+
+ if (width <= 0 || height <= 0) {
+ return null;
+ }
+
+ return BitmapRenderer.createHardwareBitmap(width, height, mDragLayer::draw);
+ }
+
public AllAppsTransitionController getAllAppsController() {
return mAllAppsController;
}
@@ -1465,11 +1474,6 @@
}
// Handle HOME_INTENT
- UserEventDispatcher ued = getUserEventDispatcher();
- Target target = newContainerTarget(mStateManager.getState().containerType);
- target.pageIndex = mWorkspace.getCurrentPage();
- ued.logActionCommand(Action.Command.HOME_INTENT, target,
- newContainerTarget(ContainerType.WORKSPACE));
hideKeyboard();
if (mLauncherCallbacks != null) {
@@ -2759,4 +2763,40 @@
void onLauncherResume();
}
+
+ /**
+ * Cross-fades the launcher's updated appearance with its previous appearance.
+ *
+ * This method is used to cross-fade UI updates on activity creation, specifically dark mode
+ * updates.
+ */
+ private void crossFadeWithPreviousAppearance() {
+ Bitmap previousAppearanceBitmap = (Bitmap) getLastNonConfigurationInstance();
+
+ if (previousAppearanceBitmap == null) {
+ return;
+ }
+
+ ImageView crossFadeHelper = new ImageView(this);
+
+ crossFadeHelper.setImageBitmap(previousAppearanceBitmap);
+ crossFadeHelper.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
+
+ InsettableFrameLayout.LayoutParams layoutParams = new InsettableFrameLayout.LayoutParams(
+ InsettableFrameLayout.LayoutParams.MATCH_PARENT,
+ InsettableFrameLayout.LayoutParams.MATCH_PARENT);
+
+ layoutParams.ignoreInsets = true;
+
+ crossFadeHelper.setLayoutParams(layoutParams);
+
+ getRootView().addView(crossFadeHelper);
+
+ crossFadeHelper
+ .animate()
+ .setDuration(THEME_CROSS_FADE_ANIMATION_DURATION)
+ .alpha(0f)
+ .withEndAction(() -> getRootView().removeView(crossFadeHelper))
+ .start();
+ }
}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index bfe327e..a4181c5 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -105,7 +105,7 @@
new Handler().post( () -> mInvariantDeviceProfile.verifyConfigChangedInBackground(context));
mInstallSessionTracker = InstallSessionHelper.INSTANCE.get(context)
- .registerInstallTracker(mModel, MODEL_EXECUTOR);
+ .registerInstallTracker(mModel);
// Register an observer to rebind the notification listener when dots are re-enabled.
mNotificationDotsObserver =
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index b6bc500..eba0ac9 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.BACKGROUND_APP_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.HINT_STATE_ORDINAL;
@@ -35,7 +36,6 @@
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.uioverrides.states.AllAppsState;
import com.android.launcher3.uioverrides.states.OverviewState;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import java.util.Arrays;
@@ -97,7 +97,7 @@
* TODO: Create a separate class for NORMAL state.
*/
public static final LauncherState NORMAL = new LauncherState(NORMAL_STATE_ORDINAL,
- ContainerType.WORKSPACE,
+ LAUNCHER_STATE_HOME,
FLAG_DISABLE_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED | FLAG_HIDE_BACK_BUTTON |
FLAG_HAS_SYS_UI_SCRIM) {
@Override
@@ -126,9 +126,9 @@
public final int ordinal;
/**
- * Used for containerType in {@link com.android.launcher3.logging.UserEventDispatcher}
+ * Used for {@link com.android.launcher3.logging.StatsLogManager}
*/
- public final int containerType;
+ public final int statsLogOrdinal;
/**
* True if the state has overview panel visible.
@@ -137,8 +137,8 @@
private final int mFlags;
- public LauncherState(int id, int containerType, int flags) {
- this.containerType = containerType;
+ public LauncherState(int id, int statsLogOrdinal, int flags) {
+ this.statsLogOrdinal = statsLogOrdinal;
this.mFlags = flags;
this.overviewUi = (flags & FLAG_OVERVIEW_UI) != 0;
this.ordinal = id;
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 2df7f5a..92b88e6 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -37,14 +37,11 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.logging.FileLog;
-import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Themes;
@@ -135,19 +132,6 @@
}
@Override
- public Target getDropTargetForLogging() {
- Target t = LoggerUtils.newTarget(Target.Type.CONTROL);
- if (mCurrentAccessibilityAction == UNINSTALL) {
- t.controlType = ControlType.UNINSTALL_TARGET;
- } else if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
- t.controlType = ControlType.DISMISS_PREDICTION;
- } else {
- t.controlType = ControlType.SETTINGS_BUTTON;
- }
- return t;
- }
-
- @Override
protected boolean supportsDrop(ItemInfo info) {
return supportsAccessibilityDrop(info, getViewUnderDrag(info));
}
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 007e5f5..1bbbb2b 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -25,8 +25,11 @@
import android.os.UserHandle;
import android.text.TextUtils;
+import androidx.annotation.WorkerThread;
+
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.pm.InstallSessionHelper;
+import com.android.launcher3.util.Executors;
/**
* BroadcastReceiver to handle session commit intent.
@@ -38,6 +41,11 @@
@Override
public void onReceive(Context context, Intent intent) {
+ Executors.MODEL_EXECUTOR.execute(() -> processIntent(context, intent));
+ }
+
+ @WorkerThread
+ private static void processIntent(Context context, Intent intent) {
if (!isEnabled(context)) {
// User has decided to not add icons on homescreen.
return;
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index dea2a8d..43ccb79 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -133,6 +133,10 @@
public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET";
public static final String EXTRA_WALLPAPER_FLAVOR = "com.android.launcher3.WALLPAPER_FLAVOR";
+ // An intent extra to indicate the launch source by launcher.
+ public static final String EXTRA_WALLPAPER_LAUNCH_SOURCE =
+ "com.android.wallpaper.LAUNCH_SOURCE";
+
public static boolean IS_RUNNING_IN_TEST_HARNESS =
ActivityManager.isRunningInTestHarness();
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 45aaa1b..98328cf 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -85,7 +85,6 @@
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
-import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
@@ -97,8 +96,6 @@
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.WorkspaceTouchListener;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSparseArrayMap;
@@ -1004,8 +1001,6 @@
public void onOverlayScrollChanged(float scroll) {
if (Float.compare(scroll, 1f) == 0) {
if (!mOverlayShown) {
- mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
- Action.Direction.LEFT, ContainerType.WORKSPACE, 0);
mLauncher.getStatsLogManager().logger()
.withSrcState(LAUNCHER_STATE_HOME)
.withDstState(LAUNCHER_STATE_HOME)
@@ -1020,20 +1015,16 @@
// Not announcing the overlay page for accessibility since it announces itself.
} else if (Float.compare(scroll, 0f) == 0) {
if (mOverlayShown) {
- UserEventDispatcher ued = mLauncher.getUserEventDispatcher();
- if (!ued.isPreviousHomeGesture()) {
- mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
- Action.Direction.RIGHT, ContainerType.WORKSPACE, -1);
- mLauncher.getStatsLogManager().logger()
- .withSrcState(LAUNCHER_STATE_HOME)
- .withDstState(LAUNCHER_STATE_HOME)
- .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setWorkspace(
- LauncherAtom.WorkspaceContainer.newBuilder()
- .setPageIndex(-1))
- .build())
- .log(LAUNCHER_SWIPERIGHT);
- }
+ // TODO: this is logged unnecessarily on home gesture.
+ mLauncher.getStatsLogManager().logger()
+ .withSrcState(LAUNCHER_STATE_HOME)
+ .withDstState(LAUNCHER_STATE_HOME)
+ .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(-1))
+ .build())
+ .log(LAUNCHER_SWIPERIGHT);
} else if (Float.compare(mOverlayTranslation, 0f) != 0) {
// When arriving to 0 overscroll from non-zero overscroll, announce page for
// accessibility since default announcements were disabled while in overscroll
@@ -1124,12 +1115,8 @@
protected void notifyPageSwitchListener(int prevPage) {
super.notifyPageSwitchListener(prevPage);
if (prevPage != mCurrentPage) {
- int swipeDirection = (prevPage < mCurrentPage)
- ? Action.Direction.RIGHT : Action.Direction.LEFT;
StatsLogManager.EventEnum event = (prevPage < mCurrentPage)
? LAUNCHER_SWIPERIGHT : LAUNCHER_SWIPELEFT;
- mLauncher.getUserEventDispatcher().logActionOnContainer(Action.Touch.SWIPE,
- swipeDirection, ContainerType.WORKSPACE, prevPage);
mLauncher.getStatsLogManager().logger()
.withSrcState(LAUNCHER_STATE_HOME)
.withDstState(LAUNCHER_STATE_HOME)
@@ -1176,13 +1163,6 @@
}
@Override
- protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
- if (!isSwitchingState()) {
- super.determineScrollingStart(ev, touchSlopScale);
- }
- }
-
- @Override
public void announceForAccessibility(CharSequence text) {
// Don't announce if apps is on top of us.
if (!mLauncher.isInState(ALL_APPS)) {
diff --git a/src/com/android/launcher3/WorkspaceLayoutManager.java b/src/com/android/launcher3/WorkspaceLayoutManager.java
index ea887cc..d6302ce 100644
--- a/src/com/android/launcher3/WorkspaceLayoutManager.java
+++ b/src/com/android/launcher3/WorkspaceLayoutManager.java
@@ -130,12 +130,16 @@
}
child.setHapticFeedbackEnabled(false);
- child.setOnLongClickListener(ItemLongClickListener.INSTANCE_WORKSPACE);
+ child.setOnLongClickListener(getWorkspaceChildOnLongClickListener());
if (child instanceof DropTarget) {
onAddDropTarget((DropTarget) child);
}
}
+ default View.OnLongClickListener getWorkspaceChildOnLongClickListener() {
+ return ItemLongClickListener.INSTANCE_WORKSPACE;
+ }
+
Hotseat getHotseat();
CellLayout getScreenWithId(int screenId);
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index d1340fa..8bc8e53 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -92,10 +92,14 @@
public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 9;
- public static final int VIEW_TYPE_SEARCH_SHORTCUT = 1 << 10;
+ public static final int VIEW_TYPE_SEARCH_ICON_ROW = 1 << 10;
public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11;
+ public static final int VIEW_TYPE_SEARCH_THUMBNAIL = 1 << 12;
+
+ public static final int VIEW_TYPE_SEARCH_SUGGEST = 1 << 13;
+
// Common view type masks
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
@@ -186,7 +190,9 @@
|| viewType == VIEW_TYPE_SEARCH_SLICE
|| viewType == VIEW_TYPE_SEARCH_ROW
|| viewType == VIEW_TYPE_SEARCH_PEOPLE
- || viewType == VIEW_TYPE_SEARCH_SHORTCUT;
+ || viewType == VIEW_TYPE_SEARCH_THUMBNAIL
+ || viewType == VIEW_TYPE_SEARCH_ICON_ROW
+ || viewType == VIEW_TYPE_SEARCH_SUGGEST;
}
}
@@ -197,6 +203,7 @@
*/
public static class AdapterItemWithPayload<T> extends AdapterItem {
private T mPayload;
+ private String mSearchSessionId;
private AllAppsSearchPlugin mPlugin;
private IntConsumer mSelectionHandler;
@@ -218,6 +225,14 @@
mSelectionHandler = runnable;
}
+ public void setSearchSessionId(String searchSessionId) {
+ mSearchSessionId = searchSessionId;
+ }
+
+ public String getSearchSessionId() {
+ return mSearchSessionId;
+ }
+
public IntConsumer getSelectionHandler() {
return mSelectionHandler;
}
@@ -225,6 +240,8 @@
public T getPayload() {
return mPayload;
}
+
+
}
/**
@@ -307,15 +324,21 @@
@Override
public int getSpanSize(int position) {
- if (isIconViewType(mApps.getAdapterItems().get(position).viewType)) {
- return 1;
+ int viewType = mApps.getAdapterItems().get(position).viewType;
+ if (isIconViewType(viewType)) {
+ return 1 * SPAN_MULTIPLIER;
+ } else if (viewType == VIEW_TYPE_SEARCH_THUMBNAIL) {
+ return mAppsPerRow;
} else {
// Section breaks span the full width
- return mAppsPerRow;
+ return mAppsPerRow * SPAN_MULTIPLIER;
}
}
}
+ // multiplier to support adapter item column count that is not mAppsPerRow.
+ public static final int SPAN_MULTIPLIER = 3;
+
private final BaseDraggingActivity mLauncher;
private final LayoutInflater mLayoutInflater;
private final AlphabeticalAppsList mApps;
@@ -352,7 +375,7 @@
public void setAppsPerRow(int appsPerRow) {
mAppsPerRow = appsPerRow;
- mGridLayoutMgr.setSpanCount(mAppsPerRow);
+ mGridLayoutMgr.setSpanCount(mAppsPerRow * SPAN_MULTIPLIER);
}
/**
@@ -438,12 +461,18 @@
case VIEW_TYPE_SEARCH_SLICE:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.search_result_slice, parent, false));
- case VIEW_TYPE_SEARCH_SHORTCUT:
+ case VIEW_TYPE_SEARCH_ICON_ROW:
return new ViewHolder(mLayoutInflater.inflate(
- R.layout.search_result_shortcut, parent, false));
+ R.layout.search_result_icon_row, parent, false));
case VIEW_TYPE_SEARCH_PEOPLE:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.search_result_people_item, parent, false));
+ case VIEW_TYPE_SEARCH_THUMBNAIL:
+ return new ViewHolder(mLayoutInflater.inflate(
+ R.layout.search_result_thumbnail, parent, false));
+ case VIEW_TYPE_SEARCH_SUGGEST:
+ return new ViewHolder(mLayoutInflater.inflate(
+ R.layout.search_result_suggest, parent, false));
default:
throw new RuntimeException("Unexpected view type");
}
@@ -464,24 +493,27 @@
//TODO: replace with custom TopHitBubbleTextView with support for both shortcut
// and apps
if (adapterItem instanceof AdapterItemWithPayload) {
- AdapterItemWithPayload withPayload = (AdapterItemWithPayload) adapterItem;
- IntConsumer selectionHandler = type -> {
+ AdapterItemWithPayload item = (AdapterItemWithPayload) adapterItem;
+ item.setSelectionHandler(type -> {
SearchTargetEvent e = new SearchTargetEvent(SearchTarget.ItemType.APP,
- type);
+ type, item.position, item.getSearchSessionId());
e.bundle = HeroSearchResultView.getAppBundle(info);
- if (withPayload.getPlugin() != null) {
- withPayload.getPlugin().notifySearchTargetEvent(e);
+ if (item.getPlugin() != null) {
+ item.getPlugin().notifySearchTargetEvent(e);
}
- };
+ });
icon.setOnClickListener(view -> {
- selectionHandler.accept(SearchTargetEvent.SELECT);
+ item.getSelectionHandler().accept(SearchTargetEvent.SELECT);
mOnIconClickListener.onClick(view);
});
icon.setOnLongClickListener(view -> {
- selectionHandler.accept(SearchTargetEvent.LONG_PRESS);
+ item.getSelectionHandler().accept(SearchTargetEvent.SELECT);
return mOnIconLongClickListener.onLongClick(view);
});
- withPayload.setSelectionHandler(selectionHandler);
+ }
+ else {
+ icon.setOnClickListener(mOnIconClickListener);
+ icon.setOnLongClickListener(mOnIconLongClickListener);
}
break;
case VIEW_TYPE_EMPTY_SEARCH:
@@ -500,20 +532,22 @@
break;
case VIEW_TYPE_SEARCH_SLICE:
SliceView sliceView = (SliceView) holder.itemView;
- AdapterItemWithPayload<Uri> item =
+ AdapterItemWithPayload<Uri> slicePayload =
(AdapterItemWithPayload<Uri>) mApps.getAdapterItems().get(position);
sliceView.setOnSliceActionListener((info1, s) -> {
- if (item.getPlugin() != null) {
+ if (slicePayload.getPlugin() != null) {
SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
SearchTarget.ItemType.SETTINGS_SLICE,
- SearchTargetEvent.CHILD_SELECT);
+ SearchTargetEvent.CHILD_SELECT, slicePayload.position,
+ slicePayload.getSearchSessionId());
searchTargetEvent.bundle = new Bundle();
- searchTargetEvent.bundle.putParcelable("uri", item.getPayload());
- item.getPlugin().notifySearchTargetEvent(searchTargetEvent);
+ searchTargetEvent.bundle.putParcelable("uri", slicePayload.getPayload());
+ slicePayload.getPlugin().notifySearchTargetEvent(searchTargetEvent);
}
});
try {
- LiveData<Slice> liveData = SliceLiveData.fromUri(mLauncher, item.getPayload());
+ LiveData<Slice> liveData = SliceLiveData.fromUri(mLauncher,
+ slicePayload.getPayload());
liveData.observe((Launcher) mLauncher, sliceView);
sliceView.setTag(liveData);
} catch (Exception ignored) {
@@ -523,11 +557,14 @@
case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
case VIEW_TYPE_SEARCH_HERO_APP:
case VIEW_TYPE_SEARCH_ROW:
- case VIEW_TYPE_SEARCH_SHORTCUT:
+ case VIEW_TYPE_SEARCH_ICON_ROW:
case VIEW_TYPE_SEARCH_PEOPLE:
+ case VIEW_TYPE_SEARCH_THUMBNAIL:
+ case VIEW_TYPE_SEARCH_SUGGEST:
+ AdapterItemWithPayload item =
+ (AdapterItemWithPayload) mApps.getAdapterItems().get(position);
PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView;
- payloadResultView.applyAdapterInfo(
- (AdapterItemWithPayload) mApps.getAdapterItems().get(position));
+ payloadResultView.setup(item);
break;
case VIEW_TYPE_ALL_APPS_DIVIDER:
// nothing to do
@@ -541,8 +578,8 @@
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) return;
if (holder.itemView instanceof BubbleTextView) {
BubbleTextView icon = (BubbleTextView) holder.itemView;
- icon.setOnClickListener(mOnIconClickListener);
- icon.setOnLongClickListener(mOnIconLongClickListener);
+ icon.setOnClickListener(null);
+ icon.setOnLongClickListener(null);
} else if (holder.itemView instanceof SliceView) {
SliceView sliceView = (SliceView) holder.itemView;
sliceView.setOnSliceActionListener(null);
@@ -553,7 +590,6 @@
}
}
-
@Override
public boolean onFailedToRecycleView(ViewHolder holder) {
// Always recycle and we will reset the view when it is bound
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 13a93ff..72b6d94 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -19,8 +19,6 @@
import static android.view.View.MeasureSpec.UNSPECIFIED;
import static android.view.View.MeasureSpec.makeMeasureSpec;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -38,10 +36,6 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsGridAdapter.AppsGridLayoutManager;
-import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.views.RecyclerViewFastScroller;
import java.util.ArrayList;
@@ -50,7 +44,7 @@
/**
* A RecyclerView with custom fast scroll support for the all apps view.
*/
-public class AllAppsRecyclerView extends BaseRecyclerView implements LogContainerProvider {
+public class AllAppsRecyclerView extends BaseRecyclerView {
private AlphabeticalAppsList mApps;
private final int mNumAppsPerRow;
@@ -176,13 +170,6 @@
mAutoSizedOverlays.clear();
}
- @Override
- public void fillInLogContainerData(ItemInfo childInfo, Target child,
- ArrayList<Target> parents) {
- parents.add(newContainerTarget(
- getApps().hasFilter() ? ContainerType.SEARCHRESULT : ContainerType.ALLAPPS));
- }
-
public void onSearchResultsChanged() {
// Always scroll the view to the top so the user can see the changed results
scrollToTop();
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index 14595ca..0005db8 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -18,8 +18,6 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.HOTSEAT;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.PREDICTION;
import android.animation.Animator;
import android.animation.AnimatorInflater;
@@ -120,10 +118,10 @@
return (type & TYPE_DISCOVERY_BOUNCE) != 0;
}
- private void show(int containerType) {
+ private void show() {
mIsOpen = true;
mLauncher.getDragLayer().addView(this);
- mLauncher.getUserEventDispatcher().logActionBounceTip(containerType);
+ // TODO: add WW log for discovery bounce tip show event.
}
public static void showForHomeIfNeeded(Launcher launcher) {
@@ -146,7 +144,7 @@
}
onboardingPrefs.incrementEventCount(OnboardingPrefs.HOME_BOUNCE_COUNT);
- new DiscoveryBounce(launcher, 0).show(HOTSEAT);
+ new DiscoveryBounce(launcher, 0).show();
}
public static void showForOverviewIfNeeded(Launcher launcher,
@@ -179,7 +177,7 @@
onboardingPrefs.incrementEventCount(OnboardingPrefs.SHELF_BOUNCE_COUNT);
new DiscoveryBounce(launcher, (1 - OVERVIEW.getVerticalProgress(launcher)))
- .show(PREDICTION);
+ .show();
}
/**
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index 3320189..d7fa5bc 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -35,6 +35,8 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.systemui.plugins.AllAppsSearchPlugin;
+import com.android.systemui.plugins.shared.SearchTarget;
+import com.android.systemui.plugins.shared.SearchTargetEvent;
import java.util.ArrayList;
import java.util.List;
@@ -213,6 +215,44 @@
/**
* Updates View using Adapter's payload
*/
+
+ default void setup(AdapterItemWithPayload<T> adapterItemWithPayload) {
+ Object[] targetInfo = getTargetInfo();
+ if (targetInfo != null) {
+ targetInfo[0] = adapterItemWithPayload.getSearchSessionId();
+ targetInfo[1] = adapterItemWithPayload.position;
+ }
+ applyAdapterInfo(adapterItemWithPayload);
+ }
+
void applyAdapterInfo(AdapterItemWithPayload<T> adapterItemWithPayload);
+
+ /**
+ * Gets object created by {@link PayloadResultHandler#createTargetInfo()}
+ */
+ Object[] getTargetInfo();
+
+ /**
+ * Creates a wrapper object to hold searchSessionId and item position
+ */
+ default Object[] createTargetInfo() {
+ return new Object[2];
+ }
+
+ /**
+ * Generates a SearchTargetEvent object for a PayloadHandlerView
+ */
+ default SearchTargetEvent getSearchTargetEvent(SearchTarget.ItemType itemType,
+ int eventType) {
+ Object[] targetInfo = getTargetInfo();
+ if (targetInfo == null) return null;
+
+ String searchSessionId = (String) targetInfo[0];
+ int position = (int) targetInfo[1];
+ return new SearchTargetEvent(itemType, eventType,
+ position, searchSessionId);
+ }
}
+
+
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index 5362575..6dd316e 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -73,9 +73,9 @@
addAnimationHoldersRecur(a, mDuration, springProperty, mAnimHolders);
}
- public void finish(boolean isSuccess, int logAction) {
+ public void finish(boolean isSuccess) {
for (Consumer<EndState> listeners : mEndListeners) {
- listeners.accept(new EndState(isSuccess, logAction));
+ listeners.accept(new EndState(isSuccess));
}
mEndListeners.clear();
}
@@ -164,7 +164,7 @@
/**
* Add a listener of receiving the end state.
- * Note that the listeners are called as a result of calling {@link #finish(boolean, int)}
+ * Note that the listeners are called as a result of calling {@link #finish(boolean)}
* and not automatically
*/
public void addEndListener(Consumer<EndState> listener) {
@@ -173,11 +173,9 @@
public static class EndState {
public boolean isSuccess;
- public int logAction;
- public EndState(boolean isSuccess, int logAction) {
+ public EndState(boolean isSuccess) {
this.isSuccess = isSuccess;
- this.logAction = logAction;
}
}
}
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 2d625c5..42e247a 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -16,10 +16,11 @@
package com.android.launcher3.dragndrop;
-import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
-import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ADD_EXTERNAL_ITEM_BACK;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ADD_EXTERNAL_ITEM_CANCELLED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ADD_EXTERNAL_ITEM_DRAGGED;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ADD_EXTERNAL_ITEM_PLACED_AUTOMATICALLY;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ADD_EXTERNAL_ITEM_START;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.annotation.TargetApi;
@@ -49,11 +50,10 @@
import com.android.launcher3.LauncherAppWidgetHost;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.R;
+import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pm.PinRequestHelper;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.widget.PendingAddShortcutInfo;
@@ -125,7 +125,7 @@
// savedInstanceState is null when the activity is created the first time (i.e., avoids
// duplicate logging during rotation)
if (savedInstanceState == null) {
- logCommand(Action.Command.ENTRY);
+ logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_START);
}
}
@@ -178,6 +178,7 @@
startActivity(homeIntent,
ActivityOptions.makeCustomAnimation(this, 0, android.R.anim.fade_out)
.toBundle());
+ logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_DRAGGED);
mFinishOnPause = true;
return false;
}
@@ -240,7 +241,7 @@
* Called when the cancel button is clicked.
*/
public void onCancelClick(View v) {
- logCommand(Action.Command.CANCEL);
+ logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_CANCELLED);
finish();
}
@@ -250,7 +251,7 @@
public void onPlaceAutomaticallyClick(View v) {
if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
ItemInstallQueue.INSTANCE.get(this).queueItem(mRequest.getShortcutInfo());
- logCommand(Action.Command.CONFIRM);
+ logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_PLACED_AUTOMATICALLY);
mRequest.accept();
finish();
return;
@@ -274,13 +275,13 @@
.queueItem(mRequest.getAppWidgetProviderInfo(this), widgetId);
mWidgetOptions.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
mRequest.accept(mWidgetOptions);
- logCommand(Action.Command.CONFIRM);
+ logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_PLACED_AUTOMATICALLY);
finish();
}
@Override
public void onBackPressed() {
- logCommand(Action.Command.BACK);
+ logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_BACK);
super.onBackPressed();
}
@@ -320,10 +321,7 @@
throw new UnsupportedOperationException();
}
- private void logCommand(int command) {
- getUserEventDispatcher().dispatchUserEvent(newLauncherEvent(
- newCommandAction(command),
- newItemTarget(mWidgetCell.getWidgetView(), mInstantAppResolver),
- newContainerTarget(ContainerType.PINITEM)), null);
+ private void logCommand(StatsLogManager.EventEnum command) {
+ getStatsLogManager().logger().log(command);
}
}
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index ef666f0..1cfe6ac 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -206,7 +206,6 @@
}
handleMoveEvent(mLastTouch.x, mLastTouch.y);
- mLauncher.getUserEventDispatcher().resetActionDurationMillis();
if (!mLauncher.isTouchInProgress() && options.simulatedDndStartPoint == null) {
// If it is an internal drag and the touch is already complete, cancel immediately
@@ -544,7 +543,6 @@
}
}
final View dropTargetAsView = dropTarget instanceof View ? (View) dropTarget : null;
- mLauncher.getUserEventDispatcher().logDragNDrop(mDragObject, dropTargetAsView);
dispatchDropComplete(dropTargetAsView, accepted);
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 281598a..63fa391 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -23,7 +23,6 @@
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
@@ -95,7 +94,6 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pageindicators.PageIndicatorDots;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ClipPathView;
@@ -599,15 +597,6 @@
* is played.
*/
private void animateOpen(List<WorkspaceItemInfo> items, int pageNo) {
- animateOpen(items, pageNo, false);
- }
-
- /**
- * Opens the user folder described by the specified tag. The opening of the folder
- * is animated relative to the specified View. If the View is null, no animation
- * is played.
- */
- private void animateOpen(List<WorkspaceItemInfo> items, int pageNo, boolean skipUserEventLog) {
Folder openFolder = getOpen(mLauncher);
if (openFolder != null && openFolder != this) {
// Close any open folder before opening a folder.
@@ -657,14 +646,6 @@
mState = STATE_OPEN;
announceAccessibilityChanges();
- if (!skipUserEventLog) {
- mLauncher.getUserEventDispatcher().logActionOnItem(
- LauncherLogProto.Action.Touch.TAP,
- LauncherLogProto.Action.Direction.NONE,
- LauncherLogProto.ItemType.FOLDER_ICON, mInfo.cellX, mInfo.cellY);
- }
-
-
mContent.setFocusOnFirstChild();
}
});
@@ -1513,7 +1494,6 @@
}
statsLogger.log(LAUNCHER_FOLDER_LABEL_UPDATED);
- logFolderLabelState(mFromLabelState, toLabelState);
mFolderName.dispatchBackKey();
}
}
@@ -1644,8 +1624,7 @@
return true;
}
} else {
- mLauncher.getUserEventDispatcher().logActionTapOutside(
- newContainerTarget(LauncherLogProto.ContainerType.FOLDER));
+ // TODO: add ww log if need to gather tap outside to close folder
close(true);
return true;
}
@@ -1680,17 +1659,6 @@
return mContent;
}
- /**
- * Logs current folder label info.
- *
- * @deprecated This method is only used for log validation and soon will be removed.
- */
- @Deprecated
- public void logFolderLabelState(FromState fromState, ToState toState) {
- mLauncher.getUserEventDispatcher()
- .logLauncherEvent(mInfo.getFolderLabelStateLauncherEvent(fromState, toState));
- }
-
/** Returns the height of the current folder's bottom edge from the bottom of the screen. */
private int getHeightFromBottom() {
DragLayer.LayoutParams layoutParams = (DragLayer.LayoutParams) getLayoutParams();
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 32d061c..3296eed 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -478,7 +478,6 @@
// event is assumed to be folder creation on the server side.
.withEditText(newTitle.toString())
.log(LAUNCHER_FOLDER_AUTO_LABELED);
- mFolder.logFolderLabelState(fromState, ToState.TO_SUGGESTION0);
}
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index cd84c96..effb3a4 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -513,8 +513,7 @@
}
// Setup search view
- SearchUiManager searchUiManager =
- mRootView.findViewById(R.id.search_container_all_apps);
+ SearchUiManager searchUiManager = mRootView.findViewById(R.id.search_container_all_apps);
mRootView.findViewById(R.id.apps_view).setTranslationY(
mDp.heightPx - searchUiManager.getScrollRangeDelta(mInsets));
ViewGroup searchView = (ViewGroup) searchUiManager;
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
deleted file mode 100644
index cd4f034..0000000
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.logging;
-
-import android.util.ArrayMap;
-import android.util.SparseArray;
-import android.view.View;
-
-import com.android.launcher3.ButtonDropTarget;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogExtensions.TargetExtension;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.util.InstantAppResolver;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-
-/**
- * Helper methods for logging.
- */
-public class LoggerUtils {
- private static final ArrayMap<Class, SparseArray<String>> sNameCache = new ArrayMap<>();
- private static final String UNKNOWN = "UNKNOWN";
- private static final int DEFAULT_PREDICTED_RANK = 10000;
- private static final String DELIMITER_DOT = "\\.";
-
- public static String getFieldName(int value, Class c) {
- SparseArray<String> cache;
- synchronized (sNameCache) {
- cache = sNameCache.get(c);
- if (cache == null) {
- cache = new SparseArray<>();
- for (Field f : c.getDeclaredFields()) {
- if (f.getType() == int.class && Modifier.isStatic(f.getModifiers())) {
- try {
- f.setAccessible(true);
- cache.put(f.getInt(null), f.getName());
- } catch (IllegalAccessException e) {
- // Ignore
- }
- }
- }
- sNameCache.put(c, cache);
- }
- }
- String result = cache.get(value);
- return result != null ? result : UNKNOWN;
- }
-
- public static Target newItemTarget(int itemType) {
- Target t = newTarget(Target.Type.ITEM);
- t.itemType = itemType;
- return t;
- }
-
- public static Target newItemTarget(View v, InstantAppResolver instantAppResolver) {
- return (v != null) && (v.getTag() instanceof ItemInfo)
- ? newItemTarget((ItemInfo) v.getTag(), instantAppResolver)
- : newTarget(Target.Type.ITEM);
- }
-
- public static Target newItemTarget(ItemInfo info, InstantAppResolver instantAppResolver) {
- Target t = newTarget(Target.Type.ITEM);
- switch (info.itemType) {
- case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
- t.itemType = (instantAppResolver != null && info instanceof AppInfo
- && instantAppResolver.isInstantApp(((AppInfo) info)))
- ? ItemType.WEB_APP
- : ItemType.APP_ICON;
- t.predictedRank = DEFAULT_PREDICTED_RANK;
- break;
- case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
- t.itemType = ItemType.SHORTCUT;
- t.predictedRank = DEFAULT_PREDICTED_RANK;
- break;
- case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
- t.itemType = ItemType.FOLDER_ICON;
- break;
- case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
- t.itemType = ItemType.WIDGET;
- break;
- case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- t.itemType = ItemType.DEEPSHORTCUT;
- t.predictedRank = DEFAULT_PREDICTED_RANK;
- break;
- }
- return t;
- }
-
- public static Target newDropTarget(View v) {
- if (!(v instanceof ButtonDropTarget)) {
- return newTarget(Target.Type.CONTAINER);
- }
- if (v instanceof ButtonDropTarget) {
- return ((ButtonDropTarget) v).getDropTargetForLogging();
- }
- return newTarget(Target.Type.CONTROL);
- }
-
- public static Target newTarget(int targetType, TargetExtension extension) {
- Target t = new Target();
- t.type = targetType;
- t.extension = extension;
- return t;
- }
-
- public static Target newTarget(int targetType) {
- Target t = new Target();
- t.type = targetType;
- return t;
- }
-
- public static Target newControlTarget(int controlType) {
- Target t = newTarget(Target.Type.CONTROL);
- t.controlType = controlType;
- return t;
- }
-
- public static Target newContainerTarget(int containerType) {
- Target t = newTarget(Target.Type.CONTAINER);
- t.containerType = containerType;
- return t;
- }
-
- public static Action newAction(int type) {
- Action a = new Action();
- a.type = type;
- return a;
- }
-
- public static Action newCommandAction(int command) {
- Action a = newAction(Action.Type.COMMAND);
- a.command = command;
- return a;
- }
-
- public static Action newTouchAction(int touch) {
- Action a = newAction(Action.Type.TOUCH);
- a.touch = touch;
- return a;
- }
-
- public static LauncherEvent newLauncherEvent(Action action, Target... srcTargets) {
- LauncherEvent event = new LauncherEvent();
- event.srcTarget = srcTargets;
- event.action = action;
- return event;
- }
-
- /**
- * Creates LauncherEvent using Action and ArrayList of Targets
- */
- public static LauncherEvent newLauncherEvent(Action action, ArrayList<Target> targets) {
- Target[] targetsArray = new Target[targets.size()];
- targets.toArray(targetsArray);
- return newLauncherEvent(action, targetsArray);
- }
-
- /**
- * String conversion for only the helpful parts of {@link Object#toString()} method
- * @param stringToExtract "foo.bar.baz.MyObject@1234"
- * @return "MyObject@1234"
- */
- public static String extractObjectNameAndAddress(String stringToExtract) {
- String[] superStringParts = stringToExtract.split(DELIMITER_DOT);
- if (superStringParts.length == 0) {
- return "";
- }
- return superStringParts[superStringParts.length - 1];
- }
-}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index ec1c3ef..2c5bf32 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -27,7 +27,6 @@
import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.LauncherLogProto;
import com.android.launcher3.util.ResourceBasedOverride;
import java.util.List;
@@ -51,40 +50,22 @@
public static final int LAUNCHER_STATE_UNCHANGED = 5;
/**
- * Returns proper launcher state enum for {@link StatsLogManager}(to be removed during
- * UserEventDispatcher cleanup)
- */
- public static int containerTypeToAtomState(int containerType) {
- switch (containerType) {
- case LauncherLogProto.ContainerType.ALLAPPS_VALUE:
- return LAUNCHER_STATE_ALLAPPS;
- case LauncherLogProto.ContainerType.OVERVIEW_VALUE:
- return LAUNCHER_STATE_OVERVIEW;
- case LauncherLogProto.ContainerType.WORKSPACE_VALUE:
- return LAUNCHER_STATE_HOME;
- case LauncherLogProto.ContainerType.APP_VALUE:
- return LAUNCHER_STATE_BACKGROUND;
- }
- return LAUNCHER_STATE_UNSPECIFIED;
- }
-
- /**
- * Returns event enum based on the two {@link ContainerType} transition information when swipe
+ * Returns event enum based on the two state transition information when swipe
* gesture happens(to be removed during UserEventDispatcher cleanup).
*/
- public static EventEnum getLauncherAtomEvent(int startContainerType,
- int targetContainerType, EventEnum fallbackEvent) {
- if (startContainerType == LauncherLogProto.ContainerType.WORKSPACE.getNumber()
- && targetContainerType == LauncherLogProto.ContainerType.WORKSPACE.getNumber()) {
+ public static EventEnum getLauncherAtomEvent(int startState,
+ int targetState, EventEnum fallbackEvent) {
+ if (startState == LAUNCHER_STATE_HOME
+ && targetState == LAUNCHER_STATE_HOME) {
return LAUNCHER_HOME_GESTURE;
- } else if (startContainerType != LauncherLogProto.ContainerType.TASKSWITCHER.getNumber()
- && targetContainerType == LauncherLogProto.ContainerType.TASKSWITCHER.getNumber()) {
+ } else if (startState != LAUNCHER_STATE_OVERVIEW
+ && targetState == LAUNCHER_STATE_OVERVIEW) {
return LAUNCHER_OVERVIEW_GESTURE;
- } else if (startContainerType != LauncherLogProto.ContainerType.ALLAPPS.getNumber()
- && targetContainerType == LauncherLogProto.ContainerType.ALLAPPS.getNumber()) {
+ } else if (startState != LAUNCHER_STATE_ALLAPPS
+ && targetState == LAUNCHER_STATE_ALLAPPS) {
return LAUNCHER_ALLAPPS_OPEN_UP;
- } else if (startContainerType == LauncherLogProto.ContainerType.ALLAPPS.getNumber()
- && targetContainerType != LauncherLogProto.ContainerType.ALLAPPS.getNumber()) {
+ } else if (startState == LAUNCHER_STATE_ALLAPPS
+ && targetState != LAUNCHER_STATE_ALLAPPS) {
return LAUNCHER_ALLAPPS_CLOSE_DOWN;
}
return fallbackEvent; // TODO fix
@@ -322,7 +303,38 @@
LAUNCHER_FOLDER_CONVERTED_TO_ICON(628),
@UiEvent(doc = "A hotseat prediction item was pinned")
- LAUNCHER_HOTSEAT_PREDICTION_PINNED(629);
+ LAUNCHER_HOTSEAT_PREDICTION_PINNED(629),
+
+ @UiEvent(doc = "Activity to add external item was started")
+ LAUNCHER_ADD_EXTERNAL_ITEM_START(641),
+
+ @UiEvent(doc = "Activity to add external item was cancelled")
+ LAUNCHER_ADD_EXTERNAL_ITEM_CANCELLED(642),
+
+ @UiEvent(doc = "Activity to add external item was backed out")
+ LAUNCHER_ADD_EXTERNAL_ITEM_BACK(643),
+
+ @UiEvent(doc = "Item was placed automatically in external item addition flow")
+ LAUNCHER_ADD_EXTERNAL_ITEM_PLACED_AUTOMATICALLY(644),
+
+ @UiEvent(doc = "Item was dragged in external item addition flow")
+ LAUNCHER_ADD_EXTERNAL_ITEM_DRAGGED(645),
+
+ @UiEvent(doc = "Undo event was tapped.")
+ LAUNCHER_UNDO(648),
+
+ @UiEvent(doc = "Task switcher clear all target was tapped.")
+ LAUNCHER_TASK_CLEAR_ALL(649),
+
+ @UiEvent(doc = "Task preview was long pressed.")
+ LAUNCHER_TASK_PREVIEW_LONGPRESS(650),
+
+ @UiEvent(doc = "User swiped down on workspace (triggering noti shade to open).")
+ LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN(651),
+
+ @UiEvent(doc = "Notification dismissed by swiping right.")
+ LAUNCHER_NOTIFICATION_DISMISSED(652),
+ ;
// ADD MORE
diff --git a/src/com/android/launcher3/logging/StatsLogUtils.java b/src/com/android/launcher3/logging/StatsLogUtils.java
deleted file mode 100644
index a5cc7ea..0000000
--- a/src/com/android/launcher3/logging/StatsLogUtils.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.android.launcher3.logging;
-
-import android.view.View;
-import android.view.ViewParent;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-
-import java.util.ArrayList;
-
-public class StatsLogUtils {
- private final static int MAXIMUM_VIEW_HIERARCHY_LEVEL = 5;
-
- /**
- * Implemented by containers to provide a container source for a given child.
- */
- public interface LogContainerProvider {
-
- /**
- * Populates parent container targets for an item
- */
- void fillInLogContainerData(ItemInfo childInfo, Target child, ArrayList<Target> parents);
- }
-
- /**
- * Recursively finds the parent of the given child which implements IconLogInfoProvider
- */
- public static LogContainerProvider getLaunchProviderRecursive(@Nullable View v) {
- ViewParent parent;
- if (v != null) {
- parent = v.getParent();
- } else {
- return null;
- }
-
- // Optimization to only check up to 5 parents.
- int count = MAXIMUM_VIEW_HIERARCHY_LEVEL;
- while (parent != null && count-- > 0) {
- if (parent instanceof LogContainerProvider) {
- return (LogContainerProvider) parent;
- } else {
- parent = parent.getParent();
- }
- }
- return null;
- }
-}
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
deleted file mode 100644
index a40cc26..0000000
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.logging;
-
-import static com.android.launcher3.logging.LoggerUtils.newAction;
-import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.logging.LoggerUtils.newDropTarget;
-import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
-import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
-import static com.android.launcher3.logging.LoggerUtils.newTarget;
-import static com.android.launcher3.logging.LoggerUtils.newTouchAction;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.TipType;
-
-import static java.util.Optional.ofNullable;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.DropTarget;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.StatsLogUtils.LogContainerProvider;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.LauncherLogProto;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.util.InstantAppResolver;
-import com.android.launcher3.util.LogConfig;
-import com.android.launcher3.util.ResourceBasedOverride;
-
-import com.google.protobuf.InvalidProtocolBufferException;
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-import com.google.protobuf.nano.MessageNano;
-
-import java.util.ArrayList;
-import java.util.UUID;
-
-/**
- * Manages the creation of {@link LauncherEvent}.
- * To debug this class, execute following command before side loading a new apk.
- * <p>
- * $ adb shell setprop log.tag.UserEvent VERBOSE
- */
-public class UserEventDispatcher implements ResourceBasedOverride {
-
- private static final String TAG = "UserEvent";
- private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.USEREVENT);
- private static final String UUID_STORAGE = "uuid";
-
- /**
- * A factory method for UserEventDispatcher
- */
- public static UserEventDispatcher newInstance(Context context) {
- SharedPreferences sharedPrefs = Utilities.getDevicePrefs(context);
- String uuidStr = sharedPrefs.getString(UUID_STORAGE, null);
- if (uuidStr == null) {
- uuidStr = UUID.randomUUID().toString();
- sharedPrefs.edit().putString(UUID_STORAGE, uuidStr).apply();
- }
- UserEventDispatcher ued = Overrides.getObject(UserEventDispatcher.class,
- context.getApplicationContext(), R.string.user_event_dispatcher_class);
- ued.mUuidStr = uuidStr;
- ued.mInstantAppResolver = InstantAppResolver.newInstance(context);
- return ued;
- }
-
-
- /**
- * Fills in the container data on the given event if the given view is not null.
- *
- * @return whether container data was added.
- */
- private boolean fillLogContainer(@Nullable View v, Target child,
- @Nullable ArrayList<Target> targets) {
- LogContainerProvider firstParent = StatsLogUtils.getLaunchProviderRecursive(v);
- if (v == null || !(v.getTag() instanceof ItemInfo) || firstParent == null) {
- return false;
- }
- final ItemInfo itemInfo = (ItemInfo) v.getTag();
- firstParent.fillInLogContainerData(itemInfo, child, targets);
- return true;
- }
-
- protected void onFillInLogContainerData(@NonNull ItemInfo itemInfo, @NonNull Target target,
- @NonNull ArrayList<Target> targets) {
- }
-
- private boolean mSessionStarted;
- private long mElapsedContainerMillis;
- private long mElapsedSessionMillis;
- private long mActionDurationMillis;
- private String mUuidStr;
- protected InstantAppResolver mInstantAppResolver;
- private boolean mAppOrTaskLaunch;
- private boolean mPreviousHomeGesture;
-
- private void fillComponentInfo(Target target, ComponentName cn) {
- if (cn != null) {
- target.packageNameHash = (mUuidStr + cn.getPackageName()).hashCode();
- target.componentHash = (mUuidStr + cn.flattenToString()).hashCode();
- }
- }
-
- public void logActionCommand(int command, int srcContainerType, int dstContainerType) {
- logActionCommand(command, newContainerTarget(srcContainerType),
- dstContainerType >= 0 ? newContainerTarget(dstContainerType) : null);
- }
-
- public void logActionCommand(int command, int srcContainerType, int dstContainerType,
- int pageIndex) {
- Target srcTarget = newContainerTarget(srcContainerType);
- srcTarget.pageIndex = pageIndex;
- logActionCommand(command, srcTarget,
- dstContainerType >= 0 ? newContainerTarget(dstContainerType) : null);
- }
-
- public void logActionCommand(int command, Target srcTarget, Target dstTarget) {
- LauncherEvent event = newLauncherEvent(newCommandAction(command), srcTarget);
- if (command == Action.Command.STOP) {
- if (mAppOrTaskLaunch || !mSessionStarted) {
- mSessionStarted = false;
- return;
- }
- }
-
- if (dstTarget != null) {
- event.destTarget = new Target[1];
- event.destTarget[0] = dstTarget;
- event.action.isStateChange = true;
- }
- dispatchUserEvent(event, null);
- }
-
- public void logActionOnControl(int action, int controlType) {
- logActionOnControl(action, controlType, null);
- }
-
- public void logActionOnControl(int action, int controlType, int parentContainerType) {
- logActionOnControl(action, controlType, null, parentContainerType);
- }
-
- /**
- * Logs control action with proper parent hierarchy
- */
- public void logActionOnControl(int actionType, int controlType,
- @Nullable View controlInContainer, int... parentTypes) {
- Target control = newTarget(Target.Type.CONTROL);
- control.controlType = controlType;
- Action action = newAction(actionType);
-
- ArrayList<Target> targets = makeTargetsList(control);
- if (controlInContainer != null) {
- fillLogContainer(controlInContainer, control, targets);
- }
- for (int parentContainerType : parentTypes) {
- if (parentContainerType < 0) continue;
- targets.add(newContainerTarget(parentContainerType));
- }
- LauncherEvent event = newLauncherEvent(action, targets);
- if (actionType == Action.Touch.DRAGDROP) {
- event.actionDurationMillis = SystemClock.uptimeMillis() - mActionDurationMillis;
- }
- dispatchUserEvent(event, null);
- }
-
- public void logActionTapOutside(Target target) {
- LauncherEvent event = newLauncherEvent(newTouchAction(Action.Type.TOUCH),
- target);
- event.action.isOutside = true;
- dispatchUserEvent(event, null);
- }
-
- public void logActionBounceTip(int containerType) {
- LauncherEvent event = newLauncherEvent(newAction(Action.Type.TIP),
- newContainerTarget(containerType));
- event.srcTarget[0].tipType = TipType.BOUNCE;
- dispatchUserEvent(event, null);
- }
-
- public void logActionOnContainer(int action, int dir, int containerType) {
- logActionOnContainer(action, dir, containerType, 0);
- }
-
- public void logActionOnContainer(int action, int dir, int containerType, int pageIndex) {
- LauncherEvent event = newLauncherEvent(newTouchAction(action),
- newContainerTarget(containerType));
- event.action.dir = dir;
- event.srcTarget[0].pageIndex = pageIndex;
- dispatchUserEvent(event, null);
- }
-
- /**
- * Used primarily for swipe up and down when state changes when swipe up happens from the
- * navbar bezel, the {@param srcChildContainerType} is NAVBAR and
- * {@param srcParentContainerType} is either one of the two
- * (1) WORKSPACE: if the launcher is the foreground activity
- * (2) APP: if another app was the foreground activity
- */
- public void logStateChangeAction(int action, int dir, int downX, int downY,
- int srcChildTargetType, int srcParentContainerType, int dstContainerType,
- int pageIndex) {
- LauncherEvent event;
- if (srcChildTargetType == ItemType.TASK) {
- event = newLauncherEvent(newTouchAction(action),
- newItemTarget(srcChildTargetType),
- newContainerTarget(srcParentContainerType));
- } else {
- event = newLauncherEvent(newTouchAction(action),
- newContainerTarget(srcChildTargetType),
- newContainerTarget(srcParentContainerType));
- }
- event.destTarget = new Target[1];
- event.destTarget[0] = newContainerTarget(dstContainerType);
- event.action.dir = dir;
- event.action.isStateChange = true;
- event.srcTarget[0].pageIndex = pageIndex;
- event.srcTarget[0].spanX = downX;
- event.srcTarget[0].spanY = downY;
- dispatchUserEvent(event, null);
- }
-
- public void logActionOnItem(int action, int dir, int itemType) {
- logActionOnItem(action, dir, itemType, null, null);
- }
-
- /**
- * Creates new {@link LauncherEvent} of ITEM target type with input arguments and dispatches it.
- *
- * @param touchAction ENUM value of {@link LauncherLogProto.Action.Touch} Action
- * @param dir ENUM value of {@link LauncherLogProto.Action.Direction} Action
- * @param itemType ENUM value of {@link LauncherLogProto.ItemType}
- * @param gridX Nullable X coordinate of item's position on the workspace grid
- * @param gridY Nullable Y coordinate of item's position on the workspace grid
- */
- public void logActionOnItem(int touchAction, int dir, int itemType,
- @Nullable Integer gridX, @Nullable Integer gridY) {
- Target itemTarget = newTarget(Target.Type.ITEM);
- itemTarget.itemType = itemType;
- ofNullable(gridX).ifPresent(value -> itemTarget.gridX = value);
- ofNullable(gridY).ifPresent(value -> itemTarget.gridY = value);
- LauncherEvent event = newLauncherEvent(newTouchAction(touchAction), itemTarget);
- event.action.dir = dir;
- 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();
- try {
- dispatchUserEvent(LauncherEvent.parseFrom(launcherEvent.toByteArray()), null);
- } catch (InvalidProtocolBufferNanoException e) {
- throw new RuntimeException("Cannot convert LauncherEvent from Lite to Nano version.");
- }
- }
-
- public void logDeepShortcutsOpen(View icon) {
- ItemInfo info = (ItemInfo) icon.getTag();
- Target child = newItemTarget(info, mInstantAppResolver);
- ArrayList<Target> targets = makeTargetsList(child);
- fillLogContainer(icon, child, targets);
- dispatchUserEvent(newLauncherEvent(newTouchAction(Action.Touch.TAP), targets), null);
- }
-
- public void logDragNDrop(DropTarget.DragObject dragObj, View dropTargetAsView) {
- Target srcChild = newItemTarget(dragObj.originalDragInfo, mInstantAppResolver);
- ArrayList<Target> srcTargets = makeTargetsList(srcChild);
-
-
- Target destChild = newItemTarget(dragObj.originalDragInfo, mInstantAppResolver);
- ArrayList<Target> destTargets = makeTargetsList(destChild);
-
- //dragObj.dragSource.fillInLogContainerData(dragObj.originalDragInfo, srcChild, srcTargets);
- if (dropTargetAsView instanceof LogContainerProvider) {
- ((LogContainerProvider) dropTargetAsView).fillInLogContainerData(dragObj.dragInfo,
- destChild, destTargets);
- }
- else {
- destTargets.add(newDropTarget(dropTargetAsView));
- }
- LauncherEvent event = newLauncherEvent(newTouchAction(Action.Touch.DRAGDROP), srcTargets);
- Target[] destTargetsArray = new Target[destTargets.size()];
- destTargets.toArray(destTargetsArray);
- event.destTarget = destTargetsArray;
-
- event.actionDurationMillis = SystemClock.uptimeMillis() - mActionDurationMillis;
- dispatchUserEvent(event, null);
- }
-
- public final void startSession() {
- mSessionStarted = true;
- mElapsedSessionMillis = SystemClock.uptimeMillis();
- mElapsedContainerMillis = SystemClock.uptimeMillis();
- }
-
- public final void setPreviousHomeGesture(boolean homeGesture) {
- mPreviousHomeGesture = homeGesture;
- }
-
- public final boolean isPreviousHomeGesture() {
- return mPreviousHomeGesture;
- }
-
- public final void resetActionDurationMillis() {
- mActionDurationMillis = SystemClock.uptimeMillis();
- }
-
- public void dispatchUserEvent(LauncherEvent ev, Intent intent) {
- if (mPreviousHomeGesture) {
- mPreviousHomeGesture = false;
- }
- mAppOrTaskLaunch = false;
- ev.elapsedContainerMillis = SystemClock.uptimeMillis() - mElapsedContainerMillis;
- ev.elapsedSessionMillis = SystemClock.uptimeMillis() - mElapsedSessionMillis;
- if (!IS_VERBOSE) {
- return;
- }
- LauncherLogProto.LauncherEvent liteLauncherEvent;
- try {
- liteLauncherEvent =
- LauncherLogProto.LauncherEvent.parseFrom(MessageNano.toByteArray(ev));
- } catch (InvalidProtocolBufferException e) {
- throw new RuntimeException("Cannot parse LauncherEvent from Nano to Lite version");
- }
- Log.d(TAG, liteLauncherEvent.toString());
- }
-
- /**
- * Constructs an ArrayList with targets
- */
- public static ArrayList<Target> makeTargetsList(Target... targets) {
- ArrayList<Target> result = new ArrayList<>();
- for (Target target : targets) {
- result.add(target);
- }
- return result;
- }
-}
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 41ccbd7..06a2c92 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -20,15 +20,9 @@
import static androidx.core.util.Preconditions.checkNotNull;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.logger.LauncherAtom.Attribute.EMPTY_LABEL;
import static com.android.launcher3.logger.LauncherAtom.Attribute.MANUAL_LABEL;
import static com.android.launcher3.logger.LauncherAtom.Attribute.SUGGESTED_LABEL;
-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 android.os.Process;
@@ -43,10 +37,6 @@
import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.model.ModelWriter;
-import com.android.launcher3.userevent.LauncherLogProto;
-import com.android.launcher3.userevent.LauncherLogProto.Target;
-import com.android.launcher3.userevent.LauncherLogProto.Target.FromFolderLabelState;
-import com.android.launcher3.userevent.LauncherLogProto.Target.ToFolderLabelState;
import com.android.launcher3.util.ContentWriter;
import java.util.ArrayList;
@@ -359,113 +349,4 @@
}
return LauncherAtom.ToState.TO_STATE_UNSPECIFIED;
}
-
- /**
- * Returns {@link LauncherLogProto.LauncherEvent} to log current folder label info.
- *
- * @deprecated This method is used only for validation purpose and soon will be removed.
- */
- @Deprecated
- public LauncherLogProto.LauncherEvent getFolderLabelStateLauncherEvent(FromState fromState,
- ToState toState) {
- return LauncherLogProto.LauncherEvent.newBuilder()
- .setAction(LauncherLogProto.Action
- .newBuilder()
- .setType(LauncherLogProto.Action.Type.SOFT_KEYBOARD))
- .addSrcTarget(Target
- .newBuilder()
- .setType(Target.Type.ITEM)
- .setItemType(LauncherLogProto.ItemType.EDITTEXT)
- .setFromFolderLabelState(convertFolderLabelState(fromState))
- .setToFolderLabelState(convertFolderLabelState(toState)))
- .addSrcTarget(Target.newBuilder()
- .setType(Target.Type.CONTAINER)
- .setContainerType(LauncherLogProto.ContainerType.FOLDER)
- .setPageIndex(screenId)
- .setGridX(cellX)
- .setGridY(cellY)
- .setCardinality(contents.size()))
- .addSrcTarget(newParentContainerTarget())
- .build();
- }
-
- /**
- * @deprecated This method is used only for validation purpose and soon will be removed.
- */
- @Deprecated
- private Target.Builder newParentContainerTarget() {
- Target.Builder builder = Target.newBuilder().setType(Target.Type.CONTAINER);
- switch (container) {
- case CONTAINER_HOTSEAT:
- return builder.setContainerType(LauncherLogProto.ContainerType.HOTSEAT);
- case CONTAINER_DESKTOP:
- return builder.setContainerType(LauncherLogProto.ContainerType.WORKSPACE);
- default:
- throw new AssertionError(String
- .format("Expected container to be either %s or %s but found %s.",
- CONTAINER_HOTSEAT,
- CONTAINER_DESKTOP,
- container));
- }
- }
-
- /**
- * @deprecated This method is used only for validation purpose and soon will be removed.
- */
- @Deprecated
- private static FromFolderLabelState convertFolderLabelState(FromState fromState) {
- switch (fromState) {
- case FROM_EMPTY:
- return FROM_EMPTY;
- case FROM_SUGGESTED:
- return FROM_SUGGESTED;
- case FROM_CUSTOM:
- return FROM_CUSTOM;
- default:
- return FROM_FOLDER_LABEL_STATE_UNSPECIFIED;
- }
- }
-
- /**
- * @deprecated This method is used only for validation purpose and soon will be removed.
- */
- @Deprecated
- private static ToFolderLabelState convertFolderLabelState(ToState toState) {
- switch (toState) {
- case UNCHANGED:
- return ToFolderLabelState.UNCHANGED;
- case TO_SUGGESTION0:
- return ToFolderLabelState.TO_SUGGESTION0_WITH_VALID_PRIMARY;
- case TO_SUGGESTION1_WITH_VALID_PRIMARY:
- return ToFolderLabelState.TO_SUGGESTION1_WITH_VALID_PRIMARY;
- case TO_SUGGESTION1_WITH_EMPTY_PRIMARY:
- return ToFolderLabelState.TO_SUGGESTION1_WITH_EMPTY_PRIMARY;
- case TO_SUGGESTION2_WITH_VALID_PRIMARY:
- return ToFolderLabelState.TO_SUGGESTION2_WITH_VALID_PRIMARY;
- case TO_SUGGESTION2_WITH_EMPTY_PRIMARY:
- return ToFolderLabelState.TO_SUGGESTION2_WITH_EMPTY_PRIMARY;
- case TO_SUGGESTION3_WITH_VALID_PRIMARY:
- return ToFolderLabelState.TO_SUGGESTION3_WITH_VALID_PRIMARY;
- case TO_SUGGESTION3_WITH_EMPTY_PRIMARY:
- return ToFolderLabelState.TO_SUGGESTION3_WITH_EMPTY_PRIMARY;
- case TO_EMPTY_WITH_VALID_PRIMARY:
- return ToFolderLabelState.TO_EMPTY_WITH_VALID_PRIMARY;
- case TO_EMPTY_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY:
- return ToFolderLabelState.TO_EMPTY_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY;
- case TO_EMPTY_WITH_EMPTY_SUGGESTIONS:
- return ToFolderLabelState.TO_EMPTY_WITH_EMPTY_SUGGESTIONS;
- case TO_EMPTY_WITH_SUGGESTIONS_DISABLED:
- return ToFolderLabelState.TO_EMPTY_WITH_SUGGESTIONS_DISABLED;
- case TO_CUSTOM_WITH_VALID_PRIMARY:
- return ToFolderLabelState.TO_CUSTOM_WITH_VALID_PRIMARY;
- case TO_CUSTOM_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY:
- return ToFolderLabelState.TO_CUSTOM_WITH_VALID_SUGGESTIONS_AND_EMPTY_PRIMARY;
- case TO_CUSTOM_WITH_EMPTY_SUGGESTIONS:
- return ToFolderLabelState.TO_CUSTOM_WITH_EMPTY_SUGGESTIONS;
- case TO_CUSTOM_WITH_SUGGESTIONS_DISABLED:
- return ToFolderLabelState.TO_CUSTOM_WITH_SUGGESTIONS_DISABLED;
- default:
- return ToFolderLabelState.TO_FOLDER_LABEL_STATE_UNSPECIFIED;
- }
- }
}
diff --git a/src/com/android/launcher3/model/data/RemoteActionItemInfo.java b/src/com/android/launcher3/model/data/RemoteActionItemInfo.java
new file mode 100644
index 0000000..81f7f3a
--- /dev/null
+++ b/src/com/android/launcher3/model/data/RemoteActionItemInfo.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.model.data;
+
+import android.app.RemoteAction;
+import android.os.Process;
+
+/**
+ * Represents a launchable {@link RemoteAction}
+ */
+public class RemoteActionItemInfo extends ItemInfoWithIcon {
+
+ private final RemoteAction mRemoteAction;
+ private final String mToken;
+ private final boolean mShouldStart;
+
+ public RemoteActionItemInfo(RemoteAction remoteAction, String token, boolean shouldStart) {
+ mShouldStart = shouldStart;
+ mToken = token;
+ mRemoteAction = remoteAction;
+ title = remoteAction.getTitle();
+ user = Process.myUserHandle();
+ }
+
+ public RemoteActionItemInfo(RemoteActionItemInfo info) {
+ super(info);
+ this.mShouldStart = info.mShouldStart;
+ this.mRemoteAction = info.mRemoteAction;
+ this.mToken = info.mToken;
+ }
+
+ @Override
+ public ItemInfoWithIcon clone() {
+ return new RemoteActionItemInfo(this);
+ }
+
+ public RemoteAction getRemoteAction() {
+ return mRemoteAction;
+ }
+
+ public String getToken() {
+ return mToken;
+ }
+
+ /**
+ * Getter method for mShouldStart
+ */
+ public boolean shouldStartInLauncher() {
+ return mShouldStart;
+ }
+}
diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java
index 32f060b..9b06523 100644
--- a/src/com/android/launcher3/notification/NotificationMainView.java
+++ b/src/com/android/launcher3/notification/NotificationMainView.java
@@ -17,6 +17,7 @@
package com.android.launcher3.notification;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DISMISSED;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@@ -41,7 +42,6 @@
import com.android.launcher3.touch.BaseSwipeDetector;
import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.Themes;
/**
@@ -168,10 +168,7 @@
Launcher launcher = Launcher.getLauncher(getContext());
launcher.getPopupDataProvider().cancelNotification(
mNotificationInfo.notificationKey);
- launcher.getUserEventDispatcher().logActionOnItem(
- LauncherLogProto.Action.Touch.SWIPE,
- LauncherLogProto.Action.Direction.RIGHT, // Assume all swipes are right for logging.
- LauncherLogProto.ItemType.NOTIFICATION);
+ launcher.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
}
// SingleAxisSwipeDetector.Listener's
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 753a6dd..fa25114 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -17,6 +17,7 @@
package com.android.launcher3.pm;
import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -31,6 +32,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
+import androidx.annotation.WorkerThread;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.SessionCommitReceiver;
@@ -39,10 +41,10 @@
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
import java.util.ArrayList;
import java.util.HashMap;
@@ -65,27 +67,27 @@
private final LauncherApps mLauncherApps;
private final Context mAppContext;
- private final IntSet mPromiseIconIds;
private final PackageInstaller mInstaller;
private final HashMap<String, Boolean> mSessionVerifiedMap = new HashMap<>();
+ private IntSet mPromiseIconIds;
+
public InstallSessionHelper(Context context) {
mInstaller = context.getPackageManager().getPackageInstaller();
mAppContext = context.getApplicationContext();
mLauncherApps = context.getSystemService(LauncherApps.class);
+ }
+ @WorkerThread
+ private IntSet getPromiseIconIds() {
+ Preconditions.assertWorkerThread();
+ if (mPromiseIconIds != null) {
+ return mPromiseIconIds;
+ }
mPromiseIconIds = IntSet.wrap(IntArray.fromConcatString(
- getPrefs(context).getString(PROMISE_ICON_IDS, "")));
+ getPrefs(mAppContext).getString(PROMISE_ICON_IDS, "")));
- cleanUpPromiseIconIds();
- }
-
- public static UserHandle getUserHandle(SessionInfo info) {
- return Utilities.ATLEAST_Q ? info.getUser() : Process.myUserHandle();
- }
-
- protected void cleanUpPromiseIconIds() {
IntArray existingIds = new IntArray();
for (SessionInfo info : getActiveSessions().values()) {
existingIds.add(info.getSessionId());
@@ -100,6 +102,7 @@
for (int i = idsToRemove.size() - 1; i >= 0; --i) {
mPromiseIconIds.getArray().removeValue(idsToRemove.get(i));
}
+ return mPromiseIconIds;
}
public HashMap<PackageUserKey, SessionInfo> getActiveSessions() {
@@ -126,7 +129,7 @@
private void updatePromiseIconPrefs() {
getPrefs(mAppContext).edit()
- .putString(PROMISE_ICON_IDS, mPromiseIconIds.getArray().toConcatString())
+ .putString(PROMISE_ICON_IDS, getPromiseIconIds().getArray().toConcatString())
.apply();
}
@@ -184,13 +187,15 @@
return info.getInstallReason() == PackageManager.INSTALL_REASON_DEVICE_RESTORE;
}
+ @WorkerThread
public boolean promiseIconAddedForId(int sessionId) {
- return mPromiseIconIds.contains(sessionId);
+ return getPromiseIconIds().contains(sessionId);
}
+ @WorkerThread
public void removePromiseIconId(int sessionId) {
- if (mPromiseIconIds.contains(sessionId)) {
- mPromiseIconIds.getArray().removeValue(sessionId);
+ if (promiseIconAddedForId(sessionId)) {
+ getPromiseIconIds().getArray().removeValue(sessionId);
updatePromiseIconPrefs();
}
}
@@ -203,6 +208,7 @@
* - The app is not already installed
* - A promise icon for the session has not already been created
*/
+ @WorkerThread
void tryQueuePromiseAppIcon(PackageInstaller.SessionInfo sessionInfo) {
if (FeatureFlags.PROMISE_APPS_NEW_INSTALLS.get()
&& SessionCommitReceiver.isEnabled(mAppContext)
@@ -210,25 +216,24 @@
&& sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER
&& sessionInfo.getAppIcon() != null
&& !TextUtils.isEmpty(sessionInfo.getAppLabel())
- && !mPromiseIconIds.contains(sessionInfo.getSessionId())
+ && !promiseIconAddedForId(sessionInfo.getSessionId())
&& new PackageManagerHelper(mAppContext).getApplicationInfo(
sessionInfo.getAppPackageName(), getUserHandle(sessionInfo), 0) == null) {
ItemInstallQueue.INSTANCE.get(mAppContext)
.queueItem(sessionInfo.getAppPackageName(), getUserHandle(sessionInfo));
- mPromiseIconIds.add(sessionInfo.getSessionId());
+ getPromiseIconIds().add(sessionInfo.getSessionId());
updatePromiseIconPrefs();
}
}
- public InstallSessionTracker registerInstallTracker(
- InstallSessionTracker.Callback callback, LooperExecutor executor) {
+ public InstallSessionTracker registerInstallTracker(InstallSessionTracker.Callback callback) {
InstallSessionTracker tracker = new InstallSessionTracker(this, callback);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- mInstaller.registerSessionCallback(tracker, executor.getHandler());
+ mInstaller.registerSessionCallback(tracker, MODEL_EXECUTOR.getHandler());
} else {
- mLauncherApps.registerPackageInstallerSessionCallback(executor, tracker);
+ mLauncherApps.registerPackageInstallerSessionCallback(MODEL_EXECUTOR, tracker);
}
return tracker;
}
@@ -240,4 +245,8 @@
mLauncherApps.unregisterPackageInstallerSessionCallback(tracker);
}
}
+
+ public static UserHandle getUserHandle(SessionInfo info) {
+ return Utilities.ATLEAST_Q ? info.getUser() : Process.myUserHandle();
+ }
}
diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java
index eb3ca73..b0b907a 100644
--- a/src/com/android/launcher3/pm/InstallSessionTracker.java
+++ b/src/com/android/launcher3/pm/InstallSessionTracker.java
@@ -24,8 +24,11 @@
import android.os.UserHandle;
import android.util.SparseArray;
+import androidx.annotation.WorkerThread;
+
import com.android.launcher3.util.PackageUserKey;
+@WorkerThread
public class InstallSessionTracker extends PackageInstaller.SessionCallback {
// Lazily initialized
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index 2d7d6b0..5ade22b 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -60,6 +60,9 @@
private void onUsersChanged(Intent intent) {
enableAndResetCache();
mUserChangeListeners.forEach(Runnable::run);
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "profile changed", new Exception());
+ }
}
/**
@@ -104,9 +107,6 @@
mUsers = null;
mUserToSerialMap = null;
}
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.WORK_PROFILE_REMOVED, "Work profile removed", new Exception());
- }
}
}
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index d5b32fc..90285c4 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -151,32 +151,52 @@
* @param viewsToFlip number of views from the top to to flip in case of reverse order
*/
protected void reorderAndShow(int viewsToFlip) {
+ setupForDisplay();
+ boolean reverseOrder = mIsAboveIcon;
+ if (reverseOrder) {
+ reverseOrder(viewsToFlip);
+ }
+ onInflationComplete(reverseOrder);
+ addArrow();
+ animateOpen();
+ }
+
+ /**
+ * Shows the popup at the desired location.
+ */
+ protected void show() {
+ setupForDisplay();
+ onInflationComplete(false);
+ addArrow();
+ animateOpen();
+ }
+
+ private void setupForDisplay() {
setVisibility(View.INVISIBLE);
mIsOpen = true;
getPopupContainer().addView(this);
orientAboutObject();
+ }
- boolean reverseOrder = mIsAboveIcon;
- if (reverseOrder) {
- int count = getChildCount();
- ArrayList<View> allViews = new ArrayList<>(count);
- for (int i = 0; i < count; i++) {
- if (i == viewsToFlip) {
- Collections.reverse(allViews);
- }
- allViews.add(getChildAt(i));
+ private void reverseOrder(int viewsToFlip) {
+ int count = getChildCount();
+ ArrayList<View> allViews = new ArrayList<>(count);
+ for (int i = 0; i < count; i++) {
+ if (i == viewsToFlip) {
+ Collections.reverse(allViews);
}
- Collections.reverse(allViews);
- removeAllViews();
- for (int i = 0; i < count; i++) {
- addView(allViews.get(i));
- }
-
- orientAboutObject();
+ allViews.add(getChildAt(i));
}
- onInflationComplete(reverseOrder);
+ Collections.reverse(allViews);
+ removeAllViews();
+ for (int i = 0; i < count; i++) {
+ addView(allViews.get(i));
+ }
- // Add the arrow.
+ orientAboutObject();
+ }
+
+ private void addArrow() {
final Resources res = getResources();
final int arrowCenterOffset = res.getDimensionPixelSize(isAlignedWithStart()
? R.dimen.popup_arrow_horizontal_center_start
@@ -214,8 +234,6 @@
mArrow.setPivotX(arrowLp.width / 2);
mArrow.setPivotY(mIsAboveIcon ? arrowLp.height : 0);
-
- animateOpen();
}
protected boolean isAlignedWithStart() {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 26b32b8..6d92b8b 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -19,10 +19,8 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS_IF_NOTIFICATIONS;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.animation.AnimatorSet;
@@ -160,8 +158,7 @@
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
BaseDragLayer dl = getPopupContainer();
if (!dl.isEventOverView(this, ev)) {
- mLauncher.getUserEventDispatcher().logActionTapOutside(
- newContainerTarget(ContainerType.DEEPSHORTCUTS));
+ // TODO: add WW log if want to log if tap closed deep shortcut container.
close(true);
// We let touches on the original icon go through so that users can launch
@@ -435,7 +432,9 @@
// Make sure we keep the original icon hidden while it is being dragged.
mOriginalIcon.setVisibility(INVISIBLE);
} else {
- mLauncher.getUserEventDispatcher().logDeepShortcutsOpen(mOriginalIcon);
+ // TODO: add WW logging if want to add logging for long press on popup
+ // container.
+ // mLauncher.getUserEventDispatcher().logDeepShortcutsOpen(mOriginalIcon);
if (!mIsAboveIcon) {
// Show the icon but keep the text hidden.
mOriginalIcon.setVisibility(VISIBLE);
diff --git a/src/com/android/launcher3/popup/RemoteActionShortcut.java b/src/com/android/launcher3/popup/RemoteActionShortcut.java
index 61829c0..7c393ad 100644
--- a/src/com/android/launcher3/popup/RemoteActionShortcut.java
+++ b/src/com/android/launcher3/popup/RemoteActionShortcut.java
@@ -37,7 +37,6 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
@TargetApi(Build.VERSION_CODES.Q)
public class RemoteActionShortcut extends SystemShortcut<BaseDraggingActivity> {
@@ -107,9 +106,6 @@
Toast.LENGTH_SHORT)
.show();
}
-
- mTarget.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP,
- LauncherLogProto.ControlType.REMOTE_ACTION_SHORTCUT, view);
}
@Override
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 81302ac..577fe4a 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -21,8 +21,6 @@
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
@@ -117,8 +115,6 @@
(WidgetsBottomSheet) mTarget.getLayoutInflater().inflate(
R.layout.widgets_bottom_sheet, mTarget.getDragLayer(), false);
widgetsBottomSheet.populateAndShow(mItemInfo);
- mTarget.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
- ControlType.WIDGETS_BUTTON, view);
mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo)
.log(LAUNCHER_SYSTEM_SHORTCUT_WIDGETS_TAP);
}
@@ -139,8 +135,6 @@
Rect sourceBounds = mTarget.getViewBounds(view);
new PackageManagerHelper(mTarget).startDetailsActivityForInfo(
mItemInfo, sourceBounds, ActivityOptions.makeBasic().toBundle());
- mTarget.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
- ControlType.APPINFO_TARGET, view);
mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo)
.log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP);
}
diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
index 4baecb7..f4b059d 100644
--- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
@@ -306,6 +306,15 @@
return true;
});
sandboxCategory.addPreference(launchAssistantTutorialPreference);
+ Preference launchSandboxModeTutorialPreference = new Preference(context);
+ launchSandboxModeTutorialPreference.setKey("launchSandboxMode");
+ launchSandboxModeTutorialPreference.setTitle("Launch Sandbox Mode");
+ launchSandboxModeTutorialPreference.setSummary("Practice navigation gestures");
+ launchSandboxModeTutorialPreference.setOnPreferenceClickListener(preference -> {
+ startActivity(launchSandboxIntent.putExtra("tutorial_type", "SANDBOX_MODE"));
+ return true;
+ });
+ sandboxCategory.addPreference(launchSandboxModeTutorialPreference);
}
private String toName(String action) {
diff --git a/src/com/android/launcher3/states/HintState.java b/src/com/android/launcher3/states/HintState.java
index b8a184f..fd1d965 100644
--- a/src/com/android/launcher3/states/HintState.java
+++ b/src/com/android/launcher3/states/HintState.java
@@ -15,11 +15,12 @@
*/
package com.android.launcher3.states;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
+
import android.content.Context;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
* Scale down workspace/hotseat to hint at going to either overview (on pause) or first home screen.
@@ -30,7 +31,7 @@
| FLAG_HAS_SYS_UI_SCRIM;
public HintState(int id) {
- super(id, ContainerType.DEFAULT_CONTAINERTYPE, STATE_FLAGS);
+ super(id, LAUNCHER_STATE_HOME, STATE_FLAGS);
}
@Override
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index 2a4f887..45172b5 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.states;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
+
import android.content.Context;
import android.graphics.Rect;
@@ -22,7 +24,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
* Definition for spring loaded state used during drag and drop.
@@ -35,7 +36,7 @@
| FLAG_HIDE_BACK_BUTTON;
public SpringLoadedState(int id) {
- super(id, ContainerType.WORKSPACE, STATE_FLAGS);
+ super(id, LAUNCHER_STATE_HOME, STATE_FLAGS);
}
@Override
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 8ee5a6e..9fd53e2 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -21,6 +21,9 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_COMPONENTS;
@@ -52,9 +55,6 @@
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
import com.android.launcher3.testing.TestProtocol;
-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.util.FlingBlockCheck;
import com.android.launcher3.util.TouchController;
@@ -190,11 +190,6 @@
protected abstract float initCurrentAnimation(@AnimationFlags int animComponents);
- /**
- * Returns the container that the touch started from when leaving NORMAL state.
- */
- protected abstract int getLogContainerTypeForNormalState(MotionEvent ev);
-
private boolean reinitCurrentAnimation(boolean reachedToState, boolean isDragTowardPositive) {
LauncherState newFromState = mFromState == null ? mLauncher.getStateManager().getState()
: reachedToState ? mToState : mFromState;
@@ -307,11 +302,11 @@
public boolean onDrag(float displacement, MotionEvent ev) {
if (!mIsLogContainerSet) {
if (mStartState == ALL_APPS) {
- mStartContainerType = ContainerType.ALLAPPS;
+ mStartContainerType = LAUNCHER_STATE_ALLAPPS;
} else if (mStartState == NORMAL) {
- mStartContainerType = getLogContainerTypeForNormalState(ev);
+ mStartContainerType = LAUNCHER_STATE_HOME;
} else if (mStartState == OVERVIEW) {
- mStartContainerType = ContainerType.TASKSWITCHER;
+ mStartContainerType = LAUNCHER_STATE_OVERVIEW;
}
mIsLogContainerSet = true;
}
@@ -401,7 +396,6 @@
@Override
public void onDragEnd(float velocity) {
boolean fling = mDetector.isFling(velocity);
- final int logAction = fling ? Touch.FLING : Touch.SWIPE;
boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
if (blockedFling) {
@@ -458,7 +452,7 @@
}
}
- mCurrentAnimation.setEndAction(() -> onSwipeInteractionCompleted(targetState, logAction));
+ mCurrentAnimation.setEndAction(() -> onSwipeInteractionCompleted(targetState));
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
anim.setFloatValues(startProgress, endProgress);
maybeUpdateAtomicAnim(mFromState, targetState, targetState == mToState ? 1f : 0f);
@@ -522,11 +516,7 @@
.setInterpolator(scrollInterpolatorForVelocity(velocity));
}
- protected int getDirectionForLog() {
- return mToState.ordinal > mFromState.ordinal ? Direction.UP : Direction.DOWN;
- }
-
- protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
+ protected void onSwipeInteractionCompleted(LauncherState targetState) {
if (mAtomicComponentsController != null) {
mAtomicComponentsController.getAnimationPlayer().end();
mAtomicComponentsController = null;
@@ -535,18 +525,18 @@
boolean shouldGoToTargetState = true;
if (mPendingAnimation != null) {
boolean reachedTarget = mToState == targetState;
- mPendingAnimation.finish(reachedTarget, logAction);
+ mPendingAnimation.finish(reachedTarget);
mPendingAnimation = null;
shouldGoToTargetState = !reachedTarget;
}
if (shouldGoToTargetState) {
- goToTargetState(targetState, logAction);
+ goToTargetState(targetState);
}
}
- protected void goToTargetState(LauncherState targetState, int logAction) {
+ protected void goToTargetState(LauncherState targetState) {
if (targetState != mStartState) {
- logReachedState(logAction, targetState);
+ logReachedState(targetState);
}
if (!mLauncher.isInState(targetState)) {
// If we're already in the target state, don't jump to it at the end of the animation in
@@ -556,24 +546,18 @@
mLauncher.getDragLayer().getScrim().createSysuiMultiplierAnim(1f).setDuration(0).start();
}
- private void logReachedState(int logAction, LauncherState targetState) {
+ private void logReachedState(LauncherState targetState) {
// Transition complete. log the action
- mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
- getDirectionForLog(), mDetector.getDownX(), mDetector.getDownY(),
- mStartContainerType /* e.g., hotseat */,
- mStartState.containerType /* e.g., workspace */,
- targetState.containerType,
- mLauncher.getWorkspace().getCurrentPage());
mLauncher.getStatsLogManager().logger()
- .withSrcState(StatsLogManager.containerTypeToAtomState(mStartState.containerType))
- .withDstState(StatsLogManager.containerTypeToAtomState(targetState.containerType))
+ .withSrcState(mStartState.statsLogOrdinal)
+ .withDstState(targetState.statsLogOrdinal)
.withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
.setWorkspace(
LauncherAtom.WorkspaceContainer.newBuilder()
.setPageIndex(mLauncher.getWorkspace().getCurrentPage()))
.build())
- .log(StatsLogManager.getLauncherAtomEvent(mStartState.containerType,
- targetState.containerType, mToState.ordinal > mFromState.ordinal
+ .log(StatsLogManager.getLauncherAtomEvent(mStartState.statsLogOrdinal,
+ targetState.statsLogOrdinal, mToState.ordinal > mFromState.ordinal
? LAUNCHER_UNKNOWN_SWIPEUP
: LAUNCHER_UNKNOWN_SWIPEDOWN));
}
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 4a202b6..f9dcf2d 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -24,7 +24,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
* TouchController to switch between NORMAL and ALL_APPS state.
@@ -70,12 +69,6 @@
}
@Override
- protected int getLogContainerTypeForNormalState(MotionEvent ev) {
- return mLauncher.getDragLayer().isEventOverView(mLauncher.getHotseat(), mTouchDownEvent)
- ? ContainerType.HOTSEAT : ContainerType.WORKSPACE;
- }
-
- @Override
protected float initCurrentAnimation(@AnimationFlags int animComponents) {
float range = getShiftRange();
long maxAccuracy = (long) (2 * range);
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 61d6f7d..d56391d 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -25,7 +25,9 @@
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
import android.app.AlertDialog;
+import android.app.PendingIntent;
import android.content.Intent;
+import android.content.IntentSender;
import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller.SessionInfo;
import android.os.Process;
@@ -49,6 +51,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.PromiseAppInfo;
+import com.android.launcher3.model.data.RemoteActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.testing.TestLogging;
@@ -236,6 +239,27 @@
startAppShortcutOrInfoActivity(v, shortcut, launcher);
}
+ /**
+ * Event handler for a {@link android.app.RemoteAction} click
+ *
+ */
+ public static void onClickRemoteAction(Launcher launcher,
+ RemoteActionItemInfo remoteActionInfo) {
+ try {
+ PendingIntent pendingIntent = remoteActionInfo.getRemoteAction().getActionIntent();
+ if (remoteActionInfo.shouldStartInLauncher()) {
+ launcher.startIntentSenderForResult(pendingIntent.getIntentSender(), 0, null, 0, 0,
+ 0);
+ } else {
+ pendingIntent.send();
+ }
+ } catch (PendingIntent.CanceledException | IntentSender.SendIntentException e) {
+ Toast.makeText(launcher,
+ launcher.getResources().getText(R.string.shortcut_not_available),
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN, "start: startAppShortcutOrInfoActivity");
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index fb02f79..17f02be 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -72,7 +72,6 @@
out.halfPageSize = view.getNormalChildHeight() / 2;
out.halfScreenSize = view.getMeasuredHeight() / 2;
out.screenCenter = insets.top + view.getPaddingTop() + out.scroll + out.halfPageSize;
- out.pageParentScale = view.getScaleY();
}
@Override
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index 354d78d..114b75a 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -112,7 +112,6 @@
public int halfPageSize;
public int screenCenter;
public int halfScreenSize;
- public float pageParentScale;
}
class ChildBounds {
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 06479e6..5f5b2d1 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -70,7 +70,6 @@
out.halfPageSize = view.getNormalChildWidth() / 2;
out.halfScreenSize = view.getMeasuredWidth() / 2;
out.screenCenter = insets.left + view.getPaddingLeft() + out.scroll + out.halfPageSize;
- out.pageParentScale = view.getScaleX();
}
@Override
diff --git a/src/com/android/launcher3/util/Executors.java b/src/com/android/launcher3/util/Executors.java
index 0a32734..a85ae45 100644
--- a/src/com/android/launcher3/util/Executors.java
+++ b/src/com/android/launcher3/util/Executors.java
@@ -20,8 +20,10 @@
import android.os.Process;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Various different executors used in Launcher
@@ -83,4 +85,29 @@
*/
public static final LooperExecutor MODEL_EXECUTOR =
new LooperExecutor(createAndStartNewLooper("launcher-loader"));
+
+ /**
+ * A simple ThreadFactory to set the thread name and priority when used with executors.
+ */
+ public static class SimpleThreadFactory implements ThreadFactory {
+
+ private final int mPriority;
+ private final String mNamePrefix;
+
+ private final AtomicInteger mCount = new AtomicInteger(0);
+
+ public SimpleThreadFactory(String namePrefix, int priority) {
+ mNamePrefix = namePrefix;
+ mPriority = priority;
+ }
+
+ @Override
+ public Thread newThread(Runnable runnable) {
+ Thread t = new Thread(() -> {
+ Process.setThreadPriority(mPriority);
+ runnable.run();
+ }, mNamePrefix + mCount.incrementAndGet());
+ return t;
+ }
+ }
}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 52a82f8..d9a14e9 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.views;
-import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA;
import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.Utilities.getFullDrawable;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
@@ -23,9 +22,6 @@
import static com.android.launcher3.views.IconLabelDotView.setIconAndDotVisible;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
@@ -74,7 +70,6 @@
private static @Nullable IconLoadResult sIconLoadResult;
public static final float SHAPE_PROGRESS_DURATION = 0.10f;
- private static final int FADE_DURATION_MS = 200;
private static final RectF sTmpRectF = new RectF();
private static final Object[] sTmpObjArray = new Object[1];
@@ -89,6 +84,9 @@
private IconLoadResult mIconLoadResult;
+ // Draw the drawable of the BubbleTextView behind ClipIconView to reveal the built in shadow.
+ private View mBtvDrawable;
+
private ClipIconView mClipIconView;
private @Nullable Drawable mBadge;
@@ -98,7 +96,6 @@
private final Rect mFinalDrawableBounds = new Rect();
- private AnimatorSet mFadeAnimatorSet;
private ListenerView mListenerView;
private Runnable mFastFinishRunnable;
@@ -116,6 +113,8 @@
mIsRtl = Utilities.isRtl(getResources());
mListenerView = new ListenerView(context, attrs);
mClipIconView = new ClipIconView(context, attrs);
+ mBtvDrawable = new ImageView(context, attrs);
+ addView(mBtvDrawable);
addView(mClipIconView);
setWillNotDraw(false);
}
@@ -176,6 +175,7 @@
setLayoutParams(lp);
mClipIconView.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height));
+ mBtvDrawable.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height));
}
private void updatePosition(RectF pos, InsettableFrameLayout.LayoutParams lp) {
@@ -292,6 +292,8 @@
drawable = drawable == null ? null : drawable.getConstantState().newDrawable();
int iconOffset = getOffsetForIconBounds(l, drawable, pos);
synchronized (iconLoadResult) {
+ iconLoadResult.btvDrawable = btvIcon == null || drawable == btvIcon
+ ? null : btvIcon.getConstantState().newDrawable();
iconLoadResult.drawable = drawable;
iconLoadResult.badge = badge;
iconLoadResult.iconOffset = iconOffset;
@@ -311,7 +313,8 @@
* @param iconOffset The amount of offset needed to match this view with the original view.
*/
@UiThread
- private void setIcon(@Nullable Drawable drawable, @Nullable Drawable badge, int iconOffset) {
+ private void setIcon(@Nullable Drawable drawable, @Nullable Drawable badge,
+ @Nullable Drawable btvIcon, int iconOffset) {
final InsettableFrameLayout.LayoutParams lp =
(InsettableFrameLayout.LayoutParams) getLayoutParams();
mBadge = badge;
@@ -342,6 +345,10 @@
mBadge.setBounds(0, 0, clipViewOgWidth, clipViewOgHeight);
}
}
+
+ if (!mIsOpening && btvIcon != null) {
+ mBtvDrawable.setBackground(btvIcon);
+ }
invalidate();
}
@@ -360,7 +367,7 @@
synchronized (mIconLoadResult) {
if (mIconLoadResult.isIconLoaded) {
setIcon(mIconLoadResult.drawable, mIconLoadResult.badge,
- mIconLoadResult.iconOffset);
+ mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset);
setIconAndDotVisible(originalView, false);
} else {
mIconLoadResult.onIconLoaded = () -> {
@@ -369,7 +376,7 @@
}
setIcon(mIconLoadResult.drawable, mIconLoadResult.badge,
- mIconLoadResult.iconOffset);
+ mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset);
setVisibility(VISIBLE);
setIconAndDotVisible(originalView, false);
@@ -434,10 +441,6 @@
mEndRunnable.run();
mEndRunnable = null;
}
- if (mFadeAnimatorSet != null) {
- mFadeAnimatorSet.end();
- mFadeAnimatorSet = null;
- }
}
@Override
@@ -546,8 +549,16 @@
setIconAndDotVisible(originalView, true);
view.finish(dragLayer);
} else {
- view.mFadeAnimatorSet = view.createFadeAnimation(originalView, dragLayer);
- view.mFadeAnimatorSet.start();
+ originalView.setVisibility(VISIBLE);
+ if (originalView instanceof IconLabelDotView) {
+ setIconAndDotVisible(originalView, true);
+ }
+ if (originalView instanceof BubbleTextView) {
+ BubbleTextView btv = (BubbleTextView) originalView;
+ btv.setIconVisible(true);
+ btv.setForceHideDot(true);
+ }
+ view.finish(dragLayer);
}
} else {
view.finish(dragLayer);
@@ -564,47 +575,6 @@
return view;
}
- private AnimatorSet createFadeAnimation(View originalView, DragLayer dragLayer) {
- AnimatorSet fade = new AnimatorSet();
- fade.setDuration(FADE_DURATION_MS);
- fade.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- originalView.setVisibility(VISIBLE);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- finish(dragLayer);
- }
- });
-
- if (originalView instanceof IconLabelDotView) {
- fade.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- setIconAndDotVisible(originalView, true);
- }
- });
- }
-
- if (originalView instanceof BubbleTextView) {
- BubbleTextView btv = (BubbleTextView) originalView;
- fade.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- btv.setIconVisible(true);
- btv.setForceHideDot(true);
- }
- });
- fade.play(ObjectAnimator.ofInt(btv.getIcon(), DRAWABLE_ALPHA, 0, 255));
- } else if (!(originalView instanceof FolderIcon)) {
- fade.play(ObjectAnimator.ofFloat(originalView, ALPHA, 0f, 1f));
- }
-
- return fade;
- }
-
private void finish(DragLayer dragLayer) {
((ViewGroup) dragLayer.getParent()).removeView(this);
dragLayer.removeView(mListenerView);
@@ -628,11 +598,7 @@
mLoadIconSignal = null;
mEndRunnable = null;
mFinalDrawableBounds.setEmpty();
- if (mFadeAnimatorSet != null) {
- mFadeAnimatorSet.cancel();
- }
mPositionOut = null;
- mFadeAnimatorSet = null;
mListenerView.setListener(null);
mOriginalIcon = null;
mOnTargetChangeRunnable = null;
@@ -640,11 +606,13 @@
sTmpObjArray[0] = null;
mIconLoadResult = null;
mClipIconView.recycle();
+ mBtvDrawable.setBackground(null);
mFastFinishRunnable = null;
}
private static class IconLoadResult {
final ItemInfo itemInfo;
+ Drawable btvDrawable;
Drawable drawable;
Drawable badge;
int iconOffset;
diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java
index a8e1c6b..dd322d9 100644
--- a/src/com/android/launcher3/views/HeroSearchResultView.java
+++ b/src/com/android/launcher3/views/HeroSearchResultView.java
@@ -16,12 +16,16 @@
package com.android.launcher3.views;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ShortcutInfo;
import android.graphics.Point;
import android.os.Bundle;
import android.util.AttributeSet;
+import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
@@ -31,9 +35,10 @@
import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController;
+import com.android.launcher3.allapps.search.AllAppsSearchBarController.PayloadResultHandler;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.graphics.DragPreviewProvider;
@@ -53,9 +58,10 @@
* A view representing a high confidence app search result that includes shortcuts
*/
public class HeroSearchResultView extends LinearLayout implements DragSource,
- AllAppsSearchBarController.PayloadResultHandler<List<ItemInfoWithIcon>> {
+ PayloadResultHandler<List<Pair<ShortcutInfo, ItemInfoWithIcon>>> {
public static final int MAX_SHORTCUTS_COUNT = 2;
+ private final Object[] mTargetInfo = createTargetInfo();
BubbleTextView mBubbleTextView;
View mIconView;
BubbleTextView[] mDeepShortcutTextViews = new BubbleTextView[2];
@@ -102,7 +108,7 @@
grid.allAppsIconSizePx));
bubbleTextView.setOnClickListener(view -> {
WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
- SearchTargetEvent event = new SearchTargetEvent(
+ SearchTargetEvent event = getSearchTargetEvent(
SearchTarget.ItemType.APP_HERO,
SearchTargetEvent.CHILD_SELECT);
event.bundle = getAppBundle(itemInfo);
@@ -119,15 +125,25 @@
* Apply {@link ItemInfo} for appIcon and shortcut Icons
*/
@Override
- public void applyAdapterInfo(AdapterItemWithPayload<List<ItemInfoWithIcon>> adapterItem) {
+ public void applyAdapterInfo(
+ AdapterItemWithPayload<List<Pair<ShortcutInfo, ItemInfoWithIcon>>> adapterItem) {
mBubbleTextView.applyFromApplicationInfo(adapterItem.appInfo);
mIconView.setBackground(mBubbleTextView.getIcon());
mIconView.setTag(adapterItem.appInfo);
- List<ItemInfoWithIcon> shorcutInfos = adapterItem.getPayload();
+ List<Pair<ShortcutInfo, ItemInfoWithIcon>> shortcutDetails = adapterItem.getPayload();
+ LauncherAppState appState = LauncherAppState.getInstance(getContext());
for (int i = 0; i < mDeepShortcutTextViews.length; i++) {
- mDeepShortcutTextViews[i].setVisibility(shorcutInfos.size() > i ? VISIBLE : GONE);
- if (i < shorcutInfos.size()) {
- mDeepShortcutTextViews[i].applyFromItemInfoWithIcon(shorcutInfos.get(i));
+ BubbleTextView shortcutView = mDeepShortcutTextViews[i];
+ mDeepShortcutTextViews[i].setVisibility(shortcutDetails.size() > i ? VISIBLE : GONE);
+ if (i < shortcutDetails.size()) {
+ Pair<ShortcutInfo, ItemInfoWithIcon> p = shortcutDetails.get(i);
+ //apply ItemInfo and prepare view
+ shortcutView.applyFromWorkspaceItem((WorkspaceItemInfo) p.second);
+ MODEL_EXECUTOR.execute(() -> {
+ // load unbadged shortcut in background and update view when icon ready
+ appState.getIconCache().getUnbadgedShortcutIcon(p.second, p.first);
+ MAIN_EXECUTOR.post(() -> shortcutView.reapplyItemInfo(p.second));
+ });
}
}
mPlugin = adapterItem.getPlugin();
@@ -135,6 +151,11 @@
}
@Override
+ public Object[] getTargetInfo() {
+ return mTargetInfo;
+ }
+
+ @Override
public void onDropCompleted(View target, DropTarget.DragObject d, boolean success) {
mBubbleTextView.setVisibility(VISIBLE);
mBubbleTextView.setIconVisible(true);
@@ -169,7 +190,7 @@
mLauncher.getWorkspace().beginDragShared(mContainer.mBubbleTextView,
draggableView, mContainer, itemInfo, previewProvider, new DragOptions());
- SearchTargetEvent event = new SearchTargetEvent(
+ SearchTargetEvent event = mContainer.getSearchTargetEvent(
SearchTarget.ItemType.APP_HERO, SearchTargetEvent.LONG_PRESS);
event.bundle = getAppBundle(itemInfo);
if (mContainer.mPlugin != null) {
@@ -186,7 +207,7 @@
Launcher launcher = Launcher.getLauncher(getContext());
launcher.startActivitySafely(this, itemInfo.getIntent(), itemInfo);
- SearchTargetEvent event = new SearchTargetEvent(
+ SearchTargetEvent event = getSearchTargetEvent(
SearchTarget.ItemType.APP_HERO, eventType);
event.bundle = getAppBundle(itemInfo);
if (mPlugin != null) {
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 3ec20d5..80f0981 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -16,6 +16,7 @@
package com.android.launcher3.views;
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_FLAVOR;
+import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_LAUNCH_SOURCE;
import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_OFFSET;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS;
@@ -132,7 +133,7 @@
view.setOnLongClickListener(popup);
popup.mItemMap.put(view, item);
}
- popup.reorderAndShow(popup.getChildCount());
+ popup.show();
}
@VisibleForTesting
@@ -211,7 +212,8 @@
Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
.putExtra(EXTRA_WALLPAPER_OFFSET,
- launcher.getWorkspace().getWallpaperOffsetForCenterPage());
+ launcher.getWorkspace().getWallpaperOffsetForCenterPage())
+ .putExtra(EXTRA_WALLPAPER_LAUNCH_SOURCE, "app_launched_launcher");
if (!Utilities.existsStyleWallpapers(launcher)) {
intent.putExtra(EXTRA_WALLPAPER_FLAVOR, "wallpaper_only");
} else {
diff --git a/src/com/android/launcher3/views/SearchResultIconRow.java b/src/com/android/launcher3/views/SearchResultIconRow.java
new file mode 100644
index 0000000..313ae5e
--- /dev/null
+++ b/src/com/android/launcher3/views/SearchResultIconRow.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
+import android.app.RemoteAction;
+import android.content.Context;
+import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
+import com.android.launcher3.allapps.search.AllAppsSearchBarController;
+import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.touch.ItemClickHandler;
+import com.android.systemui.plugins.AllAppsSearchPlugin;
+import com.android.systemui.plugins.shared.SearchTarget;
+import com.android.systemui.plugins.shared.SearchTarget.ItemType;
+import com.android.systemui.plugins.shared.SearchTargetEvent;
+
+/**
+ * A view representing a stand alone shortcut search result
+ */
+public class SearchResultIconRow extends DoubleShadowBubbleTextView implements
+ AllAppsSearchBarController.PayloadResultHandler<SearchTarget> {
+
+ private final Object[] mTargetInfo = createTargetInfo();
+ private ShortcutInfo mShortcutInfo;
+ private AllAppsSearchPlugin mPlugin;
+ private AdapterItemWithPayload<SearchTarget> mAdapterItem;
+
+
+ public SearchResultIconRow(@NonNull Context context) {
+ super(context);
+ }
+
+ public SearchResultIconRow(@NonNull Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SearchResultIconRow(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ public void applyAdapterInfo(AdapterItemWithPayload<SearchTarget> adapterItemWithPayload) {
+ if (mAdapterItem != null) {
+ mAdapterItem.setSelectionHandler(null);
+ }
+ mAdapterItem = adapterItemWithPayload;
+ SearchTarget payload = adapterItemWithPayload.getPayload();
+ mPlugin = adapterItemWithPayload.getPlugin();
+
+ if (payload.mRemoteAction != null) {
+ prepareUsingRemoteAction(payload.mRemoteAction,
+ payload.bundle.getString(SearchTarget.REMOTE_ACTION_TOKEN),
+ payload.bundle.getBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START));
+ } else {
+ prepareUsingShortcutInfo(payload.shortcuts.get(0));
+ }
+ setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
+ adapterItemWithPayload.setSelectionHandler(this::handleSelection);
+ }
+
+ private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) {
+ mShortcutInfo = shortcutInfo;
+ WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(mShortcutInfo, getContext());
+ applyFromWorkspaceItem(workspaceItemInfo);
+ LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
+ MODEL_EXECUTOR.execute(() -> {
+ launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, mShortcutInfo);
+ reapplyItemInfoAsync(workspaceItemInfo);
+ });
+ }
+
+ private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start) {
+ RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
+
+ applyFromRemoteActionInfo(itemInfo);
+ UI_HELPER_EXECUTOR.post(() -> {
+ // If the Drawable from the remote action is not AdaptiveBitmap, styling will not work.
+ try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
+ Drawable d = itemInfo.getRemoteAction().getIcon().loadDrawable(getContext());
+ itemInfo.bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
+ Build.VERSION.SDK_INT);
+ reapplyItemInfoAsync(itemInfo);
+ }
+ });
+
+ }
+
+ void reapplyItemInfoAsync(ItemInfoWithIcon itemInfoWithIcon) {
+ MAIN_EXECUTOR.post(() -> reapplyItemInfo(itemInfoWithIcon));
+ }
+
+ @Override
+ public Object[] getTargetInfo() {
+ return mTargetInfo;
+ }
+
+ private void handleSelection(int eventType) {
+ ItemInfo itemInfo = (ItemInfo) getTag();
+ Launcher launcher = Launcher.getLauncher(getContext());
+ final SearchTargetEvent searchTargetEvent;
+ if (itemInfo instanceof WorkspaceItemInfo) {
+ ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) itemInfo, launcher);
+ searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.SHORTCUT,
+ eventType);
+ searchTargetEvent.shortcut = mShortcutInfo;
+ } else {
+ RemoteActionItemInfo remoteItemInfo = (RemoteActionItemInfo) itemInfo;
+ ItemClickHandler.onClickRemoteAction(launcher, remoteItemInfo);
+ searchTargetEvent = getSearchTargetEvent(ItemType.ACTION,
+ eventType);
+ searchTargetEvent.bundle = new Bundle();
+ searchTargetEvent.remoteAction = remoteItemInfo.getRemoteAction();
+ searchTargetEvent.bundle.putBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START,
+ remoteItemInfo.shouldStartInLauncher());
+ searchTargetEvent.bundle.putString(SearchTarget.REMOTE_ACTION_TOKEN,
+ remoteItemInfo.getToken());
+ }
+ if (mPlugin != null) {
+ mPlugin.notifySearchTargetEvent(searchTargetEvent);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/SearchResultPeopleView.java b/src/com/android/launcher3/views/SearchResultPeopleView.java
index 6e45e88..0c9a22f 100644
--- a/src/com/android/launcher3/views/SearchResultPeopleView.java
+++ b/src/com/android/launcher3/views/SearchResultPeopleView.java
@@ -15,9 +15,6 @@
*/
package com.android.launcher3.views;
-import static android.content.Intent.URI_ALLOW_UNSAFE;
-import static android.content.Intent.URI_ANDROID_APP_SCHEME;
-
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -28,7 +25,6 @@
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.net.Uri;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
@@ -50,7 +46,6 @@
import com.android.systemui.plugins.shared.SearchTarget;
import com.android.systemui.plugins.shared.SearchTargetEvent;
-import java.net.URISyntaxException;
import java.util.ArrayList;
/**
@@ -66,8 +61,8 @@
private TextView mTitleView;
private ImageButton[] mProviderButtons = new ImageButton[3];
private AllAppsSearchPlugin mPlugin;
- private Uri mContactUri;
-
+ private Intent mIntent;
+ private final Object[] mTargetInfo = createTargetInfo();
public SearchResultPeopleView(Context context) {
this(context, null, 0);
@@ -109,7 +104,7 @@
Bundle payload = adapterItemWithPayload.getPayload();
mPlugin = adapterItemWithPayload.getPlugin();
mTitleView.setText(payload.getString("title"));
- mContactUri = payload.getParcelable("contact_uri");
+ mIntent = payload.getParcelable("intent");
Bitmap icon = payload.getParcelable("icon");
if (icon != null) {
RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(getResources(), icon);
@@ -125,25 +120,20 @@
for (int i = 0; i < mProviderButtons.length; i++) {
ImageButton button = mProviderButtons[i];
if (providers != null && i < providers.size()) {
- try {
- Bundle provider = providers.get(i);
- Intent intent = Intent.parseUri(provider.getString("intent_uri_str"),
- URI_ANDROID_APP_SCHEME | URI_ALLOW_UNSAFE);
- setupProviderButton(button, provider, intent);
- String pkg = provider.getString("package_name");
- UI_HELPER_EXECUTOR.post(() -> {
- try {
- ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(
- pkg, 0);
- Drawable appIcon = applicationInfo.loadIcon(mPackageManager);
- MAIN_EXECUTOR.post(()-> button.setImageDrawable(appIcon));
- } catch (PackageManager.NameNotFoundException ignored) {
- }
+ Bundle provider = providers.get(i);
+ Intent intent = provider.getParcelable("intent");
+ setupProviderButton(button, provider, intent, adapterItemWithPayload);
+ String pkg = provider.getString("package_name");
+ UI_HELPER_EXECUTOR.post(() -> {
+ try {
+ ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(
+ pkg, 0);
+ Drawable appIcon = applicationInfo.loadIcon(mPackageManager);
+ MAIN_EXECUTOR.post(() -> button.setImageDrawable(appIcon));
+ } catch (PackageManager.NameNotFoundException ignored) {
+ }
- });
- } catch (URISyntaxException ex) {
- button.setVisibility(GONE);
- }
+ });
} else {
button.setVisibility(GONE);
}
@@ -151,15 +141,21 @@
adapterItemWithPayload.setSelectionHandler(this::handleSelection);
}
- private void setupProviderButton(ImageButton button, Bundle provider, Intent intent) {
+ @Override
+ public Object[] getTargetInfo() {
+ return mTargetInfo;
+ }
+
+ private void setupProviderButton(ImageButton button, Bundle provider, Intent intent,
+ AllAppsGridAdapter.AdapterItem adapterItem) {
Launcher launcher = Launcher.getLauncher(getContext());
button.setOnClickListener(b -> {
launcher.startActivitySafely(b, intent, null);
- SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
+ SearchTargetEvent searchTargetEvent = getSearchTargetEvent(
SearchTarget.ItemType.PEOPLE,
SearchTargetEvent.CHILD_SELECT);
searchTargetEvent.bundle = new Bundle();
- searchTargetEvent.bundle.putParcelable("contact_uri", mContactUri);
+ searchTargetEvent.bundle.putParcelable("intent", mIntent);
searchTargetEvent.bundle.putBundle("provider", provider);
if (mPlugin != null) {
mPlugin.notifySearchTargetEvent(searchTargetEvent);
@@ -169,14 +165,13 @@
private void handleSelection(int eventType) {
- if (mContactUri != null) {
+ if (mIntent != null) {
Launcher launcher = Launcher.getLauncher(getContext());
- launcher.startActivitySafely(this, new Intent(Intent.ACTION_VIEW, mContactUri).setFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK), null);
- SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
- SearchTarget.ItemType.PEOPLE, eventType);
+ launcher.startActivitySafely(this, mIntent, null);
+ SearchTargetEvent searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.PEOPLE,
+ eventType);
searchTargetEvent.bundle = new Bundle();
- searchTargetEvent.bundle.putParcelable("contact_uri", mContactUri);
+ searchTargetEvent.bundle.putParcelable("intent", mIntent);
if (mPlugin != null) {
mPlugin.notifySearchTargetEvent(searchTargetEvent);
}
diff --git a/src/com/android/launcher3/views/SearchResultPlayItem.java b/src/com/android/launcher3/views/SearchResultPlayItem.java
index 8624609..ff3ecc8 100644
--- a/src/com/android/launcher3/views/SearchResultPlayItem.java
+++ b/src/com/android/launcher3/views/SearchResultPlayItem.java
@@ -58,6 +58,8 @@
private String mPackageName;
private boolean mIsInstantGame;
private AllAppsSearchPlugin mPlugin;
+ private final Object[] mTargetInfo = createTargetInfo();
+
public SearchResultPlayItem(Context context) {
this(context, null, 0);
@@ -125,6 +127,11 @@
});
}
+ @Override
+ public Object[] getTargetInfo() {
+ return mTargetInfo;
+ }
+
private void showIfNecessary(TextView textView, @Nullable String string) {
if (string == null || string.isEmpty()) {
textView.setVisibility(GONE);
@@ -160,7 +167,7 @@
}
private void logSearchEvent(int eventType) {
- SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
+ SearchTargetEvent searchTargetEvent = getSearchTargetEvent(
SearchTarget.ItemType.PLAY_RESULTS, eventType);
searchTargetEvent.bundle = new Bundle();
searchTargetEvent.bundle.putString("package_name", mPackageName);
diff --git a/src/com/android/launcher3/views/SearchResultShortcut.java b/src/com/android/launcher3/views/SearchResultShortcut.java
deleted file mode 100644
index 307cf34..0000000
--- a/src/com/android/launcher3/views/SearchResultShortcut.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.views;
-
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.content.Context;
-import android.content.pm.ShortcutInfo;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.R;
-import com.android.launcher3.allapps.AllAppsGridAdapter;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.touch.ItemClickHandler;
-import com.android.systemui.plugins.AllAppsSearchPlugin;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
-
-/**
- * A view representing a stand alone shortcut search result
- */
-public class SearchResultShortcut extends FrameLayout implements
- AllAppsSearchBarController.PayloadResultHandler<SearchTarget> {
-
- private BubbleTextView mBubbleTextView;
- private View mIconView;
- private ShortcutInfo mShortcutInfo;
- private AllAppsSearchPlugin mPlugin;
-
- public SearchResultShortcut(@NonNull Context context) {
- super(context);
- }
-
- public SearchResultShortcut(@NonNull Context context,
- @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- public SearchResultShortcut(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- Launcher launcher = Launcher.getLauncher(getContext());
- DeviceProfile grid = launcher.getDeviceProfile();
- mIconView = findViewById(R.id.icon);
- ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams();
- iconParams.height = grid.allAppsIconSizePx;
- iconParams.width = grid.allAppsIconSizePx;
- mBubbleTextView = findViewById(R.id.bubble_text);
- setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
- }
-
- @Override
- public void applyAdapterInfo(
- AllAppsGridAdapter.AdapterItemWithPayload<SearchTarget> adapterItemWithPayload) {
- SearchTarget payload = adapterItemWithPayload.getPayload();
- mPlugin = adapterItemWithPayload.getPlugin();
- mShortcutInfo = payload.shortcuts.get(0);
- WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(mShortcutInfo, getContext());
- mBubbleTextView.applyFromWorkspaceItem(workspaceItemInfo);
- mIconView.setBackground(mBubbleTextView.getIcon());
- LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
- MODEL_EXECUTOR.execute(() -> {
- launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, mShortcutInfo);
- mBubbleTextView.applyFromWorkspaceItem(workspaceItemInfo);
- mIconView.setBackground(mBubbleTextView.getIcon());
- });
- adapterItemWithPayload.setSelectionHandler(this::handleSelection);
- }
-
- private void handleSelection(int eventType) {
- WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) mBubbleTextView.getTag();
- ItemClickHandler.onClickAppShortcut(this, itemInfo, Launcher.getLauncher(getContext()));
-
- SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
- SearchTarget.ItemType.SHORTCUT, eventType);
- searchTargetEvent.shortcut = mShortcutInfo;
- if (mPlugin != null) {
- mPlugin.notifySearchTargetEvent(searchTargetEvent);
- }
- }
-}
diff --git a/src/com/android/launcher3/views/SearchResultSuggestRow.java b/src/com/android/launcher3/views/SearchResultSuggestRow.java
new file mode 100644
index 0000000..b5abbcc
--- /dev/null
+++ b/src/com/android/launcher3/views/SearchResultSuggestRow.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import static com.android.systemui.plugins.shared.SearchTarget.ItemType.SUGGEST;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
+import com.android.launcher3.allapps.search.AllAppsSearchBarController;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.touch.ItemClickHandler;
+import com.android.systemui.plugins.AllAppsSearchPlugin;
+import com.android.systemui.plugins.shared.SearchTarget;
+import com.android.systemui.plugins.shared.SearchTargetEvent;
+
+/**
+ * A view representing a fallback search suggestion row.
+ */
+public class SearchResultSuggestRow extends LinearLayout implements
+ View.OnClickListener, AllAppsSearchBarController.PayloadResultHandler<SearchTarget> {
+
+ private final Object[] mTargetInfo = createTargetInfo();
+ private AllAppsSearchPlugin mPlugin;
+ private AdapterItemWithPayload<SearchTarget> mAdapterItem;
+ private TextView mTitle;
+
+
+ public SearchResultSuggestRow(@NonNull Context context) {
+ super(context);
+ }
+
+ public SearchResultSuggestRow(@NonNull Context context,
+ @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SearchResultSuggestRow(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mTitle = findViewById(R.id.title);
+ setOnClickListener(this);
+ }
+ @Override
+ public void applyAdapterInfo(AdapterItemWithPayload<SearchTarget> adapterItemWithPayload) {
+ mAdapterItem = adapterItemWithPayload;
+ SearchTarget payload = adapterItemWithPayload.getPayload();
+ mPlugin = adapterItemWithPayload.getPlugin();
+
+ if (payload.mRemoteAction != null) {
+ RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(payload.mRemoteAction,
+ payload.bundle.getString(SearchTarget.REMOTE_ACTION_TOKEN),
+ payload.bundle.getBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START));
+ setTag(itemInfo);
+ }
+ showIfAvailable(mTitle, payload.mRemoteAction.getTitle().toString());
+ setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
+ adapterItemWithPayload.setSelectionHandler(this::handleSelection);
+ }
+
+ @Override
+ public Object[] getTargetInfo() {
+ return mTargetInfo;
+ }
+
+ private void handleSelection(int eventType) {
+ ItemInfo itemInfo = (ItemInfo) getTag();
+ Launcher launcher = Launcher.getLauncher(getContext());
+ if (itemInfo instanceof RemoteActionItemInfo) return;
+
+ RemoteActionItemInfo remoteItemInfo = (RemoteActionItemInfo) itemInfo;
+ ItemClickHandler.onClickRemoteAction(launcher, remoteItemInfo);
+ SearchTargetEvent searchTargetEvent = getSearchTargetEvent(SUGGEST, eventType);
+ searchTargetEvent.bundle = new Bundle();
+ searchTargetEvent.remoteAction = remoteItemInfo.getRemoteAction();
+ searchTargetEvent.bundle.putBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START,
+ remoteItemInfo.shouldStartInLauncher());
+ searchTargetEvent.bundle.putString(SearchTarget.REMOTE_ACTION_TOKEN,
+ remoteItemInfo.getToken());
+
+ if (mPlugin != null) {
+ mPlugin.notifySearchTargetEvent(searchTargetEvent);
+ }
+ }
+
+ @Override
+ public void onClick(View view) {
+ handleSelection(SearchTargetEvent.SELECT);
+ }
+
+ private void showIfAvailable(TextView view, @Nullable String string) {
+ System.out.println("Plugin suggest string:" + string);
+ if (TextUtils.isEmpty(string)) {
+ view.setVisibility(GONE);
+ } else {
+ System.out.println("Plugin suggest string:" + string);
+ view.setVisibility(VISIBLE);
+ view.setText(string);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/SearchSectionHeaderView.java b/src/com/android/launcher3/views/SearchSectionHeaderView.java
index d439ee3..0fe0a43 100644
--- a/src/com/android/launcher3/views/SearchSectionHeaderView.java
+++ b/src/com/android/launcher3/views/SearchSectionHeaderView.java
@@ -52,4 +52,9 @@
setVisibility(INVISIBLE);
}
}
+
+ @Override
+ public Object[] getTargetInfo() {
+ return null;
+ }
}
diff --git a/src/com/android/launcher3/views/SearchSettingsRowView.java b/src/com/android/launcher3/views/SearchSettingsRowView.java
index 93bcee2..a1a0172 100644
--- a/src/com/android/launcher3/views/SearchSettingsRowView.java
+++ b/src/com/android/launcher3/views/SearchSettingsRowView.java
@@ -48,6 +48,8 @@
private TextView mBreadcrumbsView;
private Intent mIntent;
private AllAppsSearchPlugin mPlugin;
+ private final Object[] mTargetInfo = createTargetInfo();
+
public SearchSettingsRowView(@NonNull Context context) {
super(context);
@@ -87,6 +89,11 @@
adapterItemWithPayload.setSelectionHandler(this::handleSelection);
}
+ @Override
+ public Object[] getTargetInfo() {
+ return mTargetInfo;
+ }
+
private void showIfAvailable(TextView view, @Nullable String string) {
if (TextUtils.isEmpty(string)) {
view.setVisibility(GONE);
@@ -108,7 +115,7 @@
Launcher launcher = Launcher.getLauncher(getContext());
launcher.startActivityForResult(mIntent, 0);
- SearchTargetEvent searchTargetEvent = new SearchTargetEvent(
+ SearchTargetEvent searchTargetEvent = getSearchTargetEvent(
SearchTarget.ItemType.SETTINGS_ROW, eventType);
searchTargetEvent.bundle = new Bundle();
searchTargetEvent.bundle.putParcelable("intent", mIntent);
diff --git a/src/com/android/launcher3/views/ThumbnailSearchResultView.java b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
new file mode 100644
index 0000000..bbc4773
--- /dev/null
+++ b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import android.util.AttributeSet;
+
+import androidx.core.graphics.drawable.RoundedBitmapDrawable;
+import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
+import com.android.launcher3.allapps.search.AllAppsSearchBarController;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.touch.ItemClickHandler;
+import com.android.launcher3.util.Themes;
+import com.android.systemui.plugins.AllAppsSearchPlugin;
+import com.android.systemui.plugins.shared.SearchTarget;
+import com.android.systemui.plugins.shared.SearchTargetEvent;
+
+/**
+ * A view representing a high confidence app search result that includes shortcuts
+ */
+public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppCompatImageView
+ implements AllAppsSearchBarController.PayloadResultHandler<SearchTarget> {
+
+ private final Object[] mTargetInfo = createTargetInfo();
+ AllAppsSearchPlugin mPlugin;
+ int mPosition;
+
+ public ThumbnailSearchResultView(Context context) {
+ super(context);
+ }
+
+ public ThumbnailSearchResultView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ThumbnailSearchResultView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ private void handleSelection(int eventType) {
+ Launcher launcher = Launcher.getLauncher(getContext());
+ ItemInfo itemInfo = (ItemInfo) getTag();
+ if (itemInfo instanceof RemoteActionItemInfo) {
+ RemoteActionItemInfo remoteItemInfo = (RemoteActionItemInfo) itemInfo;
+ ItemClickHandler.onClickRemoteAction(launcher, remoteItemInfo);
+ } else {
+ ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) itemInfo, launcher);
+ }
+ if (mPlugin != null) {
+ SearchTargetEvent event = getSearchTargetEvent(
+ SearchTarget.ItemType.SCREENSHOT, eventType);
+ mPlugin.notifySearchTargetEvent(event);
+ }
+ }
+
+ @Override
+ public void applyAdapterInfo(AdapterItemWithPayload<SearchTarget> adapterItem) {
+ Launcher launcher = Launcher.getLauncher(getContext());
+ mPosition = adapterItem.position;
+
+ SearchTarget target = adapterItem.getPayload();
+ Bitmap bitmap;
+ if (target.mRemoteAction != null) {
+ RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(target.mRemoteAction,
+ target.bundle.getString(SearchTarget.REMOTE_ACTION_TOKEN),
+ target.bundle.getBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START));
+ ItemClickHandler.onClickRemoteAction(launcher, itemInfo);
+ bitmap = ((BitmapDrawable) target.mRemoteAction.getIcon()
+ .loadDrawable(getContext())).getBitmap();
+ setTag(itemInfo);
+ } else {
+ bitmap = (Bitmap) target.bundle.getParcelable("bitmap");
+ WorkspaceItemInfo itemInfo = new WorkspaceItemInfo();
+ itemInfo.intent = new Intent(Intent.ACTION_VIEW)
+ .setData(Uri.parse(target.bundle.getString("uri")))
+ .setType("image/*")
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ setTag(itemInfo);
+ }
+ RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(null, bitmap);
+ drawable.setCornerRadius(Themes.getDialogCornerRadius(getContext()));
+ setImageDrawable(drawable);
+ setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
+ mPlugin = adapterItem.getPlugin();
+ adapterItem.setSelectionHandler(this::handleSelection);
+ }
+
+ @Override
+ public Object[] getTargetInfo() {
+ return mTargetInfo;
+ }
+}
diff --git a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
index 4fa670f..aa3ab8f 100644
--- a/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/AllAppsSearchPlugin.java
@@ -32,7 +32,7 @@
@ProvidesInterface(action = AllAppsSearchPlugin.ACTION, version = AllAppsSearchPlugin.VERSION)
public interface AllAppsSearchPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_ALL_APPS_SEARCH_ACTIONS";
- int VERSION = 6;
+ int VERSION = 7;
void setup(Activity activity, View view);
@@ -43,6 +43,12 @@
void onStateTransitionComplete(int state);
/**
+ * Send launcher window focus and visibility changed signals.
+ */
+ void onWindowFocusChanged(boolean hasFocus);
+ void onWindowVisibilityChanged(int visibility);
+
+ /**
* Send signal when user starts typing, perform search, when search ends
*/
void startedSearchSession();
diff --git a/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java b/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
index c6b8300..3f0dc39 100644
--- a/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
+++ b/src_plugins/com/android/systemui/plugins/shared/SearchTarget.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.plugins.shared;
+import android.app.RemoteAction;
import android.content.pm.ShortcutInfo;
import android.os.Bundle;
@@ -25,17 +26,69 @@
*/
public class SearchTarget implements Comparable<SearchTarget> {
+
+ /**
+ * A bundle key for boolean value of whether remote action should be started in launcher or not
+ */
+ public static final String REMOTE_ACTION_SHOULD_START = "should_start_for_result";
+ public static final String REMOTE_ACTION_TOKEN = "action_token";
+
+
public enum ViewType {
+
+ /**
+ * Consists of N number of icons. (N: launcher column count)
+ */
TOP_HIT(0),
+
+ /**
+ * Consists of 1 icon and two subsidiary icons.
+ */
HERO(1),
+
+ /**
+ * Main/sub/breadcrumb texts are rendered.
+ */
DETAIL(2),
+
+ /**
+ * Consists of an icon, three detail strings.
+ */
ROW(3),
+
+ /**
+ * Consists of an icon, three detail strings and a button.
+ */
ROW_WITH_BUTTON(4),
+
+ /**
+ * Consists of a single slice view
+ */
SLICE(5),
+
+ /**
+ * Similar to hero section.
+ */
SHORTCUT(6),
- PEOPLE(7);
+
+ /**
+ * Person icon and handling app icons are rendered.
+ */
+ PEOPLE(7),
+
+ /**
+ * N number of 1x1 ratio thumbnail is rendered.
+ * (current N = 3)
+ */
+ THUMBNAIL(8),
+
+ /**
+ * Fallback search icon and relevant text is rendered.
+ */
+ SUGGEST(9);
private final int mId;
+
ViewType(int id) {
mId = id;
}
@@ -52,9 +105,15 @@
APP(3, "", ViewType.TOP_HIT),
APP_HERO(4, "", ViewType.HERO),
SHORTCUT(5, "Shortcuts", ViewType.SHORTCUT),
- PEOPLE(6, "People", ViewType.PEOPLE);
+ PEOPLE(6, "People", ViewType.PEOPLE),
+ SCREENSHOT(7, "Screenshots", ViewType.THUMBNAIL),
+ ACTION(8, "Actions", ViewType.SHORTCUT),
+ SUGGEST(9, "Fallback Search", ViewType.SUGGEST),
+ CHROME_TAB(10, "Chrome Tab", ViewType.SHORTCUT);
private final int mId;
+
+ /** Used to render section title. */
private final String mTitle;
private final ViewType mViewType;
@@ -81,19 +140,21 @@
public List<ShortcutInfo> shortcuts;
public Bundle bundle;
public float score;
+ public String mSessionId;
+ public RemoteAction mRemoteAction;
/**
* Constructor to create the search target. Bundle is currently temporary to hold
* search target primitives that cannot be expressed as java primitive objects
* or AOSP native objects.
- *
*/
public SearchTarget(ItemType itemType, List<ShortcutInfo> shortcuts,
- Bundle bundle, float score) {
+ Bundle bundle, float score, String sessionId) {
this.type = itemType;
this.shortcuts = shortcuts;
this.bundle = bundle;
this.score = score;
+ this.mSessionId = sessionId;
}
@Override
diff --git a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
index ac4bc33..5016abc 100644
--- a/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
+++ b/src_plugins/com/android/systemui/plugins/shared/SearchTargetEvent.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.plugins.shared;
+import android.app.RemoteAction;
import android.content.pm.ShortcutInfo;
import android.os.Bundle;
@@ -29,12 +30,17 @@
public SearchTarget.ItemType type;
public ShortcutInfo shortcut;
+ public RemoteAction remoteAction;
public int eventType;
public Bundle bundle;
- public float score;
+ public int index;
+ public String sessionIdentifier;
- public SearchTargetEvent(SearchTarget.ItemType itemType, int eventType) {
+ public SearchTargetEvent(SearchTarget.ItemType itemType, int eventType, int index,
+ String sessionId) {
this.type = itemType;
this.eventType = eventType;
+ this.index = index;
+ this.sessionIdentifier = sessionId;
}
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index ec3f93f..a4e53a1 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -16,13 +16,13 @@
package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
import android.content.Context;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
* Definition for AllApps state
@@ -41,7 +41,7 @@
};
public AllAppsState(int id) {
- super(id, ContainerType.ALLAPPS, STATE_FLAGS);
+ super(id, LAUNCHER_STATE_ALLAPPS, STATE_FLAGS);
}
@Override
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
index d102bcc..da5a94f 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -15,10 +15,11 @@
*/
package com.android.launcher3.uioverrides.states;
+import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
+
import android.content.Context;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
/**
* Definition for overview state
@@ -26,7 +27,7 @@
public class OverviewState extends LauncherState {
public OverviewState(int id) {
- super(id, ContainerType.WORKSPACE, FLAG_DISABLE_RESTORE);
+ super(id, LAUNCHER_STATE_OVERVIEW, FLAG_DISABLE_RESTORE);
}
@Override
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 5e42d9b..e118481 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -279,6 +279,8 @@
if (userManager != null) {
for (UserHandle userHandle : userManager.getUserProfiles()) {
if (!userHandle.isSystem()) {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED,
+ "removing user " + userHandle.getIdentifier());
mDevice.executeShellCommand("pm remove-user " + userHandle.getIdentifier());
}
}
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java
index f5f93c4..8d594de 100644
--- a/tests/src/com/android/launcher3/ui/WorkTabTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java
@@ -55,7 +55,9 @@
private static final int WORK_PAGE = AllAppsContainerView.AdapterHolder.WORK;
@Before
- public void createWorkProfile() throws Exception {
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
String output =
mDevice.executeShellCommand(
"pm create-user --profileOf 0 --managed TestProfile");
@@ -136,7 +138,8 @@
});
executeOnLauncher(launcher -> Log.d(TestProtocol.WORK_PROFILE_REMOVED,
- "Work profile status: " + launcher.getAppsView().isPersonalTabVisible()));
+ "work profile status (" + mProfileUserId + ") :"
+ + launcher.getAppsView().isWorkTabVisible()));
// verify work edu is seen next
waitForLauncherCondition("Launcher did not show the next edu screen", l ->