Support People search result in launcher

NOTE: this uses PackageManager and should be removed after people<>shortcut mapping in search provider.

Bug: 166337069
Test: Manual
Change-Id: I016ff0d5e6ada1599cce3d75bdcd55347c85193e
This commit is contained in:
Samuel Fufa 2020-09-08 14:00:56 -07:00
parent 7aa577d883
commit 35f9150a67
3 changed files with 225 additions and 0 deletions

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher3.views.SearchResultPeopleView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:gravity="center_vertical"
android:layout_height="wrap_content"
android:padding="8dp"
android:orientation="horizontal">
<View
android:id="@+id/icon"
android:layout_marginRight="8dp"
android:layout_width="@dimen/default_icon_bitmap_size"
android:layout_height="@dimen/default_icon_bitmap_size" />
<TextView
android:layout_width="0dp"
android:textColor="?android:attr/textColorPrimary"
android:id="@+id/title"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="@+id/provider_0"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:layout_margin="5dp"
android:background="?android:attr/selectableItemBackground"
android:layout_width="@dimen/default_icon_bitmap_size"
android:layout_height="@dimen/default_icon_bitmap_size" />
<ImageButton
android:id="@+id/provider_1"
android:layout_margin="5dp"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:background="?android:attr/selectableItemBackground"
android:layout_width="@dimen/default_icon_bitmap_size"
android:layout_height="@dimen/default_icon_bitmap_size" />
<ImageButton
android:id="@+id/provider_2"
android:layout_margin="5dp"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:background="?android:attr/selectableItemBackground"
android:layout_width="@dimen/default_icon_bitmap_size"
android:layout_height="@dimen/default_icon_bitmap_size" />
</com.android.launcher3.views.SearchResultPeopleView>

View File

@ -91,6 +91,8 @@ public class AllAppsGridAdapter extends
public static final int VIEW_TYPE_SEARCH_SHORTCUT = 1 << 10;
public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11;
// Common view type masks
public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
@ -182,6 +184,7 @@ public class AllAppsGridAdapter extends
|| viewType == VIEW_TYPE_SEARCH_ROW_WITH_BUTTON
|| viewType == VIEW_TYPE_SEARCH_SLICE
|| viewType == VIEW_TYPE_SEARCH_ROW
|| viewType == VIEW_TYPE_SEARCH_PEOPLE
|| viewType == VIEW_TYPE_SEARCH_SHORTCUT;
}
}
@ -432,6 +435,9 @@ public class AllAppsGridAdapter extends
case VIEW_TYPE_SEARCH_SHORTCUT:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.search_result_shortcut, parent, false));
case VIEW_TYPE_SEARCH_PEOPLE:
return new ViewHolder(mLayoutInflater.inflate(
R.layout.search_result_people_item, parent, false));
default:
throw new RuntimeException("Unexpected view type");
}
@ -475,6 +481,7 @@ public class AllAppsGridAdapter extends
case VIEW_TYPE_SEARCH_HERO_APP:
case VIEW_TYPE_SEARCH_ROW:
case VIEW_TYPE_SEARCH_SHORTCUT:
case VIEW_TYPE_SEARCH_PEOPLE:
PayloadResultHandler payloadResultView = (PayloadResultHandler) holder.itemView;
payloadResultView.applyAdapterInfo(
(AdapterItemWithPayload) mApps.getAdapterItems().get(position));

View File

@ -0,0 +1,156 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.views;
import static android.content.Intent.URI_ALLOW_UNSAFE;
import static android.content.Intent.URI_ANDROID_APP_SCHEME;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
import com.android.launcher3.util.Themes;
import java.net.URISyntaxException;
import java.util.ArrayList;
/**
* A view representing a single people search result in all apps
*/
public class SearchResultPeopleView extends LinearLayout implements
AllAppsSearchBarController.PayloadResultHandler<Bundle> {
private final int mIconSize;
private final int mButtonSize;
private final PackageManager mPackageManager;
View mIconView;
TextView mTitleView;
ImageButton[] mProviderButtons = new ImageButton[3];
public SearchResultPeopleView(Context context) {
this(context, null, 0);
}
public SearchResultPeopleView(Context context,
@Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SearchResultPeopleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
DeviceProfile deviceProfile = Launcher.getLauncher(getContext()).getDeviceProfile();
mPackageManager = getContext().getPackageManager();
mIconSize = deviceProfile.iconSizePx;
mButtonSize = (int) (deviceProfile.iconSizePx / 1.5f);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mIconView = findViewById(R.id.icon);
mIconView.getLayoutParams().height = mIconSize;
mIconView.getLayoutParams().width = mIconSize;
mTitleView = findViewById(R.id.title);
mProviderButtons[0] = findViewById(R.id.provider_0);
mProviderButtons[1] = findViewById(R.id.provider_1);
mProviderButtons[2] = findViewById(R.id.provider_2);
for (ImageButton button : mProviderButtons) {
button.getLayoutParams().width = mButtonSize;
button.getLayoutParams().height = mButtonSize;
}
setOnClickListener(v -> handleSelection());
}
@Override
public void applyAdapterInfo(
AllAppsGridAdapter.AdapterItemWithPayload<Bundle> adapterItemWithPayload) {
Launcher launcher = Launcher.getLauncher(getContext());
Bundle payload = adapterItemWithPayload.getPayload();
mTitleView.setText(payload.getString("title"));
mContactUri = payload.getParcelable("contact_uri");
Bitmap icon = payload.getParcelable("icon");
if (icon != null) {
RoundedBitmapDrawable d = RoundedBitmapDrawableFactory.create(getResources(), icon);
float radius = Themes.getDialogCornerRadius(getContext());
d.setCornerRadius(radius);
d.setBounds(0, 0, mIconSize, mIconSize);
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(),
Bitmap.createScaledBitmap(icon, mIconSize, mIconSize, false));
mIconView.setBackground(d);
}
ArrayList<Bundle> providers = payload.getParcelableArrayList("providers");
for (int i = 0; i < mProviderButtons.length; i++) {
ImageButton button = mProviderButtons[i];
if (providers != null && i < providers.size()) {
try {
Bundle provider = providers.get(i);
Intent intent = Intent.parseUri(provider.getString("intent_uri_str"),
URI_ANDROID_APP_SCHEME | URI_ALLOW_UNSAFE);
String pkg = provider.getString("package_name");
button.setOnClickListener(b -> launcher.startActivitySafely(b, intent, null));
UI_HELPER_EXECUTOR.post(() -> {
try {
ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(
pkg, 0);
Drawable appIcon = applicationInfo.loadIcon(mPackageManager);
button.setImageDrawable(appIcon);
} catch (PackageManager.NameNotFoundException ignored) {
}
});
} catch (URISyntaxException ex) {
button.setVisibility(GONE);
}
} else {
button.setVisibility(GONE);
}
}
adapterItemWithPayload.setSelectionHandler(this::handleSelection);
}
Uri mContactUri;
private void handleSelection() {
if (mContactUri != null) {
Launcher launcher = Launcher.getLauncher(getContext());
launcher.startActivitySafely(this, new Intent(Intent.ACTION_VIEW, mContactUri).setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK), null);
}
}
}