diff --git a/res/layout/search_result_icon_row.xml b/res/layout/search_result_icon_row.xml index b51896e8a7..280bbc992c 100644 --- a/res/layout/search_result_icon_row.xml +++ b/res/layout/search_result_icon_row.xml @@ -40,13 +40,13 @@ android:gravity="start|center_vertical" android:textAlignment="viewStart" android:textColor="?android:attr/textColorPrimary" - android:textSize="@dimen/settings_hero_title_size" /> + android:textSize="@dimen/search_hero_title_size" /> @@ -57,7 +57,7 @@ android:layout_height="match_parent" android:gravity="start|center_vertical" launcher:iconDisplay="shortcut_popup" - android:textSize="@dimen/settings_hero_subtitle_size" + android:textSize="@dimen/search_hero_subtitle_size" launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" launcher:layoutHorizontal="false" /> @@ -67,7 +67,7 @@ android:layout_width="@dimen/deep_shortcut_icon_size" android:layout_height="match_parent" launcher:iconDisplay="shortcut_popup" - android:textSize="@dimen/settings_hero_inline_button_size" + android:textSize="@dimen/search_hero_inline_button_size" launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" launcher:layoutHorizontal="false" /> diff --git a/res/layout/search_result_settings_row.xml b/res/layout/search_result_settings_row.xml index 19daf346e2..05f7561628 100644 --- a/res/layout/search_result_settings_row.xml +++ b/res/layout/search_result_settings_row.xml @@ -18,40 +18,42 @@ android:background="?android:attr/selectableItemBackground" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" + android:orientation="horizontal" android:gravity="center_vertical" - android:padding="4dp" - android:minHeight="48dp" - android:textColor="?android:attr/textColorPrimary" - android:textSize="14sp"> + android:padding="@dimen/dynamic_grid_cell_padding_x" + android:textColor="?android:attr/textColorPrimary"> - + + - - - - + android:layout_weight="1"> + + + + \ No newline at end of file diff --git a/res/layout/search_result_slice.xml b/res/layout/search_result_slice.xml index ea1d49a56d..24d75e9eb6 100644 --- a/res/layout/search_result_slice.xml +++ b/res/layout/search_result_slice.xml @@ -1,5 +1,4 @@ - - - \ No newline at end of file + android:layout_height="wrap_content"> + + + + + + + + + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 5387e1bad6..7df3f774e5 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -249,8 +249,11 @@ 24dp - 16sp - 15sp - 12sp + 16sp + 15sp + 12sp + 36dp + 16dp + 4dp diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index 7018f20a55..434bc1453d 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -37,7 +37,6 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityRecordCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.slice.widget.SliceView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.BubbleTextView; @@ -47,7 +46,6 @@ import com.android.launcher3.allapps.search.SearchSectionInfo; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.util.PackageManagerHelper; -import com.android.launcher3.views.SearchSliceWrapper; import com.android.systemui.plugins.shared.SearchTarget; import java.util.List; @@ -461,17 +459,10 @@ public class AllAppsGridAdapter extends } else { searchView.setVisibility(View.GONE); } - break; - case VIEW_TYPE_SEARCH_SLICE: - SliceView sliceView = (SliceView) holder.itemView; - SearchAdapterItem slicePayload = (SearchAdapterItem) mApps.getAdapterItems().get( - position); - SearchTarget searchTarget = slicePayload.getSearchTarget(); - sliceView.setTag(new SearchSliceWrapper(mLauncher, sliceView, searchTarget)); - break; case VIEW_TYPE_SEARCH_CORPUS_TITLE: case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON: + case VIEW_TYPE_SEARCH_SLICE: case VIEW_TYPE_SEARCH_ROW: case VIEW_TYPE_SEARCH_ICON: case VIEW_TYPE_SEARCH_ICON_ROW: @@ -496,13 +487,6 @@ public class AllAppsGridAdapter extends if (holder.itemView instanceof AllAppsSectionDecorator.SelfDecoratingView) { ((AllAppsSectionDecorator.SelfDecoratingView) holder.itemView).removeDecoration(); } - if (holder.itemView instanceof SliceView) { - SliceView sliceView = (SliceView) holder.itemView; - if (sliceView.getTag() instanceof SearchSliceWrapper) { - ((SearchSliceWrapper) sliceView.getTag()).destroy(); - } - sliceView.setTag(null); - } } @Override diff --git a/src/com/android/launcher3/views/SearchSliceWrapper.java b/src/com/android/launcher3/views/SearchResultSettingsSlice.java similarity index 50% rename from src/com/android/launcher3/views/SearchSliceWrapper.java rename to src/com/android/launcher3/views/SearchResultSettingsSlice.java index f8a7dc08d6..2d726e79d4 100644 --- a/src/com/android/launcher3/views/SearchSliceWrapper.java +++ b/src/com/android/launcher3/views/SearchResultSettingsSlice.java @@ -17,9 +17,13 @@ package com.android.launcher3.views; 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; +import androidx.annotation.Nullable; import androidx.lifecycle.LiveData; import androidx.slice.Slice; import androidx.slice.SliceItem; @@ -28,55 +32,98 @@ import androidx.slice.widget.SliceLiveData; import androidx.slice.widget.SliceView; import com.android.launcher3.Launcher; +import com.android.launcher3.R; +import com.android.launcher3.allapps.search.AllAppsSearchBarController; import com.android.launcher3.allapps.search.SearchEventTracker; import com.android.systemui.plugins.shared.SearchTarget; import com.android.systemui.plugins.shared.SearchTargetEvent; /** - * A Wrapper class for {@link SliceView} search results + * A slice view wrapper with settings app icon at start */ -public class SearchSliceWrapper implements SliceView.OnSliceActionListener { +public class SearchResultSettingsSlice extends LinearLayout implements + AllAppsSearchBarController.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 final Launcher mLauncher; - private final SearchTarget mSearchTarget; - private final SliceView mSliceView; + private SliceView mSliceView; + private View mIcon; private LiveData mSliceLiveData; + private SearchTarget mSearchTarget; + private Launcher mLauncher; - public SearchSliceWrapper(Context context, SliceView sliceView, SearchTarget searchTarget) { - mLauncher = Launcher.getLauncher(context); + public SearchResultSettingsSlice(Context context) { + this(context, null, 0); + } + + public SearchResultSettingsSlice(Context context, + @Nullable AttributeSet attrs) { + this(context, attrs, 0); + } + + public SearchResultSettingsSlice(Context context, @Nullable AttributeSet attrs, + int defStyleAttr) { + super(context, attrs, defStyleAttr); + mLauncher = Launcher.getLauncher(getContext()); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mSliceView = findViewById(R.id.slice); + mIcon = findViewById(R.id.icon); + SearchSettingsRowView.applySettingsIcon(mLauncher, mIcon); + } + + @Override + public void applySearchTarget(SearchTarget searchTarget) { + reset(); mSearchTarget = searchTarget; - mSliceView = sliceView; - sliceView.setOnSliceActionListener(this); try { mSliceLiveData = SliceLiveData.fromUri(mLauncher, getSliceUri()); - mSliceLiveData.observe((Launcher) mLauncher, sliceView); + mSliceLiveData.observe(mLauncher, mSliceView); } catch (Exception ex) { Log.e(TAG, "unable to bind slice", ex); } } - /** - * Unregisters event handlers and removes lifecycle observer - */ - public void destroy() { - mSliceView.setOnSliceActionListener(null); - mSliceLiveData.removeObservers(mLauncher); + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mSliceView.setOnSliceActionListener(this); } @Override - public void onSliceAction(@NonNull EventInfo info, @NonNull SliceItem item) { + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + reset(); + } + + @Override + public void handleSelection(int eventType) { SearchEventTracker.INSTANCE.get(mLauncher).notifySearchTargetEvent( new SearchTargetEvent.Builder(mSearchTarget, SearchTargetEvent.CHILD_SELECT).build()); } + private void reset() { + mSliceView.setOnSliceActionListener(null); + if (mSliceLiveData != null) { + mSliceLiveData.removeObservers(mLauncher); + } + } + + @Override + public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) { + handleSelection(SearchTargetEvent.CHILD_SELECT); + } + private Uri getSliceUri() { return mSearchTarget.getExtras().getParcelable(URI_EXTRA_KEY); } + } diff --git a/src/com/android/launcher3/views/SearchSettingsRowView.java b/src/com/android/launcher3/views/SearchSettingsRowView.java index f0884f88aa..160ee6514b 100644 --- a/src/com/android/launcher3/views/SearchSettingsRowView.java +++ b/src/com/android/launcher3/views/SearchSettingsRowView.java @@ -15,8 +15,14 @@ */ package com.android.launcher3.views; +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.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; @@ -27,38 +33,41 @@ 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.allapps.search.AllAppsSearchBarController; import com.android.launcher3.allapps.search.SearchEventTracker; +import com.android.launcher3.model.data.PackageItemInfo; import com.android.systemui.plugins.shared.SearchTarget; import com.android.systemui.plugins.shared.SearchTargetEvent; import java.util.ArrayList; +import java.util.List; /** - * A row of tappable TextViews with a breadcrumb for settings search. + * A row of clickable TextViews with a breadcrumb for settings search. */ public class SearchSettingsRowView extends LinearLayout implements View.OnClickListener, AllAppsSearchBarController.SearchTargetHandler { public static final String TARGET_TYPE_SETTINGS_ROW = "settings_row"; - + private View mIconView; private TextView mTitleView; - private TextView mDescriptionView; private TextView mBreadcrumbsView; private Intent mIntent; private SearchTarget mSearchTarget; public SearchSettingsRowView(@NonNull Context context) { - super(context); + this(context, null, 0); } public SearchSettingsRowView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); + this(context, attrs, 0); } public SearchSettingsRowView(@NonNull Context context, @Nullable AttributeSet attrs, @@ -69,10 +78,11 @@ public class SearchSettingsRowView extends LinearLayout implements @Override protected void onFinishInflate() { super.onFinishInflate(); + mIconView = findViewById(R.id.icon); mTitleView = findViewById(R.id.title); - mDescriptionView = findViewById(R.id.description); mBreadcrumbsView = findViewById(R.id.breadcrumbs); setOnClickListener(this); + applySettingsIcon(Launcher.getLauncher(getContext()), mIconView); } @Override @@ -81,6 +91,7 @@ public class SearchSettingsRowView extends LinearLayout implements Bundle bundle = searchTarget.getExtras(); mIntent = bundle.getParcelable("intent"); showIfAvailable(mTitleView, bundle.getString("title")); + mIconView.setContentDescription(bundle.getString("title")); ArrayList breadcrumbs = bundle.getStringArrayList("breadcrumbs"); //TODO: implement RTL friendly breadcrumbs view showIfAvailable(mBreadcrumbsView, breadcrumbs != null @@ -113,4 +124,30 @@ public class SearchSettingsRowView extends LinearLayout implements SearchEventTracker.INSTANCE.get(getContext()).notifySearchTargetEvent( new SearchTargetEvent.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 resolveInfos = launcher.getPackageManager().queryIntentActivities(intent, + PackageManager.MATCH_DEFAULT_ONLY); + if (resolveInfos.size() == 0) { + return ""; + } + return resolveInfos.get(0).activityInfo.packageName; + } }