Merge "Handle the animation when restarting apps" into ub-launcher3-master
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 44d43c6..456727c 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -19,11 +19,10 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
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;
@@ -48,12 +47,14 @@
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.stream.Stream;
@@ -123,7 +124,8 @@
@Override
protected void onUiChangedWhileSleeping() {
// Remove the snapshot because the content view may have obvious changes.
- ActivityManagerWrapper.getInstance().invalidateHomeTaskSnapshot(this);
+ UI_HELPER_EXECUTOR.execute(
+ () -> ActivityManagerWrapper.getInstance().invalidateHomeTaskSnapshot(this));
}
@Override
@@ -203,8 +205,7 @@
@Override
protected void closeOpenViews(boolean animate) {
super.closeOpenViews(animate);
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index e808f8c..e02c0c3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -74,10 +74,10 @@
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.QuickstepOnboardingPrefs;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -175,8 +175,7 @@
@Override
protected void showAllAppsFromIntent(boolean alreadyOnHome) {
- ActivityManagerWrapper.getInstance().closeSystemWindows(
- CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
super.showAllAppsFromIntent(alreadyOnHome);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index d210bc6..5181a86 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -49,11 +49,11 @@
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.TouchController;
+import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.AssistantUtilities;
import com.android.quickstep.util.OverviewToHomeAnim;
import com.android.quickstep.views.RecentsView;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
/**
* Handles swiping up on the nav bar to go home from launcher, e.g. overview or all apps.
@@ -233,8 +233,7 @@
AbstractFloatingView.closeAllOpenViews(mLauncher);
// TODO: add to WW log
}
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
} else {
// Quickly return to the state we came from (we didn't move far).
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index b8c2030..d39b6f5 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -45,9 +45,9 @@
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.TaskUtils;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
/**
* Handles quick switching to a recent task from the home screen.
@@ -92,8 +92,7 @@
public void onDragStart(boolean start, float startDisplacement) {
super.onDragStart(start, startDisplacement);
mStartContainerType = LAUNCHER_STATE_BACKGROUND;
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 9f7871a..1badfbc 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -65,16 +65,14 @@
return;
}
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
MAIN_EXECUTOR.execute(new RecentsActivityCommand<>());
}
@BinderThread
public void onOverviewShown(boolean triggeredFromAltTab) {
if (triggeredFromAltTab) {
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
}
MAIN_EXECUTOR.execute(new ShowRecentsCommand(triggeredFromAltTab));
}
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index 04b488d..c9db153 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -16,6 +16,8 @@
package com.android.quickstep;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -27,6 +29,7 @@
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.util.List;
@@ -86,4 +89,12 @@
}
return false;
}
+
+ /**
+ * Requests that the system close any open system windows (including other SystemUI).
+ */
+ public static void closeSystemWindowsAsync(String reason) {
+ UI_HELPER_EXECUTOR.execute(
+ () -> ActivityManagerWrapper.getInstance().closeSystemWindows(reason));
+ }
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 82f489f..f2f9fb7 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -63,6 +63,7 @@
import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.RotationTouchHelper;
import com.android.quickstep.TaskAnimationManager;
+import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
@@ -362,8 +363,7 @@
mInputEventReceiver.setBatchingEnabled(true);
mActivityInterface.closeOverlay();
- ActivityManagerWrapper.getInstance().closeSystemWindows(
- CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
// Notify the handler that the gesture has actually started
mInteractionHandler.onGestureStarted(isLikelyToStartNewTask);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 32b1c58..f9c52f9 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -32,8 +32,8 @@
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
+import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.ActiveGestureLog;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
@@ -91,8 +91,7 @@
mTargetHandledTouch = true;
if (!mStartingInActivityBounds) {
mActivityInterface.closeOverlay();
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
ActiveGestureLog.INSTANCE.addLog("startQuickstep");
}
if (mInputMonitor != null) {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 264a182..f35eb1f 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -107,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.util.ComponentKey;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.OverScroller;
@@ -124,7 +123,6 @@
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskThumbnailCache;
-import com.android.quickstep.TaskUtils;
import com.android.quickstep.ViewUtils;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RecentsOrientedState;
@@ -1468,8 +1466,8 @@
private void removeTask(TaskView taskView, int index, EndState endState) {
if (taskView.getTask() != null) {
- ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id);
- ComponentKey compKey = TaskUtils.getLaunchComponentKeyForTask(taskView.getTask().key);
+ UI_HELPER_EXECUTOR.execute(() ->
+ ActivityManagerWrapper.getInstance().removeTask(taskView.getTask().key.id));
mActivity.getStatsLogManager().logger().withItemInfo(taskView.getItemInfo())
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
}
@@ -1618,7 +1616,8 @@
mPendingAnimation.addEndListener((endState) -> {
if (endState.isSuccess) {
// Remove all the task views now
- ActivityManagerWrapper.getInstance().removeAllRecentTasks();
+ UI_HELPER_EXECUTOR.execute(
+ ActivityManagerWrapper.getInstance()::removeAllRecentTasks);
removeTasksViewsAndClearAllButton();
startHome();
}
diff --git a/res/layout/search_result_hero_app.xml b/res/layout/search_result_hero_app.xml
deleted file mode 100644
index bd0e42b..0000000
--- a/res/layout/search_result_hero_app.xml
+++ /dev/null
@@ -1,74 +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.HeroSearchResultView
- 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">
-
- <FrameLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:layout_weight="1">
- <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"/>
- </FrameLayout>
-
- <com.android.launcher3.BubbleTextView
- android:id="@+id/shortcut_0"
- style="@style/BaseIcon"
- android:layout_width="@dimen/deep_shortcut_icon_size"
- android:layout_height="match_parent"
- android:gravity="start|center_vertical"
- android:textAlignment="center"
- launcher:iconDisplay="shortcut_popup"
- android:textSize="12sp"
- launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
- launcher:layoutHorizontal="false"/>
-
- <com.android.launcher3.BubbleTextView
- android:id="@+id/shortcut_1"
- style="@style/BaseIcon"
- android:layout_width="@dimen/deep_shortcut_icon_size"
- android:layout_height="match_parent"
- android:gravity="start|center_vertical"
- android:textAlignment="center"
- launcher:iconDisplay="shortcut_popup"
- android:textSize="12sp"
- launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
- launcher:layoutHorizontal="false"/>
-
-</com.android.launcher3.views.HeroSearchResultView>
\ No newline at end of file
diff --git a/res/layout/search_result_icon_row.xml b/res/layout/search_result_icon_row.xml
index ef3c8b2..b51896e 100644
--- a/res/layout/search_result_icon_row.xml
+++ b/res/layout/search_result_icon_row.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Projectza
+<?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.
@@ -14,18 +14,61 @@
-->
<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:orientation="horizontal"
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"
- >
+ android:padding="@dimen/dynamic_grid_edge_margin">
+
+ <com.android.launcher3.views.SearchResultIcon
+ android:layout_width="wrap_content"
+ android:id="@+id/icon"
+ launcher:iconDisplay="hero_app"
+ android:layout_height="wrap_content" />
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/dynamic_grid_edge_margin"
+ android:orientation="vertical"
+ android:layout_gravity="center_vertical">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:id="@id/title"
+ android:layout_height="wrap_content"
+ android:gravity="start|center_vertical"
+ android:textAlignment="viewStart"
+ android:textColor="?android:attr/textColorPrimary"
+ android:textSize="@dimen/settings_hero_title_size" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:id="@+id/desc"
+ android:textColor="?android:attr/textColorTertiary"
+ android:textSize="@dimen/settings_hero_subtitle_size"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+
+ <com.android.launcher3.BubbleTextView
+ android:id="@+id/shortcut_0"
+ style="@style/BaseIcon"
+ android:layout_width="@dimen/deep_shortcut_icon_size"
+ android:layout_height="match_parent"
+ android:gravity="start|center_vertical"
+ launcher:iconDisplay="shortcut_popup"
+ android:textSize="@dimen/settings_hero_subtitle_size"
+ launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
+ launcher:layoutHorizontal="false" />
+
+ <com.android.launcher3.BubbleTextView
+ android:id="@+id/shortcut_1"
+ style="@style/BaseIcon"
+ android:layout_width="@dimen/deep_shortcut_icon_size"
+ android:layout_height="match_parent"
+ launcher:iconDisplay="shortcut_popup"
+ android:textSize="@dimen/settings_hero_inline_button_size"
+ launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
+ launcher:layoutHorizontal="false" />
</com.android.launcher3.views.SearchResultIconRow>
\ No newline at end of file
diff --git a/res/layout/search_result_suggest.xml b/res/layout/search_result_suggest.xml
index 1d8c803..01e25d5 100644
--- a/res/layout/search_result_suggest.xml
+++ b/res/layout/search_result_suggest.xml
@@ -12,7 +12,7 @@
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"
+<com.android.launcher3.views.SearchResultSuggestion 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"
@@ -26,10 +26,9 @@
launcher:iconDisplay="hero_app"
android:drawableTint="?android:attr/textColorPrimary"
launcher:customIcon="@drawable/ic_allapps_search"
- launcher:iconSizeOverride="48dp"
+ launcher:iconSizeOverride="24dp"
launcher:matchTextInsetWithQuery="true"
launcher:layoutHorizontal="true"
- android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding"
- >
+ android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding">
-</com.android.launcher3.views.SearchResultIconRow>
\ No newline at end of file
+</com.android.launcher3.views.SearchResultSuggestion>
\ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index c3ad1eb..96c30b5 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
/* Copyright 2008, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
@@ -30,13 +29,13 @@
<attr name="isWorkspaceDarkText" format="boolean" />
<attr name="workspaceTextColor" format="color" />
<attr name="workspaceShadowColor" format="color" />
- <attr name="workspaceAmbientShadowColor" format="color"/>
+ <attr name="workspaceAmbientShadowColor" format="color" />
<attr name="workspaceKeyShadowColor" format="color" />
<attr name="workspaceStatusBarScrim" format="reference" />
<attr name="widgetsTheme" format="reference" />
<attr name="loadingIconColor" format="color" />
- <attr name="iconOnlyShortcutColor" format="color"/>
- <attr name="eduHalfSheetBGColor" format="color"/>
+ <attr name="iconOnlyShortcutColor" format="color" />
+ <attr name="eduHalfSheetBGColor" format="color" />
<attr name="folderDotColor" format="color" />
<attr name="folderFillColor" format="color" />
@@ -69,13 +68,12 @@
<attr name="folderDotColor" />
</declare-styleable>
- <declare-styleable name="SearchResultIconRow">
+ <declare-styleable name="SearchResultSuggestion">
<attr name="customIcon" format="reference" />
<attr name="matchTextInsetWithQuery" format="boolean" />
</declare-styleable>
-
<declare-styleable name="ShadowInfo">
<attr name="ambientShadowColor" format="color" />
<attr name="ambientShadowBlur" format="dimension" />
@@ -167,7 +165,7 @@
<attr name="android:src" />
<attr name="android:shadowColor" />
<attr name="android:elevation" />
- <attr name="darkTintColor" format="color"/>
+ <attr name="darkTintColor" format="color" />
</declare-styleable>
<declare-styleable name="RecyclerViewFastScroller">
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f59f02f..5387e1b 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -248,4 +248,9 @@
<!-- Onboarding bottomsheet related -->
<dimen name="bottom_sheet_edu_padding">24dp</dimen>
+ <!-- Search related -->
+ <dimen name="settings_hero_title_size">16sp</dimen>
+ <dimen name="settings_hero_subtitle_size">15sp</dimen>
+ <dimen name="settings_hero_inline_button_size">12sp</dimen>
+
</resources>
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
index a55c90d..8bf027d 100644
--- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
+++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
@@ -86,13 +86,12 @@
long mainProfileId = UserCache.INSTANCE.get(context)
.getSerialNumberForUser(myUserHandle());
String oldWidgetId = Integer.toString(oldWidgetIds[i]);
- int result = new ContentWriter(context, new ContentWriter.CommitParams(
- "appWidgetId=? and (restored & 1) = 1 and profileId=?",
- new String[] { oldWidgetId, Long.toString(mainProfileId) }))
+ final String where = "appWidgetId=? and (restored & 1) = 1 and profileId=?";
+ final String[] args = new String[] { oldWidgetId, Long.toString(mainProfileId) };
+ int result = new ContentWriter(context, new ContentWriter.CommitParams(where, args))
.put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
.put(LauncherSettings.Favorites.RESTORED, state)
.commit();
-
if (result == 0) {
Cursor cursor = cr.query(Favorites.CONTENT_URI,
new String[] {Favorites.APPWIDGET_ID},
@@ -106,6 +105,11 @@
cursor.close();
}
}
+ // attempt to update widget id in backup table as well
+ new ContentWriter(context, ContentWriter.CommitParams.backupCommitParams(where, args))
+ .put(LauncherSettings.Favorites.APPWIDGET_ID, newWidgetIds[i])
+ .put(LauncherSettings.Favorites.RESTORED, state)
+ .commit();
}
LauncherAppState app = LauncherAppState.getInstanceNoCreate();
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 1015a32..5cd6372 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -446,6 +446,7 @@
canvas.restoreToCount(count);
}
super.onDraw(canvas);
+ drawDotIfNecessary(canvas);
}
protected void drawFocusHighlight(Canvas canvas) {
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index d2758f5..fe423ed 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -121,6 +121,12 @@
+ LauncherProvider.AUTHORITY + "/" + TABLE_NAME);
/**
+ * The content:// style URL for "favorites_bakup" table
+ */
+ public static final Uri BACKUP_CONTENT_URI = Uri.parse("content://"
+ + LauncherProvider.AUTHORITY + "/" + BACKUP_TABLE_NAME);
+
+ /**
* The content:// style URL for "favorites_preview" table
*/
public static final Uri PREVIEW_CONTENT_URI = Uri.parse("content://"
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index f773191..7018f20 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -75,8 +75,6 @@
public static final int VIEW_TYPE_SEARCH_CORPUS_TITLE = 1 << 5;
- public static final int VIEW_TYPE_SEARCH_HERO_APP = 1 << 6;
-
public static final int VIEW_TYPE_SEARCH_ROW_WITH_BUTTON = 1 << 7;
public static final int VIEW_TYPE_SEARCH_ROW = 1 << 8;
@@ -178,7 +176,6 @@
boolean isCountedForAccessibility() {
return viewType == VIEW_TYPE_ICON
- || viewType == VIEW_TYPE_SEARCH_HERO_APP
|| viewType == VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
|| viewType == VIEW_TYPE_SEARCH_SLICE
|| viewType == VIEW_TYPE_SEARCH_ROW
@@ -411,9 +408,6 @@
case VIEW_TYPE_SEARCH_CORPUS_TITLE:
return new ViewHolder(
mLayoutInflater.inflate(R.layout.search_section_title, parent, false));
- case VIEW_TYPE_SEARCH_HERO_APP:
- return new ViewHolder(mLayoutInflater.inflate(
- R.layout.search_result_hero_app, parent, false));
case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.search_result_play_item, parent, false));
@@ -478,7 +472,6 @@
break;
case VIEW_TYPE_SEARCH_CORPUS_TITLE:
case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
- case VIEW_TYPE_SEARCH_HERO_APP:
case VIEW_TYPE_SEARCH_ROW:
case VIEW_TYPE_SEARCH_ICON:
case VIEW_TYPE_SEARCH_ICON_ROW:
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java b/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java
index eb68592..ad3f8df 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutTextView.java
@@ -132,6 +132,12 @@
mLoadingStatePlaceholder.draw(canvas);
}
+ @Override
+ protected void drawDotIfNecessary(Canvas canvas) {
+ // This view (with the text label to the side of the icon) is not designed for a dot to be
+ // drawn on top of it, so never draw one even if a notification for this shortcut exists.
+ }
+
private void showLoadingState(boolean loading) {
if (loading == mShowLoadingState) {
return;
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index d56391d..9b9cb0a 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -96,6 +96,8 @@
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
}
+ } else if (tag instanceof RemoteActionItemInfo) {
+ onClickRemoteAction(launcher, (RemoteActionItemInfo) tag);
}
}
diff --git a/src/com/android/launcher3/util/ContentWriter.java b/src/com/android/launcher3/util/ContentWriter.java
index 30c9ff9..ee64e98 100644
--- a/src/com/android/launcher3/util/ContentWriter.java
+++ b/src/com/android/launcher3/util/ContentWriter.java
@@ -113,14 +113,26 @@
public static final class CommitParams {
- final Uri mUri = LauncherSettings.Favorites.CONTENT_URI;
- String mWhere;
- String[] mSelectionArgs;
+ final Uri mUri;
+ final String mWhere;
+ final String[] mSelectionArgs;
public CommitParams(String where, String[] selectionArgs) {
+ this(LauncherSettings.Favorites.CONTENT_URI, where, selectionArgs);
+ }
+
+ private CommitParams(Uri uri, String where, String[] selectionArgs) {
+ mUri = uri;
mWhere = where;
mSelectionArgs = selectionArgs;
}
+ /**
+ * Creates commit params for backup table.
+ */
+ public static CommitParams backupCommitParams(String where, String[] selectionArgs) {
+ return new CommitParams(
+ LauncherSettings.Favorites.BACKUP_CONTENT_URI, where, selectionArgs);
+ }
}
}
diff --git a/src/com/android/launcher3/views/HeroSearchResultView.java b/src/com/android/launcher3/views/HeroSearchResultView.java
deleted file mode 100644
index a098df9..0000000
--- a/src/com/android/launcher3/views/HeroSearchResultView.java
+++ /dev/null
@@ -1,209 +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.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.pm.ShortcutInfo;
-import android.graphics.Point;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.DeviceProfile;
-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.AllAppsStore;
-import com.android.launcher3.allapps.search.AllAppsSearchBarController.SearchTargetHandler;
-import com.android.launcher3.allapps.search.SearchEventTracker;
-import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.dragndrop.DraggableView;
-import com.android.launcher3.graphics.DragPreviewProvider;
-import com.android.launcher3.model.data.AppInfo;
-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.shortcuts.ShortcutDragPreviewProvider;
-import com.android.launcher3.touch.ItemLongClickListener;
-import com.android.launcher3.util.ComponentKey;
-import com.android.systemui.plugins.shared.SearchTarget;
-import com.android.systemui.plugins.shared.SearchTargetEvent;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A view representing a high confidence app search result that includes shortcuts
- * TODO (sfufa@) consolidate this with SearchResultIconRow
- */
-public class HeroSearchResultView extends LinearLayout implements DragSource, SearchTargetHandler {
-
- public static final String TARGET_TYPE_HERO_APP = "hero_app";
-
- public static final int MAX_SHORTCUTS_COUNT = 2;
-
- private SearchTarget mSearchTarget;
- private BubbleTextView mBubbleTextView;
- private View mIconView;
- private BubbleTextView[] mDeepShortcutTextViews = new BubbleTextView[2];
-
-
- public HeroSearchResultView(Context context) {
- super(context);
- }
-
- public HeroSearchResultView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public HeroSearchResultView(Context context, 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);
- mBubbleTextView.setOnClickListener(view -> {
- handleSelection(SearchTargetEvent.SELECT);
- launcher.getItemOnClickListener().onClick(view);
- });
- mBubbleTextView.setOnLongClickListener(new HeroItemDragHandler(getContext(), this));
-
-
- mDeepShortcutTextViews[0] = findViewById(R.id.shortcut_0);
- mDeepShortcutTextViews[1] = findViewById(R.id.shortcut_1);
- for (BubbleTextView bubbleTextView : mDeepShortcutTextViews) {
- bubbleTextView.setLayoutParams(
- new LinearLayout.LayoutParams(grid.allAppsIconSizePx,
- grid.allAppsIconSizePx));
- bubbleTextView.setOnClickListener(view -> {
- WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
- SearchTargetEvent event = new SearchTargetEvent.Builder(mSearchTarget,
- SearchTargetEvent.CHILD_SELECT).setShortcutPosition(itemInfo.rank).build();
- SearchEventTracker.getInstance(getContext()).notifySearchTargetEvent(event);
- launcher.getItemOnClickListener().onClick(view);
- });
- }
- }
-
- @Override
- public void applySearchTarget(SearchTarget searchTarget) {
- mSearchTarget = searchTarget;
- AllAppsStore apps = Launcher.getLauncher(getContext()).getAppsView().getAppsStore();
- AppInfo appInfo = apps.getApp(new ComponentKey(searchTarget.getComponentName(),
- searchTarget.getUserHandle()));
- List<ShortcutInfo> infos = mSearchTarget.getShortcutInfos();
-
- ArrayList<Pair<ShortcutInfo, ItemInfoWithIcon>> shortcuts = new ArrayList<>();
- for (int i = 0; infos != null && i < infos.size() && i < MAX_SHORTCUTS_COUNT; i++) {
- ShortcutInfo shortcutInfo = infos.get(i);
- ItemInfoWithIcon si = new WorkspaceItemInfo(shortcutInfo, getContext());
- si.rank = i;
- shortcuts.add(new Pair<>(shortcutInfo, si));
- }
-
- mBubbleTextView.applyFromApplicationInfo(appInfo);
- mIconView.setBackground(mBubbleTextView.getIcon());
- mIconView.setTag(appInfo);
- LauncherAppState appState = LauncherAppState.getInstance(getContext());
- for (int i = 0; i < mDeepShortcutTextViews.length; i++) {
- BubbleTextView shortcutView = mDeepShortcutTextViews[i];
- mDeepShortcutTextViews[i].setVisibility(shortcuts.size() > i ? VISIBLE : GONE);
- if (i < shortcuts.size()) {
- Pair<ShortcutInfo, ItemInfoWithIcon> p = shortcuts.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));
- });
- }
- }
- SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
- }
-
- @Override
- public void onDropCompleted(View target, DropTarget.DragObject d, boolean success) {
- mBubbleTextView.setVisibility(VISIBLE);
- mBubbleTextView.setIconVisible(true);
- }
-
- private void setWillDrawIcon(boolean willDraw) {
- mIconView.setVisibility(willDraw ? View.VISIBLE : View.INVISIBLE);
- }
-
- /**
- * Drag and drop handler for popup items in Launcher activity
- */
- public static class HeroItemDragHandler implements OnLongClickListener {
- private final Launcher mLauncher;
- private final HeroSearchResultView mContainer;
-
- HeroItemDragHandler(Context context, HeroSearchResultView container) {
- mLauncher = Launcher.getLauncher(context);
- mContainer = container;
- }
-
- @Override
- public boolean onLongClick(View v) {
- if (!ItemLongClickListener.canStartDrag(mLauncher)) return false;
- mContainer.setWillDrawIcon(false);
-
- DraggableView draggableView = DraggableView.ofType(DraggableView.DRAGGABLE_ICON);
- WorkspaceItemInfo itemInfo = new WorkspaceItemInfo((AppInfo) v.getTag());
- itemInfo.container = CONTAINER_ALL_APPS;
- DragPreviewProvider previewProvider = new ShortcutDragPreviewProvider(
- mContainer.mIconView, new Point());
- mLauncher.getWorkspace().beginDragShared(mContainer.mBubbleTextView,
- draggableView, mContainer, itemInfo, previewProvider, new DragOptions());
-
- SearchTargetEvent event = new SearchTargetEvent.Builder(mContainer.mSearchTarget,
- SearchTargetEvent.LONG_PRESS).build();
- SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(event);
- return false;
- }
- }
-
- @Override
- public void handleSelection(int eventType) {
- ItemInfo itemInfo = (ItemInfo) mBubbleTextView.getTag();
- if (itemInfo == null) return;
- Launcher launcher = Launcher.getLauncher(getContext());
- launcher.startActivitySafely(this, itemInfo.getIntent(), itemInfo);
-
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
- }
-}
diff --git a/src/com/android/launcher3/views/SearchResultIcon.java b/src/com/android/launcher3/views/SearchResultIcon.java
index ea06d5b..0851b54 100644
--- a/src/com/android/launcher3/views/SearchResultIcon.java
+++ b/src/com/android/launcher3/views/SearchResultIcon.java
@@ -15,16 +15,35 @@
*/
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.ComponentName;
import android.content.Context;
+import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.UserHandle;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.UiThread;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
import com.android.launcher3.allapps.search.SearchEventTracker;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.AppInfo;
+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.ItemLongClickListener;
import com.android.launcher3.util.ComponentKey;
import com.android.systemui.plugins.shared.SearchTarget;
@@ -39,6 +58,17 @@
public static final String TARGET_TYPE_APP = "app";
+ public static final String TARGET_TYPE_HERO_APP = "hero_app";
+ public static final String TARGET_TYPE_SHORTCUT = "shortcut";
+ public static final String TARGET_TYPE_REMOTE_ACTION = "remote_action";
+ public static final String TARGET_TYPE_SUGGEST = "suggest";
+
+ public static final String REMOTE_ACTION_SHOULD_START = "should_start_for_result";
+ public static final String REMOTE_ACTION_TOKEN = "action_token";
+
+
+ private static final String[] LONG_PRESS_SUPPORTED_TYPES =
+ new String[]{TARGET_TYPE_APP, TARGET_TYPE_SHORTCUT, TARGET_TYPE_HERO_APP};
private final Launcher mLauncher;
@@ -64,26 +94,96 @@
setOnFocusChangeListener(mLauncher.getFocusHandler());
setOnClickListener(this);
setOnLongClickListener(this);
- getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
+ setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ mLauncher.getDeviceProfile().allAppsCellHeightPx));
}
@Override
public void applySearchTarget(SearchTarget searchTarget) {
mSearchTarget = searchTarget;
- AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
SearchEventTracker.getInstance(getContext()).registerWeakHandler(mSearchTarget, this);
- if (searchTarget.getItemType().equals(TARGET_TYPE_APP)) {
- AppInfo appInfo = appsStore.getApp(new ComponentKey(searchTarget.getComponentName(),
- searchTarget.getUserHandle()));
- applyFromApplicationInfo(appInfo);
+ switch (searchTarget.getItemType()) {
+ case TARGET_TYPE_APP:
+ case TARGET_TYPE_HERO_APP:
+ prepareUsingApp(searchTarget.getComponentName(), searchTarget.getUserHandle());
+ break;
+ case TARGET_TYPE_SHORTCUT:
+ prepareUsingShortcutInfo(searchTarget.getShortcutInfos().get(0));
+ break;
+ case TARGET_TYPE_REMOTE_ACTION:
+ case TARGET_TYPE_SUGGEST:
+ prepareUsingRemoteAction(searchTarget.getRemoteAction(),
+ searchTarget.getExtras().getString(REMOTE_ACTION_TOKEN),
+ searchTarget.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START),
+ searchTarget.getItemType().equals(TARGET_TYPE_REMOTE_ACTION));
+ break;
}
}
+ private void prepareUsingApp(ComponentName componentName, UserHandle userHandle) {
+ AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
+ AppInfo appInfo = appsStore.getApp(new ComponentKey(componentName, userHandle));
+ applyFromApplicationInfo(appInfo);
+ }
+
+
+ private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) {
+ WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(shortcutInfo, getContext());
+ applyFromWorkspaceItem(workspaceItemInfo);
+ LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
+ MODEL_EXECUTOR.execute(() -> {
+ launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, shortcutInfo);
+ reapplyItemInfoAsync(workspaceItemInfo);
+ });
+ }
+
+ private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start,
+ boolean useIconToBadge) {
+ RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
+
+ applyFromRemoteActionInfo(itemInfo);
+ if (!loadIconFromResource()) {
+ 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());
+ BitmapInfo bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
+ Build.VERSION.SDK_INT);
+
+ if (useIconToBadge) {
+ BitmapInfo placeholder = li.createIconBitmap(
+ itemInfo.getRemoteAction().getTitle().toString().substring(0, 1),
+ bitmap.color);
+ itemInfo.bitmap = li.badgeBitmap(placeholder.icon, bitmap);
+ } else {
+ itemInfo.bitmap = bitmap;
+ }
+ reapplyItemInfoAsync(itemInfo);
+ }
+ });
+ }
+ }
+
+ @UiThread
+ void reapplyItemInfoAsync(ItemInfoWithIcon itemInfoWithIcon) {
+ MAIN_EXECUTOR.post(() -> reapplyItemInfo(itemInfoWithIcon));
+ }
+
+
@Override
public void handleSelection(int eventType) {
mLauncher.getItemOnClickListener().onClick(this);
- SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(
- new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+ reportEvent(eventType);
+ }
+
+ private void reportEvent(int eventType) {
+ SearchTargetEvent.Builder b = new SearchTargetEvent.Builder(mSearchTarget, eventType);
+ if (mSearchTarget.getItemType().equals(TARGET_TYPE_SHORTCUT)) {
+ b.setShortcutPosition(0);
+ }
+ SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(b.build());
+
}
@Override
@@ -93,8 +193,22 @@
@Override
public boolean onLongClick(View view) {
- SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(
- new SearchTargetEvent.Builder(mSearchTarget, SearchTargetEvent.LONG_PRESS).build());
+ if (!supportsLongPress(mSearchTarget.getItemType())) {
+ return false;
+ }
+ reportEvent(SearchTargetEvent.LONG_PRESS);
return ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(view);
+
+ }
+
+ private boolean supportsLongPress(String type) {
+ for (String t : LONG_PRESS_SUPPORTED_TYPES) {
+ if (t.equals(type)) return true;
+ }
+ return false;
+ }
+
+ protected boolean loadIconFromResource() {
+ return false;
}
}
diff --git a/src/com/android/launcher3/views/SearchResultIconRow.java b/src/com/android/launcher3/views/SearchResultIconRow.java
index bdbe890..03332c1 100644
--- a/src/com/android/launcher3/views/SearchResultIconRow.java
+++ b/src/com/android/launcher3/views/SearchResultIconRow.java
@@ -17,188 +17,173 @@
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.ComponentName;
import android.content.Context;
import android.content.pm.ShortcutInfo;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
+import android.os.UserHandle;
import android.util.AttributeSet;
-import android.widget.EditText;
+import android.util.Pair;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
import com.android.launcher3.allapps.search.SearchEventTracker;
-import com.android.launcher3.icons.BitmapInfo;
-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.PackageItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.util.Themes;
import com.android.systemui.plugins.shared.SearchTarget;
import com.android.systemui.plugins.shared.SearchTargetEvent;
+import java.util.ArrayList;
+import java.util.List;
+
/**
- * A view representing a stand alone shortcut search result
+ * A full width representation of {@link SearchResultIcon} with a secondary label and inline
+ * shortcuts
*/
-public class SearchResultIconRow extends DoubleShadowBubbleTextView implements
- AllAppsSearchBarController.SearchTargetHandler {
+public class SearchResultIconRow extends LinearLayout implements
+ AllAppsSearchBarController.SearchTargetHandler, View.OnClickListener,
+ View.OnLongClickListener {
+ public static final int MAX_SHORTCUTS_COUNT = 2;
- public static final String TARGET_TYPE_REMOTE_ACTION = "remote_action";
- public static final String TARGET_TYPE_SUGGEST = "suggest";
- public static final String TARGET_TYPE_SHORTCUT = "shortcut";
-
-
- public static final String REMOTE_ACTION_SHOULD_START = "should_start_for_result";
- public static final String REMOTE_ACTION_TOKEN = "action_token";
-
- private final boolean mMatchesInset;
+ private final Launcher mLauncher;
+ private final LauncherAppState mLauncherAppState;
+ private SearchResultIcon mResultIcon;
+ private TextView mTitleView;
+ private TextView mDescriptionView;
+ private BubbleTextView[] mShortcutViews = new BubbleTextView[2];
private SearchTarget mSearchTarget;
+ private PackageItemInfo mProviderInfo;
- @Nullable private Drawable mCustomIcon;
- public SearchResultIconRow(@NonNull Context context) {
+ public SearchResultIconRow(Context context) {
this(context, null, 0);
}
- public SearchResultIconRow(@NonNull Context context,
+ public SearchResultIconRow(Context context,
@Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
- public SearchResultIconRow(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
+ public SearchResultIconRow(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- TypedArray a = context.obtainStyledAttributes(attrs,
- R.styleable.SearchResultIconRow, defStyleAttr, 0);
- mMatchesInset = a.getBoolean(R.styleable.SearchResultIconRow_matchTextInsetWithQuery,
- false);
-
- int customIconResId = a.getResourceId(R.styleable.SearchResultIconRow_customIcon, 0);
-
- if (customIconResId != 0) {
- mCustomIcon = Launcher.getLauncher(context).getDrawable(customIconResId);
- }
-
- a.recycle();
- }
-
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- Launcher launcher = Launcher.getLauncher(getContext());
- if (mMatchesInset && launcher.getAppsView() != null && getParent() != null) {
- EditText editText = launcher.getAppsView().getSearchUiManager().getEditText();
- if (editText != null) {
- int counterOffset = getIconSize() + getCompoundDrawablePadding() / 2;
- setPadding(editText.getLeft() - counterOffset, getPaddingTop(),
- getPaddingRight(), getPaddingBottom());
- }
- }
+ mLauncher = Launcher.getLauncher(getContext());
+ mLauncherAppState = LauncherAppState.getInstance(getContext());
}
@Override
- protected void drawFocusHighlight(Canvas canvas) {
- mHighlightPaint.setColor(mHighlightColor);
- float r = Themes.getDialogCornerRadius(getContext());
- canvas.drawRoundRect(0, 0, getWidth(), getHeight(), r, r, mHighlightPaint);
- }
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ int iconSize = mLauncher.getDeviceProfile().allAppsIconSizePx;
+ mResultIcon = findViewById(R.id.icon);
+ mTitleView = findViewById(R.id.title);
+ mDescriptionView = findViewById(R.id.desc);
+ mShortcutViews[0] = findViewById(R.id.shortcut_0);
+ mShortcutViews[1] = findViewById(R.id.shortcut_1);
+ mResultIcon.getLayoutParams().height = iconSize;
+ mResultIcon.getLayoutParams().width = iconSize;
+ for (BubbleTextView bubbleTextView : mShortcutViews) {
+ ViewGroup.LayoutParams lp = bubbleTextView.getLayoutParams();
+ lp.width = iconSize;
+ bubbleTextView.setOnClickListener(view -> {
+ WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
+ SearchTargetEvent event = new SearchTargetEvent.Builder(mSearchTarget,
+ SearchTargetEvent.CHILD_SELECT).setShortcutPosition(itemInfo.rank).build();
+ SearchEventTracker.getInstance(getContext()).notifySearchTargetEvent(event);
+ mLauncher.getItemOnClickListener().onClick(view);
+ });
+ }
+ setOnClickListener(this);
+ setOnLongClickListener(this);
+ }
@Override
public void applySearchTarget(SearchTarget searchTarget) {
mSearchTarget = searchTarget;
- String type = searchTarget.getItemType();
- if (type.equals(TARGET_TYPE_REMOTE_ACTION) || type.equals(TARGET_TYPE_SUGGEST)) {
- prepareUsingRemoteAction(searchTarget.getRemoteAction(),
- searchTarget.getExtras().getString(REMOTE_ACTION_TOKEN),
- searchTarget.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START),
- type.equals(TARGET_TYPE_REMOTE_ACTION));
+ mResultIcon.applySearchTarget(searchTarget);
+ mResultIcon.setTextVisibility(false);
+ mTitleView.setText(mResultIcon.getText());
+ String itemType = searchTarget.getItemType();
+ boolean showDesc = itemType.equals(SearchResultIcon.TARGET_TYPE_SHORTCUT);
+ mDescriptionView.setVisibility(showDesc ? VISIBLE : GONE);
- } else if (type.equals(TARGET_TYPE_SHORTCUT)) {
- prepareUsingShortcutInfo(searchTarget.getShortcutInfos().get(0));
+ if (itemType.equals(SearchResultIcon.TARGET_TYPE_SHORTCUT)) {
+ ShortcutInfo shortcutInfo = searchTarget.getShortcutInfos().get(0);
+ setProviderDetails(new ComponentName(shortcutInfo.getPackage(), ""),
+ shortcutInfo.getUserHandle());
+ } else if (itemType.equals(SearchResultIcon.TARGET_TYPE_HERO_APP)) {
+ showInlineShortcuts(mSearchTarget.getShortcutInfos());
}
- setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
- SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
+ if (!itemType.equals(SearchResultIcon.TARGET_TYPE_HERO_APP)) {
+ showInlineShortcuts(new ArrayList<>());
+ }
}
- private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) {
- WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(shortcutInfo, getContext());
- applyFromWorkspaceItem(workspaceItemInfo);
- LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
- if (!loadIconFromResource()) {
- MODEL_EXECUTOR.execute(() -> {
- launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, shortcutInfo);
- reapplyItemInfoAsync(workspaceItemInfo);
+ private void showInlineShortcuts(List<ShortcutInfo> infos) {
+ if (infos == null) return;
+ ArrayList<Pair<ShortcutInfo, ItemInfoWithIcon>> shortcuts = new ArrayList<>();
+ for (int i = 0; infos != null && i < infos.size() && i < MAX_SHORTCUTS_COUNT; i++) {
+ ShortcutInfo shortcutInfo = infos.get(i);
+ ItemInfoWithIcon si = new WorkspaceItemInfo(shortcutInfo, getContext());
+ si.rank = i;
+ shortcuts.add(new Pair<>(shortcutInfo, si));
+ }
+
+ for (int i = 0; i < mShortcutViews.length; i++) {
+ BubbleTextView shortcutView = mShortcutViews[i];
+ mShortcutViews[i].setVisibility(shortcuts.size() > i ? VISIBLE : GONE);
+ if (i < shortcuts.size()) {
+ Pair<ShortcutInfo, ItemInfoWithIcon> p = shortcuts.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
+ mLauncherAppState.getIconCache().getUnbadgedShortcutIcon(p.second, p.first);
+ MAIN_EXECUTOR.post(() -> shortcutView.reapplyItemInfo(p.second));
+ });
+ }
+ }
+ }
+
+
+ private void setProviderDetails(ComponentName componentName, UserHandle userHandle) {
+ PackageItemInfo packageItemInfo = new PackageItemInfo(componentName.getPackageName());
+ if (mProviderInfo == packageItemInfo) return;
+ MODEL_EXECUTOR.post(() -> {
+ packageItemInfo.user = userHandle;
+ mLauncherAppState.getIconCache().getTitleAndIconForApp(packageItemInfo, true);
+ MAIN_EXECUTOR.post(() -> {
+ mDescriptionView.setText(packageItemInfo.title);
+ mProviderInfo = packageItemInfo;
});
- }
- }
-
- private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start,
- boolean useIconToBadge) {
- RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
-
- applyFromRemoteActionInfo(itemInfo);
- if (itemInfo.isEscapeHatch() || !loadIconFromResource()) {
- 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());
- BitmapInfo bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
- Build.VERSION.SDK_INT);
-
- if (useIconToBadge) {
- BitmapInfo placeholder = li.createIconBitmap(
- itemInfo.getRemoteAction().getTitle().toString().substring(0, 1),
- bitmap.color);
- itemInfo.bitmap = li.badgeBitmap(placeholder.icon, bitmap);
- } else {
- itemInfo.bitmap = bitmap;
- }
- reapplyItemInfoAsync(itemInfo);
- }
- });
- }
-
- }
-
- private boolean loadIconFromResource() {
- if (mCustomIcon == null) return false;
- setIcon(mCustomIcon);
- return true;
- }
-
- void reapplyItemInfoAsync(ItemInfoWithIcon itemInfoWithIcon) {
- MAIN_EXECUTOR.post(() -> {
- reapplyItemInfo(itemInfoWithIcon);
- mCustomIcon = getIcon();
});
}
@Override
public void handleSelection(int eventType) {
- ItemInfo itemInfo = (ItemInfo) getTag();
- Launcher launcher = Launcher.getLauncher(getContext());
- if (itemInfo instanceof WorkspaceItemInfo) {
- ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) itemInfo, launcher);
- } else {
- ItemClickHandler.onClickRemoteAction(launcher, (RemoteActionItemInfo) itemInfo);
- }
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEvent.Builder(mSearchTarget, eventType).build());
+ mResultIcon.handleSelection(eventType);
+ }
+
+ @Override
+ public void onClick(View view) {
+ mResultIcon.performClick();
+ }
+
+ @Override
+ public boolean onLongClick(View view) {
+ mResultIcon.performLongClick();
+ return false;
}
}
diff --git a/src/com/android/launcher3/views/SearchResultSuggestion.java b/src/com/android/launcher3/views/SearchResultSuggestion.java
new file mode 100644
index 0000000..ab94bf0
--- /dev/null
+++ b/src/com/android/launcher3/views/SearchResultSuggestion.java
@@ -0,0 +1,62 @@
+/*
+ * 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.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.ViewGroup;
+
+import com.android.launcher3.R;
+
+/**
+ * {@link SearchResultIconRow} with custom drawable resource
+ */
+public class SearchResultSuggestion extends SearchResultIcon {
+
+ private final Drawable mCustomIcon;
+
+ public SearchResultSuggestion(Context context) {
+ this(context, null, 0);
+ }
+
+ public SearchResultSuggestion(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SearchResultSuggestion(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.SearchResultSuggestion, defStyle, 0);
+ mCustomIcon = a.getDrawable(R.styleable.SearchResultSuggestion_customIcon);
+ a.recycle();
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ ViewGroup.LayoutParams lp = getLayoutParams();
+ lp.height = BaseDragLayer.LayoutParams.WRAP_CONTENT;
+ }
+
+ @Override
+ protected boolean loadIconFromResource() {
+ setIcon(mCustomIcon);
+ return true;
+ }
+}
diff --git a/src/com/android/launcher3/views/ThumbnailSearchResultView.java b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
index e929d7f..f213f22 100644
--- a/src/com/android/launcher3/views/ThumbnailSearchResultView.java
+++ b/src/com/android/launcher3/views/ThumbnailSearchResultView.java
@@ -15,8 +15,9 @@
*/
package com.android.launcher3.views;
-import static com.android.launcher3.views.SearchResultIconRow.REMOTE_ACTION_SHOULD_START;
-import static com.android.launcher3.views.SearchResultIconRow.REMOTE_ACTION_TOKEN;
+
+import static com.android.launcher3.views.SearchResultIcon.REMOTE_ACTION_SHOULD_START;
+import static com.android.launcher3.views.SearchResultIcon.REMOTE_ACTION_TOKEN;
import android.content.Context;
import android.content.Intent;
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index d3fc89e..e118481 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -234,11 +234,25 @@
return mDevice;
}
+ private boolean hasSystemUiObject(String resId) {
+ return mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, resId));
+ }
+
@Before
public void setUp() throws Exception {
- Assert.assertTrue("Keyguard is visible",
+ Log.d(TAG, "Before disabling battery defender");
+ mDevice.executeShellCommand("setprop vendor.battery.defender.disable 1");
+ Log.d(TAG, "Before enabling stay awake");
+ mDevice.executeShellCommand("settings put global stay_on_while_plugged_in 3");
+ for (int i = 0; i < 10 && hasSystemUiObject("keyguard_status_view"); ++i) {
+ Log.d(TAG, "Before unlocking the phone");
+ mDevice.executeShellCommand("input keyevent 82");
+ mDevice.waitForIdle();
+ }
+ Assert.assertTrue("Keyguard still visible",
mDevice.wait(
Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000));
+ Log.d(TAG, "Keyguard is not visible");
final String launcherPackageName = mDevice.getLauncherPackageName();
try {
diff --git a/tests/src/com/android/launcher3/ui/WorkTabTest.java b/tests/src/com/android/launcher3/ui/WorkTabTest.java
index 8d594de..df0770d 100644
--- a/tests/src/com/android/launcher3/ui/WorkTabTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkTabTest.java
@@ -65,12 +65,13 @@
String[] tokens = output.split("\\s+");
mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
-
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "Created new user uid" + mProfileUserId);
mDevice.executeShellCommand("am start-user " + mProfileUserId);
}
@After
public void removeWorkProfile() throws Exception {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "(teardown) removing uid" + mProfileUserId);
mDevice.executeShellCommand("pm remove-user " + mProfileUserId);
}