Merge " Introduce feature education for AllApps Search"
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 8dab915..d95cc01 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -32,6 +32,7 @@
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<uses-permission android:name="${packageName}.permission.HOTSEAT_EDU" />
+ <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application android:backupAgent="com.android.launcher3.LauncherBackupAgent"
android:fullBackupOnly="true"
diff --git a/quickstep/res/layout/search_result_icon_row.xml b/quickstep/res/layout/search_result_icon_row.xml
index 1393b87..2119fc3 100644
--- a/quickstep/res/layout/search_result_icon_row.xml
+++ b/quickstep/res/layout/search_result_icon_row.xml
@@ -45,14 +45,14 @@
<TextView
android:layout_width="wrap_content"
- android:id="@+id/desc"
+ android:id="@+id/subtitle"
android:maxLines="1"
android:textColor="?android:attr/textColorTertiary"
android:textSize="@dimen/search_hero_subtitle_size"
android:layout_height="wrap_content" />
</LinearLayout>
- <com.android.launcher3.BubbleTextView
+ <com.android.launcher3.search.SearchResultIcon
android:id="@+id/shortcut_0"
style="@style/BaseIcon"
android:layout_width="@dimen/deep_shortcut_icon_size"
@@ -63,7 +63,7 @@
launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
launcher:layoutHorizontal="false" />
- <com.android.launcher3.BubbleTextView
+ <com.android.launcher3.search.SearchResultIcon
android:id="@+id/shortcut_1"
style="@style/BaseIcon"
android:layout_width="@dimen/deep_shortcut_icon_size"
@@ -72,5 +72,4 @@
android:textSize="@dimen/search_hero_inline_button_size"
launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
launcher:layoutHorizontal="false" />
-
</com.android.launcher3.search.SearchResultIconRow>
\ No newline at end of file
diff --git a/quickstep/res/layout/search_result_play_item.xml b/quickstep/res/layout/search_result_play_item.xml
deleted file mode 100644
index ecd67b1..0000000
--- a/quickstep/res/layout/search_result_play_item.xml
+++ /dev/null
@@ -1,79 +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.search.SearchResultPlayItem xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:padding="4dp"
- android:orientation="horizontal">
- <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" />
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_gravity="start|center_vertical"
- android:layout_weight="1"
- android:orientation="vertical"
- android:paddingTop="4dp"
- android:paddingBottom="4dp"
- android:paddingStart="8dp"
- android:paddingEnd="8dp">
-
- <TextView
- android:id="@+id/title_view"
- style="@style/TextHeadline"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLines="1"
- android:ellipsize="end"
- android:textAlignment="viewStart"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="16sp" />
-
- <TextView
- android:id="@+id/detail_0"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="?android:attr/textColorPrimary" />
-
- <TextView
- android:id="@+id/detail_1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="?android:attr/textColorPrimary"
- android:visibility="gone" />
-
- <TextView
- android:id="@+id/detail_2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="?android:attr/textColorPrimary"
- android:visibility="gone" />
- </LinearLayout>
- <Button
- android:id="@+id/try_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="start|center_vertical"
- android:text="@string/search_action_try_now">
- </Button>
-
-
-</com.android.launcher3.search.SearchResultPlayItem>
diff --git a/quickstep/res/layout/search_result_settings_row.xml b/quickstep/res/layout/search_result_settings_row.xml
deleted file mode 100644
index 33c9592..0000000
--- a/quickstep/res/layout/search_result_settings_row.xml
+++ /dev/null
@@ -1,60 +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.search.SearchSettingsRowView 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="horizontal"
- android:gravity="center_vertical"
- android:padding="@dimen/dynamic_grid_cell_padding_x"
- android:textColor="?android:attr/textColorPrimary">
-
- <View
- android:layout_width="@dimen/search_settings_icon_size"
- android:src="@drawable/ic_setting"
- android:id="@+id/icon"
- android:layout_height="@dimen/search_settings_icon_size" />
-
- <LinearLayout
- android:layout_width="0dp"
- android:orientation="vertical"
- android:paddingRight="@dimen/dynamic_grid_cell_padding_x"
- android:paddingLeft="@dimen/dynamic_grid_cell_padding_x"
- android:layout_height="wrap_content"
- android:layout_weight="1">
-
-
- <TextView
- android:id="@+id/title"
- style="@style/TextTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/search_line_spacing"
- android:maxLines="1"
- android:textColor="?android:attr/textColorPrimary"
- android:textSize="@dimen/search_hero_title_size" />
-
- <TextView
- android:id="@+id/breadcrumbs"
- style="@style/TextTitle"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:textColor="?android:attr/textColorSecondary"
- android:textSize="@dimen/search_hero_subtitle_size" />
- </LinearLayout>
-</com.android.launcher3.search.SearchSettingsRowView>
\ No newline at end of file
diff --git a/quickstep/res/layout/search_result_slice.xml b/quickstep/res/layout/search_result_slice.xml
index f7dcfce..4f884ff 100644
--- a/quickstep/res/layout/search_result_slice.xml
+++ b/quickstep/res/layout/search_result_slice.xml
@@ -12,21 +12,21 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.search.SearchResultSettingsSlice xmlns:android="http://schemas.android.com/apk/res/android"
- android:paddingHorizontal="@dimen/dynamic_grid_cell_padding_x"
+<com.android.launcher3.search.SearchResultIconSlice xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:padding="@dimen/dynamic_grid_edge_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="wrap_content"
- android:paddingTop="@dimen/search_settings_icon_vertical_offset"
android:layout_height="wrap_content">
- <View
- android:layout_width="@dimen/search_settings_icon_size"
- android:src="@drawable/ic_setting"
+ <com.android.launcher3.search.SearchResultIcon
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:id="@+id/icon"
- android:layout_height="@dimen/search_settings_icon_size" />
+ launcher:iconDisplay="hero_app" />
</FrameLayout>
<androidx.slice.widget.SliceView
@@ -36,5 +36,5 @@
android:layout_marginStart="@dimen/dynamic_grid_cell_padding_x"
android:layout_width="0dp" />
-</com.android.launcher3.search.SearchResultSettingsSlice>
+</com.android.launcher3.search.SearchResultIconSlice>
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
new file mode 100644
index 0000000..5f1046d
--- /dev/null
+++ b/quickstep/res/layout/taskbar.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.taskbar.TaskbarContainerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/taskbar_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <com.android.launcher3.taskbar.TaskbarView
+ android:id="@+id/taskbar_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@color/taskbar_background"/>
+
+</com.android.launcher3.taskbar.TaskbarContainerView>
\ No newline at end of file
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 449fe10..3bc8ddc 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -24,4 +24,7 @@
<color name="all_apps_label_text_dark">#61FFFFFF</color>
<color name="all_apps_prediction_row_separator">#3c000000</color>
<color name="all_apps_prediction_row_separator_dark">#3cffffff</color>
+
+ <!-- Taskbar -->
+ <color name="taskbar_background">#101010</color>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 551f7b0..4272f50 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -119,4 +119,7 @@
<!-- Minimum distance to swipe to trigger accessibility gesture -->
<dimen name="accessibility_gesture_min_swipe_distance">80dp</dimen>
+
+ <!-- Taskbar -->
+ <dimen name="taskbar_size">48dp</dimen>
</resources>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 3643d6d..2518f42 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -19,6 +19,7 @@
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.DisplayController.DisplayHolder.CHANGE_SIZE;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
@@ -29,8 +30,11 @@
import android.content.IntentSender;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.view.LayoutInflater;
import android.view.View;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.popup.SystemShortcut;
@@ -39,7 +43,10 @@
import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateHandler;
+import com.android.launcher3.taskbar.TaskbarContainerView;
+import com.android.launcher3.taskbar.TaskbarController;
import com.android.launcher3.uioverrides.RecentsViewStateController;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SysUINavigationMode;
@@ -53,7 +60,6 @@
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;
@@ -75,6 +81,8 @@
private OverviewActionsView mActionsView;
+ private @Nullable TaskbarController mTaskbarController;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -86,6 +94,11 @@
@Override
public void onDestroy() {
SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
+
+ if (mTaskbarController != null) {
+ mTaskbarController.cleanup();
+ }
+
super.onDestroy();
}
@@ -190,6 +203,29 @@
mActionsView = findViewById(R.id.overview_actions_view);
((RecentsView) getOverviewPanel()).init(mActionsView);
mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
+
+ addTaskbarIfNecessary();
+ }
+
+ @Override
+ public void onDisplayInfoChanged(DisplayController.Info info, int flags) {
+ super.onDisplayInfoChanged(info, flags);
+ if ((flags & CHANGE_SIZE) != 0) {
+ addTaskbarIfNecessary();
+ }
+ }
+
+ private void addTaskbarIfNecessary() {
+ if (mTaskbarController != null) {
+ mTaskbarController.cleanup();
+ mTaskbarController = null;
+ }
+ if (FeatureFlags.ENABLE_TASKBAR.get() && mDeviceProfile.isTablet) {
+ TaskbarContainerView taskbarContainer = (TaskbarContainerView) LayoutInflater.from(this)
+ .inflate(R.layout.taskbar, null, false);
+ mTaskbarController = new TaskbarController(this, taskbarContainer);
+ mTaskbarController.init();
+ }
}
public <T extends OverviewActionsView> T getActionsView() {
diff --git a/quickstep/src/com/android/launcher3/search/DeviceSearchAdapterProvider.java b/quickstep/src/com/android/launcher3/search/DeviceSearchAdapterProvider.java
index 3343cf5..834a624 100644
--- a/quickstep/src/com/android/launcher3/search/DeviceSearchAdapterProvider.java
+++ b/quickstep/src/com/android/launcher3/search/DeviceSearchAdapterProvider.java
@@ -21,17 +21,16 @@
import android.app.search.SearchTarget;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
import com.android.app.search.LayoutType;
-import com.android.app.search.ResultType;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.config.FeatureFlags;
-import com.android.systemui.plugins.shared.SearchTargetLegacy;
/**
* Provides views for on-device search results
@@ -39,14 +38,12 @@
public class DeviceSearchAdapterProvider extends SearchAdapterProvider {
public static final int VIEW_TYPE_SEARCH_CORPUS_TITLE = 1 << 5;
- public static final int VIEW_TYPE_SEARCH_ROW_WITH_BUTTON = 1 << 7;
- public static final int VIEW_TYPE_SEARCH_ROW = 1 << 8;
- public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 9;
- public static final int VIEW_TYPE_SEARCH_ICON_ROW = 1 << 10;
+ public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 7;
+ public static final int VIEW_TYPE_SEARCH_ICON = (1 << 8) | VIEW_TYPE_ICON;
+ public static final int VIEW_TYPE_SEARCH_ICON_ROW = (1 << 9);
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;
- public static final int VIEW_TYPE_SEARCH_ICON = (1 << 14) | VIEW_TYPE_ICON;
public static final int VIEW_TYPE_SEARCH_WIDGET_LIVE = 1 << 15;
public static final int VIEW_TYPE_SEARCH_WIDGET_PREVIEW = 1 << 16;
@@ -58,13 +55,10 @@
super(launcher);
mAppsView = appsView;
- mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ICON, R.layout.search_result_icon);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_CORPUS_TITLE, R.layout.search_section_title);
- mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ROW_WITH_BUTTON,
- R.layout.search_result_play_item);
- mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ROW, R.layout.search_result_settings_row);
- mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_SLICE, R.layout.search_result_slice);
+ mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ICON, R.layout.search_result_icon);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_ICON_ROW, R.layout.search_result_icon_row);
+ mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_SLICE, R.layout.search_result_slice);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_PEOPLE, R.layout.search_result_people_item);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_THUMBNAIL, R.layout.search_result_thumbnail);
mViewTypeToLayoutMap.put(VIEW_TYPE_SEARCH_SUGGEST, R.layout.search_result_suggest);
@@ -110,12 +104,9 @@
@Override
- public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem) {
- if (focusedItem instanceof SearchTargetHandler) {
- SearchTargetLegacy searchTarget = ((SearchAdapterItem) focusedItem)
- .getSearchTargetLegacy();
- SearchEventTracker.INSTANCE.get(mLauncher).quickSelect(searchTarget);
- return true;
+ public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem adapterItem, View view) {
+ if (view instanceof SearchTargetHandler) {
+ return ((SearchTargetHandler) view).quickSelect();
}
return false;
}
@@ -125,25 +116,20 @@
* Returns -1 if viewType is not found
*/
public int getViewTypeForSearchTarget(SearchTarget t) {
- if (t.getLayoutType().equals(LayoutType.TEXT_HEADER)) {
- return VIEW_TYPE_SEARCH_CORPUS_TITLE;
- }
- switch (t.getResultType()) {
- case ResultType.APPLICATION:
- if (t.getLayoutType().equals(LayoutType.ICON_SINGLE_VERTICAL_TEXT)) {
- return VIEW_TYPE_SEARCH_ICON;
- }
- break;
- case ResultType.SETTING:
- if (t.getLayoutType().equals(LayoutType.ICON_SLICE)) {
- return VIEW_TYPE_SEARCH_SLICE;
- }
- return VIEW_TYPE_SEARCH_ROW;
- case ResultType.SHORTCUT:
+ switch (t.getLayoutType()) {
+ case LayoutType.TEXT_HEADER:
+ return VIEW_TYPE_SEARCH_CORPUS_TITLE;
+ case LayoutType.ICON_SINGLE_VERTICAL_TEXT:
+ return VIEW_TYPE_SEARCH_ICON;
+ case LayoutType.ICON_SLICE:
+ return VIEW_TYPE_SEARCH_SLICE;
+ case LayoutType.ICON_DOUBLE_HORIZONTAL_TEXT_BUTTON:
+ case LayoutType.ICON_DOUBLE_HORIZONTAL_TEXT:
+ case LayoutType.ICON_SINGLE_HORIZONTAL_TEXT:
return VIEW_TYPE_SEARCH_ICON_ROW;
- case ResultType.PLAY:
- return VIEW_TYPE_SEARCH_ROW_WITH_BUTTON;
+ default:
+ return -1;
+
}
- return -1;
}
}
diff --git a/quickstep/src/com/android/launcher3/search/SearchAdapterItem.java b/quickstep/src/com/android/launcher3/search/SearchAdapterItem.java
index 65ac3f9..01b1999 100644
--- a/quickstep/src/com/android/launcher3/search/SearchAdapterItem.java
+++ b/quickstep/src/com/android/launcher3/search/SearchAdapterItem.java
@@ -19,8 +19,6 @@
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ICON;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ICON_ROW;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_PEOPLE;
-import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ROW;
-import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_ROW_WITH_BUTTON;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_SLICE;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_SUGGEST;
import static com.android.launcher3.search.DeviceSearchAdapterProvider.VIEW_TYPE_SEARCH_THUMBNAIL;
@@ -44,11 +42,11 @@
private List<SearchTarget> mInlineItems = new ArrayList<>();
- private static final int AVAILABLE_FOR_ACCESSIBILITY = VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
- | VIEW_TYPE_SEARCH_SLICE | VIEW_TYPE_SEARCH_ROW | VIEW_TYPE_SEARCH_PEOPLE
- | VIEW_TYPE_SEARCH_THUMBNAIL | VIEW_TYPE_SEARCH_ICON_ROW | VIEW_TYPE_SEARCH_ICON
- | VIEW_TYPE_SEARCH_WIDGET_PREVIEW | VIEW_TYPE_SEARCH_WIDGET_LIVE
- | VIEW_TYPE_SEARCH_SUGGEST;
+ private static final int AVAILABLE_FOR_ACCESSIBILITY =
+ VIEW_TYPE_SEARCH_SLICE | VIEW_TYPE_SEARCH_PEOPLE | VIEW_TYPE_SEARCH_THUMBNAIL
+ | VIEW_TYPE_SEARCH_ICON_ROW | VIEW_TYPE_SEARCH_ICON
+ | VIEW_TYPE_SEARCH_WIDGET_PREVIEW | VIEW_TYPE_SEARCH_WIDGET_LIVE
+ | VIEW_TYPE_SEARCH_SUGGEST;
public SearchAdapterItem(SearchTargetLegacy searchTargetLegacy, int type) {
mSearchTargetLegacy = searchTargetLegacy;
diff --git a/quickstep/src/com/android/launcher3/search/SearchEventTracker.java b/quickstep/src/com/android/launcher3/search/SearchEventTracker.java
deleted file mode 100644
index 90fe661..0000000
--- a/quickstep/src/com/android/launcher3/search/SearchEventTracker.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 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.search;
-
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.systemui.plugins.AllAppsSearchPlugin;
-import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
-import com.android.systemui.plugins.shared.SearchTargetLegacy;
-
-import java.util.WeakHashMap;
-
-/**
- * A singleton class to track and report search events to search provider
- */
-public class SearchEventTracker {
- @Nullable
- private AllAppsSearchPlugin mPlugin;
- private final WeakHashMap<SearchTargetLegacy, SearchTargetHandler>
- mCallbacks = new WeakHashMap<>();
-
- public static final MainThreadInitializedObject<SearchEventTracker> INSTANCE =
- new MainThreadInitializedObject<>(SearchEventTracker::new);
-
- private SearchEventTracker(Context context) {
- }
-
- /**
- * Returns instance of SearchEventTracker
- */
- public static SearchEventTracker getInstance(Context context) {
- return SearchEventTracker.INSTANCE.get(context);
- }
-
- /**
- * Sets current connected plugin for event reporting
- */
- public void setPlugin(@Nullable AllAppsSearchPlugin plugin) {
- mPlugin = plugin;
- }
-
- /**
- * Sends SearchTargetEvent to search provider
- */
- public void notifySearchTargetEvent(SearchTargetEventLegacy searchTargetEvent) {
- if (mPlugin != null) {
- UI_HELPER_EXECUTOR.post(() -> mPlugin.notifySearchTargetEventLegacy(searchTargetEvent));
- }
- }
-
- /**
- * Registers a {@link SearchTargetHandler} to handle quick launch for specified SearchTarget.
- */
- public void registerWeakHandler(SearchTargetLegacy searchTarget,
- SearchTargetHandler targetHandler) {
- mCallbacks.put(searchTarget, targetHandler);
- }
-
- /**
- * Handles quick select for SearchTarget
- */
- public void quickSelect(SearchTargetLegacy searchTarget) {
- SearchTargetHandler searchTargetHandler = mCallbacks.get(searchTarget);
- if (searchTargetHandler != null) {
- searchTargetHandler.handleSelection(SearchTargetEventLegacy.QUICK_SELECT);
- }
- }
-
- /**
- * flushes all registered quick select handlers
- */
- public void clearHandlers() {
- mCallbacks.clear();
- }
-}
diff --git a/quickstep/src/com/android/launcher3/search/SearchResultIcon.java b/quickstep/src/com/android/launcher3/search/SearchResultIcon.java
index d5fe0e8..0b8d3cb 100644
--- a/quickstep/src/com/android/launcher3/search/SearchResultIcon.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultIcon.java
@@ -17,15 +17,16 @@
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.app.search.SearchAction;
import android.app.search.SearchTarget;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.Build;
+import android.os.Bundle;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.view.View;
@@ -36,17 +37,14 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.allapps.AllAppsStore;
-import com.android.launcher3.config.FeatureFlags;
-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.PackageItemInfo;
+import com.android.launcher3.model.data.SearchActionItemInfo;
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.SearchTargetEventLegacy;
-import com.android.systemui.plugins.shared.SearchTargetLegacy;
import java.util.List;
import java.util.function.Consumer;
@@ -58,22 +56,11 @@
SearchTargetHandler, View.OnClickListener,
View.OnLongClickListener {
-
- 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 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 static final String BUNDLE_EXTRA_SHOULD_START = "should_start";
+ private static final String BUNDLE_EXTRA_SHOULD_START_FOR_RESULT = "should_start_for_result";
private final Launcher mLauncher;
- private SearchTargetLegacy mSearchTarget;
private Consumer<ItemInfoWithIcon> mOnItemInfoChanged;
public SearchResultIcon(Context context) {
@@ -89,6 +76,8 @@
mLauncher = Launcher.getLauncher(getContext());
}
+ private boolean mLongPressSupported;
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@@ -101,37 +90,6 @@
}
/**
- * Applies search target with a ItemInfoWithIcon consumer to be called after itemInfo is
- * constructed
- */
- public void applySearchTarget(SearchTargetLegacy searchTarget, Consumer<ItemInfoWithIcon> cb) {
- mOnItemInfoChanged = cb;
- applySearchTarget(searchTarget);
- }
-
- @Override
- public void applySearchTarget(SearchTargetLegacy searchTarget) {
- mSearchTarget = searchTarget;
- SearchEventTracker.getInstance(getContext()).registerWeakHandler(mSearchTarget, this);
- setVisibility(VISIBLE);
- 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:
- prepareUsingRemoteAction(searchTarget.getRemoteAction(),
- searchTarget.getExtras().getString(REMOTE_ACTION_TOKEN),
- searchTarget.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START),
- searchTarget.getItemType().equals(TARGET_TYPE_REMOTE_ACTION));
- break;
- }
- }
-
- /**
* Applies {@link SearchTarget} to view. registers a consumer after a corresponding
* {@link ItemInfoWithIcon} is created
*/
@@ -147,13 +105,61 @@
case ResultType.APPLICATION:
prepareUsingApp(new ComponentName(parentTarget.getPackageName(),
parentTarget.getExtras().getString("class")), parentTarget.getUserHandle());
+ mLongPressSupported = true;
break;
case ResultType.SHORTCUT:
prepareUsingShortcutInfo(parentTarget.getShortcutInfo());
+ mLongPressSupported = true;
+ break;
+ default:
+ prepareUsingSearchAction(parentTarget);
+ mLongPressSupported = false;
break;
}
}
+ private void prepareUsingSearchAction(SearchTarget searchTarget) {
+ SearchAction searchAction = searchTarget.getSearchAction();
+ Bundle extras = searchAction.getExtras();
+ SearchActionItemInfo itemInfo = new SearchActionItemInfo(searchAction.getIcon(),
+ searchTarget.getPackageName(), searchTarget.getUserHandle(),
+ searchAction.getTitle());
+ itemInfo.setIntent(searchAction.getIntent());
+ itemInfo.setPendingIntent(searchAction.getPendingIntent());
+
+ //TODO: remove this after flags are introduced in SearchAction. Settings results require
+ // startActivityForResult
+ boolean isSettingsResult = searchTarget.getResultType() == ResultType.SETTING;
+ if ((extras != null && extras.getBoolean(BUNDLE_EXTRA_SHOULD_START_FOR_RESULT))
+ || isSettingsResult) {
+ itemInfo.setFlags(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT);
+ } else if (extras != null && extras.getBoolean(BUNDLE_EXTRA_SHOULD_START)) {
+ itemInfo.setFlags(SearchActionItemInfo.FLAG_SHOULD_START);
+ }
+
+
+ notifyItemInfoChanged(itemInfo);
+ LauncherAppState appState = LauncherAppState.getInstance(mLauncher);
+ MODEL_EXECUTOR.post(() -> {
+ try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
+ Icon icon = searchTarget.getSearchAction().getIcon();
+ Drawable d;
+ if (icon == null) {
+ PackageItemInfo pkgInfo = new PackageItemInfo(searchTarget.getPackageName());
+ pkgInfo.user = searchTarget.getUserHandle();
+ appState.getIconCache().getTitleAndIconForApp(pkgInfo, false);
+ itemInfo.bitmap = pkgInfo.bitmap;
+ } else {
+ d = itemInfo.getIcon().loadDrawable(getContext());
+ itemInfo.bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
+ Build.VERSION.SDK_INT);
+ }
+
+ }
+ MAIN_EXECUTOR.post(() -> applyFromSearchActionItemInfo(itemInfo));
+ });
+ }
+
private void prepareUsingApp(ComponentName componentName, UserHandle userHandle) {
AllAppsStore appsStore = mLauncher.getAppsView().getAppsStore();
AppInfo appInfo = appsStore.getApp(new ComponentKey(componentName, userHandle));
@@ -177,69 +183,26 @@
});
}
- private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start,
- boolean useIconToBadge) {
- RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
- notifyItemInfoChanged(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());
- 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;
- }
- }
- MAIN_EXECUTOR.post(() -> applyFromRemoteActionInfo(itemInfo));
- });
- }
-
@Override
- public void handleSelection(int eventType) {
- mLauncher.getItemOnClickListener().onClick(this);
- if (!FeatureFlags.USE_SEARCH_API.get()) {
- reportEvent(eventType);
- }
- }
-
- private void reportEvent(int eventType) {
- SearchTargetEventLegacy.Builder b = new SearchTargetEventLegacy.Builder(mSearchTarget,
- eventType);
- if (mSearchTarget.getItemType().equals(TARGET_TYPE_SHORTCUT)) {
- b.setShortcutPosition(0);
- }
- SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(b.build());
-
+ public boolean quickSelect() {
+ //TODO: event reporting
+ this.performClick();
+ return true;
}
@Override
public void onClick(View view) {
- handleSelection(SearchTargetEventLegacy.SELECT);
+ //TODO: event reporting
+ mLauncher.getItemOnClickListener().onClick(this);
}
@Override
public boolean onLongClick(View view) {
- if (!supportsLongPress(mSearchTarget.getItemType())) {
+ //TODO: event reporting
+ if (!mLongPressSupported) {
return false;
}
- reportEvent(SearchTargetEventLegacy.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;
+ return ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(this);
}
private void notifyItemInfoChanged(ItemInfoWithIcon itemInfoWithIcon) {
diff --git a/quickstep/src/com/android/launcher3/search/SearchResultIconRow.java b/quickstep/src/com/android/launcher3/search/SearchResultIconRow.java
index 80d543a..4fb668e 100644
--- a/quickstep/src/com/android/launcher3/search/SearchResultIconRow.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultIconRow.java
@@ -19,56 +19,42 @@
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.app.search.SearchTarget;
-import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ShortcutInfo;
-import android.os.UserHandle;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.View;
-import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
-import com.android.app.search.ResultType;
-import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
-import com.android.systemui.plugins.shared.SearchTargetLegacy;
import java.util.ArrayList;
import java.util.List;
-import java.util.function.Consumer;
/**
* A full width representation of {@link SearchResultIcon} with a secondary label and inline
- * shortcuts
+ * SearchTargets
*/
-public class SearchResultIconRow extends LinearLayout implements
- SearchTargetHandler, View.OnClickListener,
- View.OnLongClickListener, Consumer<ItemInfoWithIcon> {
- public static final int MAX_SHORTCUTS_COUNT = 2;
+public class SearchResultIconRow extends LinearLayout implements SearchTargetHandler {
+ public static final int MAX_INLINE_ITEMS = 2;
- private final Launcher mLauncher;
+ protected final Launcher mLauncher;
private final LauncherAppState mLauncherAppState;
private SearchResultIcon mResultIcon;
+
private TextView mTitleView;
- private TextView mDescriptionView;
- private BubbleTextView[] mShortcutViews = new BubbleTextView[2];
+ private TextView mSubTitleView;
+ private final SearchResultIcon[] mInlineIcons = new SearchResultIcon[MAX_INLINE_ITEMS];
- private SearchTargetLegacy mSearchTarget;
private PackageItemInfo mProviderInfo;
-
public SearchResultIconRow(Context context) {
this(context, null, 0);
}
@@ -84,129 +70,87 @@
mLauncherAppState = LauncherAppState.getInstance(getContext());
}
+ protected int getIconSize() {
+ return mLauncher.getDeviceProfile().allAppsIconSizePx;
+ }
+
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- int iconSize = mLauncher.getDeviceProfile().allAppsIconSizePx;
+
+ int iconSize = getIconSize();
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);
+ mSubTitleView = findViewById(R.id.subtitle);
+ mSubTitleView.setVisibility(GONE);
mResultIcon.getLayoutParams().height = iconSize;
mResultIcon.getLayoutParams().width = iconSize;
mResultIcon.setTextVisibility(false);
- for (BubbleTextView bubbleTextView : mShortcutViews) {
- ViewGroup.LayoutParams lp = bubbleTextView.getLayoutParams();
- lp.width = iconSize;
- bubbleTextView.setOnClickListener(view -> {
- WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) bubbleTextView.getTag();
- SearchTargetEventLegacy event = new SearchTargetEventLegacy.Builder(mSearchTarget,
- SearchTargetEventLegacy.CHILD_SELECT).setShortcutPosition(
- itemInfo.rank).build();
- SearchEventTracker.getInstance(getContext()).notifySearchTargetEvent(event);
- mLauncher.getItemOnClickListener().onClick(view);
- });
+
+ mInlineIcons[0] = findViewById(R.id.shortcut_0);
+ mInlineIcons[1] = findViewById(R.id.shortcut_1);
+ for (SearchResultIcon inlineIcon : mInlineIcons) {
+ inlineIcon.getLayoutParams().width = getIconSize();
}
- setOnClickListener(this);
- setOnLongClickListener(this);
+
+ setOnClickListener(mResultIcon);
+ setOnLongClickListener(mResultIcon);
}
@Override
public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
- mResultIcon.applySearchTarget(parentTarget, children, this);
- if (parentTarget.getResultType() == ResultType.SHORTCUT) {
- ShortcutInfo shortcutInfo = parentTarget.getShortcutInfo();
- setProviderDetails(new ComponentName(shortcutInfo.getPackage(), ""),
- shortcutInfo.getUserHandle());
+ mResultIcon.applySearchTarget(parentTarget, children, this::onItemInfoCreated);
+ if (parentTarget.getShortcutInfo() != null) {
+ updateWithShortcutInfo(parentTarget.getShortcutInfo());
+ } else if (parentTarget.getSearchAction() != null) {
+ showSubtitleIfNeeded(parentTarget.getSearchAction().getSubtitle());
}
+ showInlineItems(children);
}
@Override
- public void applySearchTarget(SearchTargetLegacy searchTarget) {
- mSearchTarget = searchTarget;
- mResultIcon.applySearchTarget(searchTarget, this);
- String itemType = searchTarget.getItemType();
- boolean showDesc = itemType.equals(SearchResultIcon.TARGET_TYPE_SHORTCUT);
- mDescriptionView.setVisibility(showDesc ? VISIBLE : GONE);
-
- 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());
- } else if (itemType.equals(SearchResultIcon.TARGET_TYPE_REMOTE_ACTION)) {
- CharSequence desc = mSearchTarget.getRemoteAction().getContentDescription();
- if (!TextUtils.isEmpty(desc)) {
- mDescriptionView.setVisibility(VISIBLE);
- mDescriptionView.setText(desc);
- }
- }
- if (!itemType.equals(SearchResultIcon.TARGET_TYPE_HERO_APP)) {
- showInlineShortcuts(new ArrayList<>());
- }
+ public boolean quickSelect() {
+ this.performClick();
+ return true;
}
- @Override
- public void accept(ItemInfoWithIcon itemInfoWithIcon) {
- mTitleView.setText(itemInfoWithIcon.title);
- }
-
- 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;
+ private void updateWithShortcutInfo(ShortcutInfo shortcutInfo) {
+ PackageItemInfo packageItemInfo = new PackageItemInfo(shortcutInfo.getPackage());
+ if (packageItemInfo.equals(mProviderInfo)) return;
MODEL_EXECUTOR.post(() -> {
- packageItemInfo.user = userHandle;
mLauncherAppState.getIconCache().getTitleAndIconForApp(packageItemInfo, true);
MAIN_EXECUTOR.post(() -> {
- mDescriptionView.setText(packageItemInfo.title);
+ showSubtitleIfNeeded(packageItemInfo.title);
mProviderInfo = packageItemInfo;
});
});
}
- @Override
- public void handleSelection(int eventType) {
- mResultIcon.handleSelection(eventType);
+
+ protected void showSubtitleIfNeeded(CharSequence subTitle) {
+ if (!TextUtils.isEmpty(subTitle)) {
+ mSubTitleView.setText(subTitle);
+ mSubTitleView.setVisibility(VISIBLE);
+ } else {
+ mSubTitleView.setVisibility(GONE);
+ }
}
- @Override
- public void onClick(View view) {
- mResultIcon.performClick();
+
+ protected void showInlineItems(List<SearchTarget> children) {
+ for (int i = 0; i < MAX_INLINE_ITEMS; i++) {
+ if (i < children.size()) {
+ mInlineIcons[i].applySearchTarget(children.get(0), new ArrayList<>());
+ mInlineIcons[i].setVisibility(VISIBLE);
+ } else {
+ mInlineIcons[i].setVisibility(GONE);
+ }
+ }
}
- @Override
- public boolean onLongClick(View view) {
- mResultIcon.performLongClick();
- return false;
+ protected void onItemInfoCreated(ItemInfoWithIcon info) {
+ setTag(info);
+ mTitleView.setText(info.title);
}
}
diff --git a/quickstep/src/com/android/launcher3/search/SearchResultSettingsSlice.java b/quickstep/src/com/android/launcher3/search/SearchResultIconSlice.java
similarity index 69%
rename from quickstep/src/com/android/launcher3/search/SearchResultSettingsSlice.java
rename to quickstep/src/com/android/launcher3/search/SearchResultIconSlice.java
index bf50b67..e6c952f 100644
--- a/quickstep/src/com/android/launcher3/search/SearchResultSettingsSlice.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultIconSlice.java
@@ -15,12 +15,13 @@
*/
package com.android.launcher3.search;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
import android.app.search.SearchTarget;
import android.content.Context;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.View;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
@@ -32,40 +33,39 @@
import androidx.slice.widget.SliceView;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
-import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
+import com.android.launcher3.model.data.PackageItemInfo;
import com.android.systemui.plugins.shared.SearchTargetLegacy;
+import java.util.ArrayList;
import java.util.List;
/**
* A slice view wrapper with settings app icon at start
*/
-public class SearchResultSettingsSlice extends LinearLayout implements
+public class SearchResultIconSlice extends LinearLayout implements
SearchTargetHandler, SliceView.OnSliceActionListener {
-
- public static final String TARGET_TYPE_SLICE = "settings_slice";
-
private static final String TAG = "SearchSliceController";
private static final String URI_EXTRA_KEY = "slice_uri";
private SliceView mSliceView;
- private View mIcon;
+ private SearchResultIcon mIcon;
private LiveData<Slice> mSliceLiveData;
private SearchTargetLegacy mSearchTarget;
private final Launcher mLauncher;
- public SearchResultSettingsSlice(Context context) {
+ public SearchResultIconSlice(Context context) {
this(context, null, 0);
}
- public SearchResultSettingsSlice(Context context,
+ public SearchResultIconSlice(Context context,
@Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
- public SearchResultSettingsSlice(Context context, @Nullable AttributeSet attrs,
+ public SearchResultIconSlice(Context context, @Nullable AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLauncher = Launcher.getLauncher(getContext());
@@ -76,24 +76,16 @@
super.onFinishInflate();
mSliceView = findViewById(R.id.slice);
mIcon = findViewById(R.id.icon);
- SearchSettingsRowView.applySettingsIcon(mLauncher, mIcon);
- }
-
- @Override
- public void applySearchTarget(SearchTargetLegacy searchTarget) {
- reset();
- mSearchTarget = searchTarget;
- try {
- mSliceLiveData = mLauncher.getLiveSearchManager().getSliceForUri(getSliceUri());
- mSliceLiveData.observe(mLauncher, mSliceView);
- } catch (Exception ex) {
- Log.e(TAG, "unable to bind slice", ex);
- }
+ mIcon.setTextVisibility(false);
+ int iconSize = mLauncher.getDeviceProfile().iconSizePx;
+ mIcon.getLayoutParams().height = iconSize;
+ mIcon.getLayoutParams().width = iconSize;
}
@Override
public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
reset();
+ updateIcon(parentTarget, children);
try {
mSliceLiveData = mLauncher.getLiveSearchManager().getSliceForUri(
parentTarget.getSliceUri());
@@ -103,6 +95,20 @@
}
}
+ private void updateIcon(SearchTarget parentTarget, List<SearchTarget> children) {
+ if (children.size() == 1) {
+ mIcon.applySearchTarget(children.get(0), new ArrayList<>());
+ } else {
+ LauncherAppState appState = LauncherAppState.getInstance(getContext());
+ MODEL_EXECUTOR.post(() -> {
+ PackageItemInfo pkgItem = new PackageItemInfo(parentTarget.getPackageName());
+ pkgItem.user = parentTarget.getUserHandle();
+ appState.getIconCache().getTitleAndIconForApp(pkgItem, false);
+ mIcon.applyFromItemInfoWithIcon(pkgItem);
+ });
+ }
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -115,12 +121,6 @@
reset();
}
- @Override
- public void handleSelection(int eventType) {
- SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent(
- new SearchTargetEventLegacy.Builder(mSearchTarget,
- SearchTargetEventLegacy.CHILD_SELECT).build());
- }
private void reset() {
mSliceView.setOnSliceActionListener(null);
@@ -131,7 +131,7 @@
@Override
public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) {
- handleSelection(SearchTargetEventLegacy.CHILD_SELECT);
+ //TODO: event reporting
}
private Uri getSliceUri() {
diff --git a/quickstep/src/com/android/launcher3/search/SearchResultPeopleView.java b/quickstep/src/com/android/launcher3/search/SearchResultPeopleView.java
index 8caa51c..f3355da 100644
--- a/quickstep/src/com/android/launcher3/search/SearchResultPeopleView.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultPeopleView.java
@@ -44,7 +44,6 @@
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.LauncherIcons;
-import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
import com.android.systemui.plugins.shared.SearchTargetLegacy;
import java.util.ArrayList;
@@ -99,7 +98,6 @@
button.getLayoutParams().width = mButtonSize;
button.getLayoutParams().height = mButtonSize;
}
- setOnClickListener(v -> handleSelection(SearchTargetEventLegacy.SELECT));
}
@Override
@@ -137,7 +135,6 @@
button.setVisibility(GONE);
}
}
- SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
}
/**
@@ -185,19 +182,6 @@
launcher.startActivitySafely(b, intent, null);
Bundle bundle = new Bundle();
bundle.putBundle("provider", provider);
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEventLegacy.Builder(mSearchTarget,
- SearchTargetEventLegacy.CHILD_SELECT).setExtras(bundle).build());
});
}
-
- @Override
- public void handleSelection(int eventType) {
- if (mIntent != null) {
- Launcher launcher = Launcher.getLauncher(getContext());
- launcher.startActivitySafely(this, mIntent, null);
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
- }
- }
}
diff --git a/quickstep/src/com/android/launcher3/search/SearchResultPlayItem.java b/quickstep/src/com/android/launcher3/search/SearchResultPlayItem.java
deleted file mode 100644
index 840bde9..0000000
--- a/quickstep/src/com/android/launcher3/search/SearchResultPlayItem.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2015 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.search;
-
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
-import android.app.search.SearchAction;
-import android.app.search.SearchTarget;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.BitmapDrawable;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.icons.BitmapRenderer;
-import com.android.launcher3.util.Themes;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.List;
-
-/**
- * A View representing a PlayStore item.
- */
-public class SearchResultPlayItem extends LinearLayout implements
- SearchTargetHandler {
-
- public static final String TARGET_TYPE_PLAY = "play";
-
- private static final int BITMAP_CROP_MASK_COLOR = 0xff424242;
- final Paint mIconPaint = new Paint();
- final Rect mTempRect = new Rect();
- private final DeviceProfile mDeviceProfile;
- private View mIconView;
- private TextView mTitleView;
- private TextView[] mDetailViews = new TextView[3];
- private Button mPreviewButton;
- private String mPackageName;
- private Intent mIntent;
- private Intent mSecondaryIntent;
-
-
- public SearchResultPlayItem(Context context) {
- this(context, null, 0);
- }
-
- public SearchResultPlayItem(Context context,
- @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SearchResultPlayItem(Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mDeviceProfile = Launcher.getLauncher(getContext()).getDeviceProfile();
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mIconView = findViewById(R.id.icon);
- mTitleView = findViewById(R.id.title_view);
- mPreviewButton = findViewById(R.id.try_button);
- mPreviewButton.setOnClickListener(view -> launchIntent(mSecondaryIntent));
- mDetailViews[0] = findViewById(R.id.detail_0);
- mDetailViews[1] = findViewById(R.id.detail_1);
- mDetailViews[2] = findViewById(R.id.detail_2);
-
- ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams();
- iconParams.height = mDeviceProfile.allAppsIconSizePx;
- iconParams.width = mDeviceProfile.allAppsIconSizePx;
- setOnClickListener(view -> launchIntent(mIntent));
- }
-
- private void showIfNecessary(TextView textView, @Nullable String string) {
- if (string == null || string.isEmpty()) {
- textView.setVisibility(GONE);
- } else {
- textView.setText(string);
- textView.setVisibility(VISIBLE);
- }
- }
-
- private void launchIntent(Intent intent) {
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getContext().startActivity(intent);
- }
-
- @Override
- public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
- if (parentTarget.getPackageName().equals(mPackageName)) {
- return;
- }
- mPackageName = parentTarget.getPackageName();
- SearchAction action = parentTarget.getSearchAction();
- mTitleView.setText(action.getTitle());
- showIfNecessary(mDetailViews[0], action.getSubtitle().toString());
- mIntent = action.getIntent();
-
- mIconView.setBackgroundResource(R.drawable.ic_deepshortcut_placeholder);
- loadIcon(action.getIcon().getUri().toString());
-
- mSecondaryIntent = children.size() == 1 ? children.get(0).getSearchAction().getIntent()
- : null;
- mPreviewButton.setVisibility(mSecondaryIntent == null ? GONE : VISIBLE);
- }
-
- private void loadIcon(String iconUrl) {
- UI_HELPER_EXECUTOR.execute(() -> {
- try {
- URL url = new URL(iconUrl);
- URLConnection con = url.openConnection();
- con.addRequestProperty("Cache-Control", "max-age: 0");
- con.setUseCaches(true);
- Bitmap bitmap = BitmapFactory.decodeStream(con.getInputStream());
- BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), getRoundedBitmap(
- Bitmap.createScaledBitmap(bitmap, mDeviceProfile.allAppsIconSizePx,
- mDeviceProfile.allAppsIconSizePx, false)));
- mIconView.post(() -> mIconView.setBackground(bitmapDrawable));
- } catch (IOException e) {
- e.printStackTrace();
- }
- });
- }
-
- private Bitmap getRoundedBitmap(Bitmap bitmap) {
- final int iconSize = bitmap.getWidth();
- final float radius = Themes.getDialogCornerRadius(getContext());
-
- Bitmap output = BitmapRenderer.createHardwareBitmap(iconSize, iconSize, (canvas) -> {
- mTempRect.set(0, 0, iconSize, iconSize);
- final RectF rectF = new RectF(mTempRect);
-
- mIconPaint.setAntiAlias(true);
- mIconPaint.reset();
- canvas.drawARGB(0, 0, 0, 0);
- mIconPaint.setColor(BITMAP_CROP_MASK_COLOR);
- canvas.drawRoundRect(rectF, radius, radius, mIconPaint);
-
- mIconPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
- canvas.drawBitmap(bitmap, mTempRect, mTempRect, mIconPaint);
- });
- return output;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/search/SearchResultWidget.java b/quickstep/src/com/android/launcher3/search/SearchResultWidget.java
index 4fe9229..c6bdb68 100644
--- a/quickstep/src/com/android/launcher3/search/SearchResultWidget.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultWidget.java
@@ -36,7 +36,6 @@
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.widget.PendingAddWidgetInfo;
-import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
import com.android.systemui.plugins.shared.SearchTargetLegacy;
/**
@@ -82,7 +81,8 @@
// detect tap event on widget container for search target event reporting
mClickDetector = new GestureDetector(context,
- new ClickListener(() -> handleSelection(SearchTargetEventLegacy.CHILD_SELECT)));
+ new ClickListener(() -> {
+ }));
mLongPressHelper = new CheckLongPressHelper(this);
mLongPressHelper.setLongPressTimeoutFactor(1);
@@ -139,12 +139,6 @@
}
@Override
- public void handleSelection(int eventType) {
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
- }
-
- @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
mLongPressHelper.onTouchEvent(ev);
mClickDetector.onTouchEvent(ev);
@@ -182,7 +176,6 @@
@Override
public boolean onLongClick(View view) {
ItemLongClickListener.INSTANCE_ALL_APPS.onLongClick(view);
- handleSelection(SearchTargetEventLegacy.LONG_PRESS);
return false;
}
diff --git a/quickstep/src/com/android/launcher3/search/SearchResultWidgetPreview.java b/quickstep/src/com/android/launcher3/search/SearchResultWidgetPreview.java
index 5effbe5..22f0b76 100644
--- a/quickstep/src/com/android/launcher3/search/SearchResultWidgetPreview.java
+++ b/quickstep/src/com/android/launcher3/search/SearchResultWidgetPreview.java
@@ -39,7 +39,6 @@
import com.android.launcher3.widget.PendingItemDragHelper;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.WidgetImageView;
-import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
import com.android.systemui.plugins.shared.SearchTargetLegacy;
/**
@@ -121,19 +120,11 @@
new PendingItemDragHelper(mWidgetCell).startDrag(
imageView.getBitmapBounds(), imageView.getBitmap().getWidth(), imageView.getWidth(),
new Point(loc[0], loc[1]), mLauncher.getAppsView(), new DragOptions());
- handleSelection(SearchTargetEventLegacy.LONG_PRESS);
return true;
}
@Override
public void onClick(View view) {
mWidgetToast = BaseWidgetSheet.showWidgetToast(getContext(), mWidgetToast);
- handleSelection(SearchTargetEventLegacy.SELECT);
- }
-
- @Override
- public void handleSelection(int eventType) {
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
}
}
diff --git a/quickstep/src/com/android/launcher3/search/SearchSectionHeaderView.java b/quickstep/src/com/android/launcher3/search/SearchSectionHeaderView.java
index ccc38db..e015122 100644
--- a/quickstep/src/com/android/launcher3/search/SearchSectionHeaderView.java
+++ b/quickstep/src/com/android/launcher3/search/SearchSectionHeaderView.java
@@ -22,8 +22,6 @@
import androidx.annotation.Nullable;
-import com.android.systemui.plugins.shared.SearchTargetLegacy;
-
import java.util.List;
/**
@@ -31,7 +29,6 @@
*/
public class SearchSectionHeaderView extends TextView implements
SearchTargetHandler {
- public static final String TARGET_TYPE_SECTION_HEADER = "section_header";
public SearchSectionHeaderView(Context context) {
super(context);
@@ -47,17 +44,6 @@
}
@Override
- public void applySearchTarget(SearchTargetLegacy searchTarget) {
- String title = searchTarget.getExtras().getString("title");
- if (title == null || !title.isEmpty()) {
- setText(title);
- setVisibility(VISIBLE);
- } else {
- setVisibility(INVISIBLE);
- }
- }
-
- @Override
public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
setText(parentTarget.getSearchAction().getTitle());
setVisibility(VISIBLE);
diff --git a/quickstep/src/com/android/launcher3/search/SearchSettingsRowView.java b/quickstep/src/com/android/launcher3/search/SearchSettingsRowView.java
deleted file mode 100644
index 6fc0046..0000000
--- a/quickstep/src/com/android/launcher3/search/SearchSettingsRowView.java
+++ /dev/null
@@ -1,161 +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.search;
-
-import static com.android.launcher3.FastBitmapDrawable.newIcon;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.app.search.SearchAction;
-import android.app.search.SearchTarget;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-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.FastBitmapDrawable;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.R;
-import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.systemui.plugins.shared.SearchTargetEventLegacy;
-import com.android.systemui.plugins.shared.SearchTargetLegacy;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A row of clickable TextViews with a breadcrumb for settings search.
- */
-public class SearchSettingsRowView extends LinearLayout implements
- View.OnClickListener, SearchTargetHandler {
-
- public static final String TARGET_TYPE_SETTINGS_ROW = "settings_row";
-
- private View mIconView;
- private TextView mTitleView;
- private TextView mBreadcrumbsView;
- private Intent mIntent;
- private SearchTargetLegacy mSearchTarget;
-
-
- public SearchSettingsRowView(@NonNull Context context) {
- this(context, null, 0);
- }
-
- public SearchSettingsRowView(@NonNull Context context,
- @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SearchSettingsRowView(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mIconView = findViewById(R.id.icon);
- mTitleView = findViewById(R.id.title);
- mBreadcrumbsView = findViewById(R.id.breadcrumbs);
- setOnClickListener(this);
- applySettingsIcon(Launcher.getLauncher(getContext()), mIconView);
- }
-
- @Override
- public void applySearchTarget(SearchTargetLegacy searchTarget) {
- mSearchTarget = searchTarget;
- Bundle bundle = searchTarget.getExtras();
- mIntent = bundle.getParcelable("intent");
- showIfAvailable(mTitleView, bundle.getString("title"));
- mIconView.setContentDescription(bundle.getString("title"));
- ArrayList<String> breadcrumbs = bundle.getStringArrayList("breadcrumbs");
- //TODO: implement RTL friendly breadcrumbs view
- showIfAvailable(mBreadcrumbsView, breadcrumbs != null
- ? String.join(" > ", breadcrumbs) : null);
- SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(searchTarget, this);
- }
-
- @Override
- public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
- SearchAction action = parentTarget.getSearchAction();
- mIconView.setContentDescription(action.getTitle());
- showIfAvailable(mTitleView, action.getTitle().toString());
- showIfAvailable(mBreadcrumbsView, action.getSubtitle().toString());
- }
-
- private void showIfAvailable(TextView view, @Nullable String string) {
- if (TextUtils.isEmpty(string)) {
- view.setVisibility(GONE);
- } else {
- view.setVisibility(VISIBLE);
- view.setText(string);
- }
- }
-
- @Override
- public void onClick(View view) {
- handleSelection(SearchTargetEventLegacy.SELECT);
- }
-
- @Override
- public void handleSelection(int eventType) {
- if (mIntent == null) return;
- // TODO: create ItemInfo object and then use it to call startActivityForResult for proper
- // WW logging
- Launcher launcher = Launcher.getLauncher(getContext());
- launcher.startActivityForResult(mIntent, 0);
-
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
- }
-
- /**
- * Requests settings app icon from {@link com.android.launcher3.icons.IconCache} and applies
- * to to view
- */
- public static void applySettingsIcon(Launcher launcher, View view) {
- LauncherAppState appState = LauncherAppState.getInstance(launcher);
- MODEL_EXECUTOR.post(() -> {
- PackageItemInfo packageItemInfo = new PackageItemInfo(getSettingsPackageName(launcher));
- appState.getIconCache().getTitleAndIconForApp(packageItemInfo, false);
- MAIN_EXECUTOR.post(() -> {
- FastBitmapDrawable iconDrawable = newIcon(appState.getContext(), packageItemInfo);
- view.setBackground(iconDrawable);
- });
- });
- }
-
- private static String getSettingsPackageName(Launcher launcher) {
- Intent intent = new Intent(android.provider.Settings.ACTION_SETTINGS);
- List<ResolveInfo> resolveInfos = launcher.getPackageManager().queryIntentActivities(intent,
- PackageManager.MATCH_DEFAULT_ONLY);
- if (resolveInfos.size() == 0) {
- return "";
- }
- return resolveInfos.get(0).activityInfo.packageName;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/search/SearchTargetHandler.java b/quickstep/src/com/android/launcher3/search/SearchTargetHandler.java
index e72578d..67502f6 100644
--- a/quickstep/src/com/android/launcher3/search/SearchTargetHandler.java
+++ b/quickstep/src/com/android/launcher3/search/SearchTargetHandler.java
@@ -29,7 +29,10 @@
/**
* Update view using values from {@link SearchTargetLegacy}
+ *
+ * @deprecated Use {@link SearchTargetHandler#applySearchTarget(SearchTarget, List)} instead
*/
+ @Deprecated
default void applySearchTarget(SearchTargetLegacy searchTarget) {
}
@@ -41,9 +44,10 @@
}
/**
- * Handles selection of SearchTarget
+ * Handle IME quick select event. returns whether event was handled.
*/
- default void handleSelection(int eventType) {
+ default boolean quickSelect() {
+ return false;
}
}
diff --git a/quickstep/src/com/android/launcher3/search/ThumbnailSearchResultView.java b/quickstep/src/com/android/launcher3/search/ThumbnailSearchResultView.java
index 44f7057..7108d63 100644
--- a/quickstep/src/com/android/launcher3/search/ThumbnailSearchResultView.java
+++ b/quickstep/src/com/android/launcher3/search/ThumbnailSearchResultView.java
@@ -16,27 +16,11 @@
package com.android.launcher3.search;
-import static com.android.launcher3.search.SearchResultIcon.REMOTE_ACTION_SHOULD_START;
-import static com.android.launcher3.search.SearchResultIcon.REMOTE_ACTION_TOKEN;
-
+import android.app.search.SearchTarget;
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.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.shared.SearchTargetEventLegacy;
-import com.android.systemui.plugins.shared.SearchTargetLegacy;
+import java.util.List;
/**
* A view representing a high confidence app search result that includes shortcuts
@@ -44,11 +28,6 @@
public class ThumbnailSearchResultView extends androidx.appcompat.widget.AppCompatImageView
implements SearchTargetHandler {
- public static final String TARGET_TYPE_SCREENSHOT = "screenshot";
- public static final String TARGET_TYPE_SCREENSHOT_LEGACY = "screenshot_legacy";
-
- private SearchTargetLegacy mSearchTarget;
-
public ThumbnailSearchResultView(Context context) {
super(context);
}
@@ -62,53 +41,7 @@
}
@Override
- public 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);
- }
- SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent(
- new SearchTargetEventLegacy.Builder(mSearchTarget, eventType).build());
- }
+ public void applySearchTarget(SearchTarget parentTarget, List<SearchTarget> children) {
- @Override
- public void applySearchTarget(SearchTargetLegacy target) {
- mSearchTarget = target;
- Bitmap bitmap;
- if (target.getRemoteAction() != null) {
- RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(target.getRemoteAction(),
- target.getExtras().getString(REMOTE_ACTION_TOKEN),
- target.getExtras().getBoolean(REMOTE_ACTION_SHOULD_START));
- bitmap = ((BitmapDrawable) target.getRemoteAction().getIcon()
- .loadDrawable(getContext())).getBitmap();
- // crop
- if (bitmap.getWidth() < bitmap.getHeight()) {
- bitmap = Bitmap.createBitmap(bitmap, 0,
- bitmap.getHeight() / 2 - bitmap.getWidth() / 2,
- bitmap.getWidth(), bitmap.getWidth());
- } else {
- bitmap = Bitmap.createBitmap(bitmap, bitmap.getWidth() / 2 - bitmap.getHeight() / 2,
- 0,
- bitmap.getHeight(), bitmap.getHeight());
- }
- setTag(itemInfo);
- } else {
- bitmap = (Bitmap) target.getExtras().getParcelable("bitmap");
- WorkspaceItemInfo itemInfo = new WorkspaceItemInfo();
- itemInfo.intent = new Intent(Intent.ACTION_VIEW)
- .setData(Uri.parse(target.getExtras().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(SearchTargetEventLegacy.SELECT));
- SearchEventTracker.INSTANCE.get(getContext()).registerWeakHandler(target, this);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
new file mode 100644
index 0000000..0093e66
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarContainerView.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.taskbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Top-level ViewGroup that hosts the TaskbarView as well as Views created by it such as Folder.
+ */
+public class TaskbarContainerView extends FrameLayout {
+ public TaskbarContainerView(@NonNull Context context) {
+ this(context, null);
+ }
+
+ public TaskbarContainerView(@NonNull Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TaskbarContainerView(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public TaskbarContainerView(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
new file mode 100644
index 0000000..7be1b92
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarController.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 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.taskbar;
+
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+
+import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
+import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
+
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.view.Gravity;
+import android.view.WindowManager;
+
+import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.R;
+import com.android.systemui.shared.system.WindowManagerWrapper;
+
+/**
+ * Interfaces with Launcher/WindowManager/SystemUI to determine what to show in TaskbarView.
+ */
+public class TaskbarController {
+
+ private static final String WINDOW_TITLE = "Taskbar";
+
+ private final TaskbarContainerView mTaskbarContainerView;
+ private final TaskbarView mTaskbarView;
+ private final BaseQuickstepLauncher mLauncher;
+ private final WindowManager mWindowManager;
+ // Layout width and height of the Taskbar in the default state.
+ private final Point mTaskbarSize;
+
+ private WindowManager.LayoutParams mWindowLayoutParams;
+
+ public TaskbarController(BaseQuickstepLauncher launcher,
+ TaskbarContainerView taskbarContainerView) {
+ mLauncher = launcher;
+ mTaskbarContainerView = taskbarContainerView;
+ mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view);
+ mWindowManager = mLauncher.getWindowManager();
+ mTaskbarSize = new Point(MATCH_PARENT,
+ mLauncher.getResources().getDimensionPixelSize(R.dimen.taskbar_size));
+ }
+
+ /**
+ * Initializes the Taskbar, including adding it to the screen.
+ */
+ public void init() {
+ addToWindowManager();
+ }
+
+ /**
+ * Removes the Taskbar from the screen, and removes any obsolete listeners etc.
+ */
+ public void cleanup() {
+ removeFromWindowManager();
+ }
+
+ private void removeFromWindowManager() {
+ if (mTaskbarContainerView.isAttachedToWindow()) {
+ mWindowManager.removeViewImmediate(mTaskbarContainerView);
+ }
+ }
+
+ private void addToWindowManager() {
+ removeFromWindowManager();
+
+ final int gravity = Gravity.BOTTOM;
+
+ mWindowLayoutParams = new WindowManager.LayoutParams(
+ mTaskbarSize.x,
+ mTaskbarSize.y,
+ TYPE_APPLICATION_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+ PixelFormat.TRANSLUCENT);
+ mWindowLayoutParams.setTitle(WINDOW_TITLE);
+ mWindowLayoutParams.packageName = mLauncher.getPackageName();
+ mWindowLayoutParams.gravity = gravity;
+ mWindowLayoutParams.setFitInsetsTypes(0);
+ mWindowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+ mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+ WindowManagerWrapper wmWrapper = WindowManagerWrapper.getInstance();
+ wmWrapper.setProvidesInsetsTypes(
+ mWindowLayoutParams,
+ new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT }
+ );
+
+ TaskbarContainerView.LayoutParams taskbarLayoutParams =
+ new TaskbarContainerView.LayoutParams(mTaskbarSize.x, mTaskbarSize.y);
+ taskbarLayoutParams.gravity = gravity;
+ mTaskbarView.setLayoutParams(taskbarLayoutParams);
+
+ mWindowManager.addView(mTaskbarContainerView, mWindowLayoutParams);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
new file mode 100644
index 0000000..5df8d5f
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.taskbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.LinearLayout;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps.
+ */
+public class TaskbarView extends LinearLayout {
+ public TaskbarView(@NonNull Context context) {
+ this(context, null);
+ }
+
+ public TaskbarView(@NonNull Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public TaskbarView(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public TaskbarView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 1f7cec5..196cae7 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -360,7 +360,7 @@
getString(R.string.all_apps_label),
getString(R.string.all_apps_label),
PendingIntent.getActivity(this, SYSTEM_ACTION_ID_ALL_APPS, intent,
- PendingIntent.FLAG_UPDATE_CURRENT));
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
am.registerSystemAction(allAppsAction, SYSTEM_ACTION_ID_ALL_APPS);
} else {
am.unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index f44f88b..22eb15a 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -72,7 +72,7 @@
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.SearchActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.views.ActivityContext;
@@ -319,14 +319,14 @@
}
/**
- * Apply label and tag using a {@link RemoteActionItemInfo}
+ * Apply label and tag using a {@link SearchActionItemInfo}
*/
- public void applyFromRemoteActionInfo(RemoteActionItemInfo remoteActionItemInfo) {
- applyIconAndLabel(remoteActionItemInfo);
- setTag(remoteActionItemInfo);
+ public void applyFromSearchActionItemInfo(SearchActionItemInfo searchActionItemInfo) {
+ applyIconAndLabel(searchActionItemInfo);
+ setTag(searchActionItemInfo);
}
- private void applyIconAndLabel(ItemInfoWithIcon info) {
+ protected void applyIconAndLabel(ItemInfoWithIcon info) {
FastBitmapDrawable iconDrawable = newIcon(getContext(), info);
mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
@@ -595,7 +595,8 @@
mLongPressHelper.cancelLongPress();
}
- /** Applies the loading progress value to the progress bar.
+ /**
+ * Applies the loading progress value to the progress bar.
*
* If this app is installing, the progress bar will be updated with the installation progress.
* If this app is installed and downloading incrementally, the progress bar will be updated
@@ -609,7 +610,7 @@
!= 0) {
updateProgressBarUi(progressLevel, progressLevel == 100);
} else if (info.hasPromiseIconUi() || (info.runtimeStatusFlags
- & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
+ & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
updateProgressBarUi(progressLevel, promiseStateChanged);
}
}
@@ -765,8 +766,8 @@
mActivity.invalidateParent(info);
} else if (info instanceof PackageItemInfo) {
applyFromItemInfoWithIcon((PackageItemInfo) info);
- } else if (info instanceof RemoteActionItemInfo) {
- applyFromRemoteActionInfo((RemoteActionItemInfo) info);
+ } else if (info instanceof SearchActionItemInfo) {
+ applyFromSearchActionItemInfo((SearchActionItemInfo) info);
}
mDisableRelayout = false;
diff --git a/src/com/android/launcher3/CheckLongPressHelper.java b/src/com/android/launcher3/CheckLongPressHelper.java
index ff405ec..c707df0 100644
--- a/src/com/android/launcher3/CheckLongPressHelper.java
+++ b/src/com/android/launcher3/CheckLongPressHelper.java
@@ -115,7 +115,7 @@
private void triggerLongPress() {
if ((mView.getParent() != null)
&& mView.hasWindowFocus()
- && (!mView.isPressed() || mListener == null)
+ && (!mView.isPressed() || mListener != null)
&& !mHasPerformedLongPress) {
boolean handled;
if (mListener != null) {
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 1d88e83..5fd9e01 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -202,7 +202,7 @@
DisplayController.getDefaultDisplay(context).getInfo(),
getPredefinedDeviceProfiles(context, gridName));
- Info myInfo = new Info(display);
+ Info myInfo = new Info(context, display);
DisplayOption myDisplayOption = invDistWeightedInterpolate(
myInfo, getPredefinedDeviceProfiles(context, gridName));
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 4d51d70..20f7c23 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -547,10 +547,15 @@
return mLauncher.startActivitySafely(v, headerItem.getIntent(), headerItem);
}
AdapterItem focusedItem = getActiveRecyclerView().getApps().getFocusedChild();
- if (mSearchAdapterProvider.onAdapterItemSelected(focusedItem)) {
- return true;
+ if (focusedItem != null) {
+ View focusedView = getActiveRecyclerView().getLayoutManager()
+ .findViewByPosition(focusedItem.position);
+ if (focusedView != null && mSearchAdapterProvider.onAdapterItemSelected(focusedItem,
+ focusedView)) {
+ return true;
+ }
}
- if (focusedItem.appInfo != null) {
+ if (focusedItem != null && focusedItem.appInfo != null) {
ItemInfo itemInfo = focusedItem.appInfo;
return mLauncher.startActivitySafely(v, itemInfo.getIntent(), itemInfo);
}
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index 522f1d4..198c4b2 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -32,10 +32,8 @@
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.PackageManagerHelper;
-import com.android.systemui.plugins.AllAppsSearchPlugin;
import java.util.ArrayList;
-import java.util.function.Consumer;
/**
* An interface to a search box that AllApps can command.
@@ -74,10 +72,7 @@
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
- if (mSearchAlgorithm instanceof PluginWrapper) {
- ((PluginWrapper) mSearchAlgorithm).runOnPluginIfConnected(
- AllAppsSearchPlugin::startedSearchSession);
- }
+ // Do nothing
}
@Override
@@ -174,16 +169,6 @@
}
/**
- * A wrapper setup for running essential calls to plugin from search controller
- */
- public interface PluginWrapper {
- /**
- * executes call if plugin is connected
- */
- void runOnPluginIfConnected(Consumer<AllAppsSearchPlugin> plugin);
- }
-
- /**
* Callback for getting search results.
*/
public interface Callbacks {
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
index e3c178b..330ec68 100644
--- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -16,6 +16,7 @@
package com.android.launcher3.allapps.search;
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
import com.android.launcher3.BaseDraggingActivity;
@@ -47,7 +48,7 @@
}
@Override
- public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem) {
+ public boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem adapterItem, View view) {
return false;
}
}
diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
index 1c7247a..511de30 100644
--- a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
@@ -18,6 +18,7 @@
import android.view.LayoutInflater;
+import android.view.View;
import android.view.ViewGroup;
import com.android.launcher3.BaseDraggingActivity;
@@ -61,5 +62,6 @@
* handles selection event on search adapter item. Returns false if provider can not handle
* event
*/
- public abstract boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem focusedItem);
+ public abstract boolean onAdapterItemSelected(AllAppsGridAdapter.AdapterItem adapterItem,
+ View view);
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 81174d8..1c5c222 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -214,6 +214,9 @@
"ENABLE_APP_PREDICTIONS_WHILE_VISIBLE", true, "Allows app "
+ "predictions to be updated while they are visible to the user.");
+ public static final BooleanFlag ENABLE_TASKBAR = new DeviceFlag(
+ "ENABLE_TASKBAR", false, "Allows a system Taskbar to be shown on larger devices.");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 5e48a0f..d09bf81 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -104,8 +104,10 @@
@WorkerThread
private void addToQueue(PendingInstallShortcutInfo info) {
ensureQueueLoaded();
- mItems.add(info);
- mStorage.write(mContext, mItems);
+ if (!mItems.contains(info)) {
+ mItems.add(info);
+ mStorage.write(mContext, mItems);
+ }
}
@WorkerThread
@@ -303,6 +305,33 @@
}
return null;
}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof PendingInstallShortcutInfo) {
+ PendingInstallShortcutInfo other = (PendingInstallShortcutInfo) obj;
+
+ boolean userMatches = user.equals(other.user);
+ boolean itemTypeMatches = itemType == other.itemType;
+ boolean intentMatches = intent.toUri(0).equals(other.intent.toUri(0));
+ boolean shortcutInfoMatches = shortcutInfo == null
+ ? other.shortcutInfo == null
+ : other.shortcutInfo != null
+ && shortcutInfo.getId().equals(other.shortcutInfo.getId())
+ && shortcutInfo.getPackage().equals(other.shortcutInfo.getPackage());
+ boolean providerInfoMatches = providerInfo == null
+ ? other.providerInfo == null
+ : other.providerInfo != null
+ && providerInfo.provider.equals(other.providerInfo.provider);
+
+ return userMatches
+ && itemTypeMatches
+ && intentMatches
+ && shortcutInfoMatches
+ && providerInfoMatches;
+ }
+ return false;
+ }
}
private static String getIntentPackage(Intent intent) {
diff --git a/src/com/android/launcher3/model/data/RemoteActionItemInfo.java b/src/com/android/launcher3/model/data/RemoteActionItemInfo.java
deleted file mode 100644
index d988bf9..0000000
--- a/src/com/android/launcher3/model/data/RemoteActionItemInfo.java
+++ /dev/null
@@ -1,68 +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.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;
- }
-
- public boolean isEscapeHatch() {
- return mToken.contains("item_type:[ESCAPE_HATCH]");
- }
-}
diff --git a/src/com/android/launcher3/model/data/SearchActionItemInfo.java b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
new file mode 100644
index 0000000..1831ffd
--- /dev/null
+++ b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2021 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.PendingIntent;
+import android.content.Intent;
+import android.graphics.drawable.Icon;
+import android.os.Process;
+import android.os.UserHandle;
+
+/**
+ * Represents a SearchAction with in launcher
+ */
+public class SearchActionItemInfo extends ItemInfoWithIcon {
+
+ public static final int FLAG_SHOULD_START = 1 << 1;
+ public static final int FLAG_SHOULD_START_FOR_RESULT = FLAG_SHOULD_START | 1 << 2;
+
+ private final String mFallbackPackageName;
+
+ private int mFlags = 0;
+ private final Icon mIcon;
+
+ private Intent mIntent;
+
+ private PendingIntent mPendingIntent;
+
+ public SearchActionItemInfo(Icon icon, String packageName, UserHandle user,
+ CharSequence title) {
+ this.user = user == null ? Process.myUserHandle() : user;
+ this.title = title;
+ mFallbackPackageName = packageName;
+ mIcon = icon;
+ }
+
+ public SearchActionItemInfo(SearchActionItemInfo info) {
+ super(info);
+ mIcon = info.mIcon;
+ mFallbackPackageName = info.mFallbackPackageName;
+ mFlags = info.mFlags;
+ title = info.title;
+ }
+
+ public void setFlags(int flags) {
+ mFlags = flags;
+ }
+
+ public int getFlags() {
+ return mFlags;
+ }
+
+ @Override
+ public Intent getIntent() {
+ return mIntent;
+ }
+
+ /**
+ * Setter for mIntent with assertion for null value mPendingIntent
+ */
+ public void setIntent(Intent intent) {
+ if (mPendingIntent != null && intent != null) {
+ throw new RuntimeException(
+ "SearchActionItemInfo can only have either an Intent or a PendingIntent");
+ }
+ mIntent = intent;
+ }
+
+ public PendingIntent getPendingIntent() {
+ return mPendingIntent;
+ }
+
+ /**
+ * Setter of mPendingIntent with assertion for null value mIntent
+ */
+ public void setPendingIntent(PendingIntent pendingIntent) {
+ if (mIntent != null && pendingIntent != null) {
+ throw new RuntimeException(
+ "SearchActionItemInfo can only have either an Intent or a PendingIntent");
+ }
+ mPendingIntent = pendingIntent;
+ }
+
+
+ /**
+ * Returns if a flag is set on instance
+ */
+ public boolean hasFlag(int flag) {
+ return (mFlags & flag) == flag;
+ }
+
+ @Override
+ public ItemInfoWithIcon clone() {
+ return new SearchActionItemInfo(this);
+ }
+
+ public Icon getIcon() {
+ return mIcon;
+ }
+}
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 4158735..d9483e5 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -51,7 +51,7 @@
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.model.data.RemoteActionItemInfo;
+import com.android.launcher3.model.data.SearchActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.testing.TestLogging;
@@ -96,8 +96,8 @@
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
}
- } else if (tag instanceof RemoteActionItemInfo) {
- onClickRemoteAction(launcher, (RemoteActionItemInfo) tag);
+ } else if (tag instanceof SearchActionItemInfo) {
+ onClickSearchAction(launcher, (SearchActionItemInfo) tag);
}
}
@@ -246,23 +246,31 @@
}
/**
- * Event handler for a {@link android.app.RemoteAction} click
- *
+ * Event handler for a {@link SearchActionItemInfo} 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);
+ public static void onClickSearchAction(Launcher launcher, SearchActionItemInfo itemInfo) {
+ if (itemInfo.getIntent() != null) {
+ if (itemInfo.hasFlag(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) {
+ launcher.startActivityForResult(itemInfo.getIntent(), 0);
} else {
- pendingIntent.send();
+ launcher.startActivity(itemInfo.getIntent());
}
- } catch (PendingIntent.CanceledException | IntentSender.SendIntentException e) {
- Toast.makeText(launcher,
- launcher.getResources().getText(R.string.shortcut_not_available),
- Toast.LENGTH_SHORT).show();
+ } else if (itemInfo.getPendingIntent() != null) {
+ try {
+ PendingIntent pendingIntent = itemInfo.getPendingIntent();
+ if (!itemInfo.hasFlag(SearchActionItemInfo.FLAG_SHOULD_START)) {
+ pendingIntent.send();
+ } else if (itemInfo.hasFlag(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) {
+ launcher.startIntentSenderForResult(pendingIntent.getIntentSender(), 0, null, 0,
+ 0, 0);
+ } else {
+ launcher.startIntentSender(pendingIntent.getIntentSender(), null, 0, 0, 0);
+ }
+ } catch (PendingIntent.CanceledException | IntentSender.SendIntentException e) {
+ Toast.makeText(launcher,
+ launcher.getResources().getText(R.string.shortcut_not_available),
+ Toast.LENGTH_SHORT).show();
+ }
}
}
@@ -272,7 +280,7 @@
Intent intent;
if (item instanceof ItemInfoWithIcon
&& (((ItemInfoWithIcon) item).runtimeStatusFlags
- & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
+ & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
ItemInfoWithIcon appInfo = (ItemInfoWithIcon) item;
intent = new PackageManagerHelper(launcher)
.getMarketIntent(appInfo.getTargetComponent().getPackageName());
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 3ab736a..355c949 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -31,8 +31,6 @@
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.Utilities;
-
import java.util.ArrayList;
/**
@@ -159,13 +157,13 @@
private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
private DisplayController.Info mInfo;
- private DisplayHolder(Context displayContext, Display display) {
+ private DisplayHolder(Context displayContext) {
mDisplayContext = displayContext;
// Note that the Display object must be obtained from DisplayManager which is
// associated to the display context, so the Display is isolated from Activity and
// Application to provide the actual state of device that excludes the additional
// adjustment and override.
- mInfo = new DisplayController.Info(display);
+ mInfo = new DisplayController.Info(mDisplayContext);
mId = mInfo.id;
}
@@ -182,31 +180,22 @@
}
protected void handleOnChange() {
- Display display = Utilities.ATLEAST_R
- ? mDisplayContext.getDisplay()
- : mDisplayContext
- .getSystemService(DisplayManager.class)
- .getDisplay(mId);
- if (display == null) {
- return;
- }
-
Info oldInfo = mInfo;
- Info newInfo = new Info(display);
+ Info info = new Info(mDisplayContext);
int change = 0;
- if (newInfo.hasDifferentSize(oldInfo)) {
+ if (info.hasDifferentSize(oldInfo)) {
change |= CHANGE_SIZE;
}
- if (newInfo.rotation != oldInfo.rotation) {
+ if (oldInfo.rotation != info.rotation) {
change |= CHANGE_ROTATION;
}
- if (newInfo.singleFrameMs != oldInfo.singleFrameMs) {
+ if (info.singleFrameMs != oldInfo.singleFrameMs) {
change |= CHANGE_FRAME_DELAY;
}
if (change != 0) {
- mInfo = newInfo;
+ mInfo = info;
final int flags = change;
MAIN_EXECUTOR.execute(() -> notifyChange(flags));
}
@@ -227,7 +216,7 @@
// Use application context to create display context so that it can have its own
// Resources.
Context displayContext = context.getApplicationContext().createDisplayContext(display);
- return new DisplayHolder(displayContext, display);
+ return new DisplayHolder(displayContext);
}
}
@@ -255,7 +244,12 @@
this.metrics = metrics;
}
- public Info(Display display) {
+ private Info(Context context) {
+ this(context, context.getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY));
+ }
+
+ public Info(Context context, Display display) {
id = display.getDisplayId();
rotation = display.getRotation();
@@ -268,8 +262,7 @@
display.getRealSize(realSize);
display.getCurrentSizeRange(smallestSize, largestSize);
- metrics = new DisplayMetrics();
- display.getMetrics(metrics);
+ metrics = context.getResources().getDisplayMetrics();
}
private boolean hasDifferentSize(Info info) {
diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java
index fab0bd4..4e82336 100644
--- a/src/com/android/launcher3/views/ClipIconView.java
+++ b/src/com/android/launcher3/views/ClipIconView.java
@@ -161,6 +161,11 @@
float scaleY = rect.height() / minSize;
float scale = Math.max(1f, Math.min(scaleX, scaleY));
+ if (Float.isNaN(scale)) {
+ // Views are no longer laid out, do not update.
+ return;
+ }
+
update(rect, progress, shapeProgressStart, cornerRadius, isOpening, scale,
minSize, lp, isVerticalBarLayout, dp);