Merge "Support Remote actions" into ub-launcher3-master
This commit is contained in:
commit
35879a3fdb
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.views.SearchResultIconRow xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/BaseIcon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:padding="@dimen/dynamic_grid_edge_margin"
|
||||
launcher:iconDisplay="hero_app"
|
||||
launcher:layoutHorizontal="true"
|
||||
>
|
||||
|
||||
</com.android.launcher3.views.SearchResultIconRow>
|
|
@ -1,42 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.views.SearchResultShortcut xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:launcher="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="@dimen/dynamic_grid_edge_margin">
|
||||
|
||||
<com.android.launcher3.BubbleTextView
|
||||
android:id="@+id/bubble_text"
|
||||
style="@style/BaseIcon"
|
||||
android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textAlignment="viewStart"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:layout_height="wrap_content"
|
||||
launcher:iconDisplay="hero_app"
|
||||
launcher:layoutHorizontal="true" />
|
||||
|
||||
<View
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/deep_shortcut_icon_size"
|
||||
android:layout_height="@dimen/deep_shortcut_icon_size"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:background="@drawable/ic_deepshortcut_placeholder" />
|
||||
|
||||
</com.android.launcher3.views.SearchResultShortcut>
|
|
@ -65,6 +65,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.PromiseAppInfo;
|
||||
import com.android.launcher3.model.data.RemoteActionItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.util.SafeCloseable;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
|
@ -300,6 +301,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
verifyHighRes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply label and tag using a {@link RemoteActionItemInfo}
|
||||
*/
|
||||
public void applyFromRemoteActionInfo(RemoteActionItemInfo remoteActionItemInfo) {
|
||||
applyIconAndLabel(remoteActionItemInfo);
|
||||
setTag(remoteActionItemInfo);
|
||||
}
|
||||
|
||||
private void applyIconAndLabel(ItemInfoWithIcon info) {
|
||||
FastBitmapDrawable iconDrawable = newIcon(getContext(), info);
|
||||
mDotParams.color = IconPalette.getMutedColor(info.bitmap.color, 0.54f);
|
||||
|
@ -681,6 +690,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
|||
mActivity.invalidateParent(info);
|
||||
} else if (info instanceof PackageItemInfo) {
|
||||
applyFromItemInfoWithIcon((PackageItemInfo) info);
|
||||
} else if (info instanceof RemoteActionItemInfo) {
|
||||
applyFromRemoteActionInfo((RemoteActionItemInfo) info);
|
||||
}
|
||||
|
||||
mDisableRelayout = false;
|
||||
|
|
|
@ -92,7 +92,7 @@ public class AllAppsGridAdapter extends
|
|||
|
||||
public static final int VIEW_TYPE_SEARCH_SLICE = 1 << 9;
|
||||
|
||||
public static final int VIEW_TYPE_SEARCH_SHORTCUT = 1 << 10;
|
||||
public static final int VIEW_TYPE_SEARCH_ICON_ROW = 1 << 10;
|
||||
|
||||
public static final int VIEW_TYPE_SEARCH_PEOPLE = 1 << 11;
|
||||
|
||||
|
@ -189,7 +189,7 @@ public class AllAppsGridAdapter extends
|
|||
|| viewType == VIEW_TYPE_SEARCH_ROW
|
||||
|| viewType == VIEW_TYPE_SEARCH_PEOPLE
|
||||
|| viewType == VIEW_TYPE_SEARCH_THUMBNAIL
|
||||
|| viewType == VIEW_TYPE_SEARCH_SHORTCUT;
|
||||
|| viewType == VIEW_TYPE_SEARCH_ICON_ROW;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -458,9 +458,9 @@ public class AllAppsGridAdapter extends
|
|||
case VIEW_TYPE_SEARCH_SLICE:
|
||||
return new ViewHolder(mLayoutInflater.inflate(
|
||||
R.layout.search_result_slice, parent, false));
|
||||
case VIEW_TYPE_SEARCH_SHORTCUT:
|
||||
case VIEW_TYPE_SEARCH_ICON_ROW:
|
||||
return new ViewHolder(mLayoutInflater.inflate(
|
||||
R.layout.search_result_shortcut, parent, false));
|
||||
R.layout.search_result_icon_row, parent, false));
|
||||
case VIEW_TYPE_SEARCH_PEOPLE:
|
||||
return new ViewHolder(mLayoutInflater.inflate(
|
||||
R.layout.search_result_people_item, parent, false));
|
||||
|
@ -551,7 +551,7 @@ public class AllAppsGridAdapter extends
|
|||
case VIEW_TYPE_SEARCH_ROW_WITH_BUTTON:
|
||||
case VIEW_TYPE_SEARCH_HERO_APP:
|
||||
case VIEW_TYPE_SEARCH_ROW:
|
||||
case VIEW_TYPE_SEARCH_SHORTCUT:
|
||||
case VIEW_TYPE_SEARCH_ICON_ROW:
|
||||
case VIEW_TYPE_SEARCH_PEOPLE:
|
||||
case VIEW_TYPE_SEARCH_THUMBNAIL:
|
||||
AdapterItemWithPayload item =
|
||||
|
@ -571,8 +571,8 @@ public class AllAppsGridAdapter extends
|
|||
if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) return;
|
||||
if (holder.itemView instanceof BubbleTextView) {
|
||||
BubbleTextView icon = (BubbleTextView) holder.itemView;
|
||||
icon.setOnClickListener(mOnIconClickListener);
|
||||
icon.setOnLongClickListener(mOnIconLongClickListener);
|
||||
icon.setOnClickListener(null);
|
||||
icon.setOnLongClickListener(null);
|
||||
} else if (holder.itemView instanceof SliceView) {
|
||||
SliceView sliceView = (SliceView) holder.itemView;
|
||||
sliceView.setOnSliceActionListener(null);
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.model.data;
|
||||
|
||||
import android.app.RemoteAction;
|
||||
import android.os.Process;
|
||||
|
||||
/**
|
||||
* Represents a launchable {@link RemoteAction}
|
||||
*/
|
||||
public class RemoteActionItemInfo extends ItemInfoWithIcon {
|
||||
|
||||
private final RemoteAction mRemoteAction;
|
||||
private final String mToken;
|
||||
private final boolean mShouldStart;
|
||||
|
||||
public RemoteActionItemInfo(RemoteAction remoteAction, String token, boolean shouldStart) {
|
||||
mShouldStart = shouldStart;
|
||||
mToken = token;
|
||||
mRemoteAction = remoteAction;
|
||||
title = remoteAction.getTitle();
|
||||
user = Process.myUserHandle();
|
||||
}
|
||||
|
||||
public RemoteActionItemInfo(RemoteActionItemInfo info) {
|
||||
super(info);
|
||||
this.mShouldStart = info.mShouldStart;
|
||||
this.mRemoteAction = info.mRemoteAction;
|
||||
this.mToken = info.mToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemInfoWithIcon clone() {
|
||||
return new RemoteActionItemInfo(this);
|
||||
}
|
||||
|
||||
public RemoteAction getRemoteAction() {
|
||||
return mRemoteAction;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return mToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method for mShouldStart
|
||||
*/
|
||||
public boolean shouldStartInLauncher() {
|
||||
return mShouldStart;
|
||||
}
|
||||
}
|
|
@ -25,7 +25,9 @@ import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SA
|
|||
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageInstaller.SessionInfo;
|
||||
import android.os.Process;
|
||||
|
@ -49,6 +51,7 @@ import com.android.launcher3.model.data.FolderInfo;
|
|||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
|
||||
import com.android.launcher3.model.data.PromiseAppInfo;
|
||||
import com.android.launcher3.model.data.RemoteActionItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.pm.InstallSessionHelper;
|
||||
import com.android.launcher3.testing.TestLogging;
|
||||
|
@ -236,6 +239,27 @@ public class ItemClickHandler {
|
|||
startAppShortcutOrInfoActivity(v, shortcut, launcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handler for a {@link android.app.RemoteAction} click
|
||||
*
|
||||
*/
|
||||
public static void onClickRemoteAction(Launcher launcher,
|
||||
RemoteActionItemInfo remoteActionInfo) {
|
||||
try {
|
||||
PendingIntent pendingIntent = remoteActionInfo.getRemoteAction().getActionIntent();
|
||||
if (remoteActionInfo.shouldStartInLauncher()) {
|
||||
launcher.startIntentSenderForResult(pendingIntent.getIntentSender(), 0, null, 0, 0,
|
||||
0);
|
||||
} else {
|
||||
pendingIntent.send();
|
||||
}
|
||||
} catch (PendingIntent.CanceledException | IntentSender.SendIntentException e) {
|
||||
Toast.makeText(launcher,
|
||||
launcher.getResources().getText(R.string.shortcut_not_available),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
|
||||
TestLogging.recordEvent(
|
||||
TestProtocol.SEQUENCE_MAIN, "start: startAppShortcutOrInfoActivity");
|
||||
|
|
|
@ -138,7 +138,7 @@ public class HeroSearchResultView extends LinearLayout implements DragSource,
|
|||
if (i < shortcutDetails.size()) {
|
||||
Pair<ShortcutInfo, ItemInfoWithIcon> p = shortcutDetails.get(i);
|
||||
//apply ItemInfo and prepare view
|
||||
shortcutView.applyFromItemInfoWithIcon(p.second);
|
||||
shortcutView.applyFromWorkspaceItem((WorkspaceItemInfo) p.second);
|
||||
MODEL_EXECUTOR.execute(() -> {
|
||||
// load unbadged shortcut in background and update view when icon ready
|
||||
appState.getIconCache().getUnbadgedShortcutIcon(p.second, p.first);
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.views;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.app.RemoteAction;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItemWithPayload;
|
||||
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.ItemInfoWithIcon;
|
||||
import com.android.launcher3.model.data.RemoteActionItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.systemui.plugins.AllAppsSearchPlugin;
|
||||
import com.android.systemui.plugins.shared.SearchTarget;
|
||||
import com.android.systemui.plugins.shared.SearchTargetEvent;
|
||||
|
||||
/**
|
||||
* A view representing a stand alone shortcut search result
|
||||
*/
|
||||
public class SearchResultIconRow extends DoubleShadowBubbleTextView implements
|
||||
AllAppsSearchBarController.PayloadResultHandler<SearchTarget> {
|
||||
|
||||
private final Object[] mTargetInfo = createTargetInfo();
|
||||
private ShortcutInfo mShortcutInfo;
|
||||
private AllAppsSearchPlugin mPlugin;
|
||||
private AdapterItemWithPayload<SearchTarget> mAdapterItem;
|
||||
|
||||
|
||||
public SearchResultIconRow(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SearchResultIconRow(@NonNull Context context,
|
||||
@Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SearchResultIconRow(@NonNull Context context, @Nullable AttributeSet attrs,
|
||||
int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyAdapterInfo(AdapterItemWithPayload<SearchTarget> adapterItemWithPayload) {
|
||||
if (mAdapterItem != null) {
|
||||
mAdapterItem.setSelectionHandler(null);
|
||||
}
|
||||
mAdapterItem = adapterItemWithPayload;
|
||||
SearchTarget payload = adapterItemWithPayload.getPayload();
|
||||
mPlugin = adapterItemWithPayload.getPlugin();
|
||||
|
||||
if (payload.mRemoteAction != null) {
|
||||
prepareUsingRemoteAction(payload.mRemoteAction,
|
||||
payload.bundle.getString(SearchTarget.REMOTE_ACTION_TOKEN),
|
||||
payload.bundle.getBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START));
|
||||
} else {
|
||||
prepareUsingShortcutInfo(payload.shortcuts.get(0));
|
||||
}
|
||||
setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
|
||||
adapterItemWithPayload.setSelectionHandler(this::handleSelection);
|
||||
}
|
||||
|
||||
private void prepareUsingShortcutInfo(ShortcutInfo shortcutInfo) {
|
||||
mShortcutInfo = shortcutInfo;
|
||||
WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(mShortcutInfo, getContext());
|
||||
applyFromWorkspaceItem(workspaceItemInfo);
|
||||
LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
|
||||
MODEL_EXECUTOR.execute(() -> {
|
||||
launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, mShortcutInfo);
|
||||
reapplyItemInfoAsync(workspaceItemInfo);
|
||||
});
|
||||
}
|
||||
|
||||
private void prepareUsingRemoteAction(RemoteAction remoteAction, String token, boolean start) {
|
||||
RemoteActionItemInfo itemInfo = new RemoteActionItemInfo(remoteAction, token, start);
|
||||
|
||||
applyFromRemoteActionInfo(itemInfo);
|
||||
UI_HELPER_EXECUTOR.post(() -> {
|
||||
// If the Drawable from the remote action is not AdaptiveBitmap, styling will not work.
|
||||
try (LauncherIcons li = LauncherIcons.obtain(getContext())) {
|
||||
Drawable d = itemInfo.getRemoteAction().getIcon().loadDrawable(getContext());
|
||||
itemInfo.bitmap = li.createBadgedIconBitmap(d, itemInfo.user,
|
||||
Build.VERSION.SDK_INT);
|
||||
reapplyItemInfoAsync(itemInfo);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void reapplyItemInfoAsync(ItemInfoWithIcon itemInfoWithIcon) {
|
||||
MAIN_EXECUTOR.post(() -> reapplyItemInfo(itemInfoWithIcon));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getTargetInfo() {
|
||||
return mTargetInfo;
|
||||
}
|
||||
|
||||
private void handleSelection(int eventType) {
|
||||
ItemInfo itemInfo = (ItemInfo) getTag();
|
||||
Launcher launcher = Launcher.getLauncher(getContext());
|
||||
final SearchTargetEvent searchTargetEvent;
|
||||
if (itemInfo instanceof WorkspaceItemInfo) {
|
||||
ItemClickHandler.onClickAppShortcut(this, (WorkspaceItemInfo) itemInfo, launcher);
|
||||
searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.SHORTCUT,
|
||||
eventType);
|
||||
searchTargetEvent.shortcut = mShortcutInfo;
|
||||
} else {
|
||||
RemoteActionItemInfo remoteItemInfo = (RemoteActionItemInfo) itemInfo;
|
||||
ItemClickHandler.onClickRemoteAction(launcher, remoteItemInfo);
|
||||
searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.REMOTE_ACTION,
|
||||
eventType);
|
||||
searchTargetEvent.bundle = new Bundle();
|
||||
searchTargetEvent.remoteAction = remoteItemInfo.getRemoteAction();
|
||||
searchTargetEvent.bundle.putBoolean(SearchTarget.REMOTE_ACTION_SHOULD_START,
|
||||
remoteItemInfo.shouldStartInLauncher());
|
||||
searchTargetEvent.bundle.putString(SearchTarget.REMOTE_ACTION_TOKEN,
|
||||
remoteItemInfo.getToken());
|
||||
}
|
||||
if (mPlugin != null) {
|
||||
mPlugin.notifySearchTargetEvent(searchTargetEvent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.views;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.allapps.AllAppsGridAdapter;
|
||||
import com.android.launcher3.allapps.search.AllAppsSearchBarController;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.systemui.plugins.AllAppsSearchPlugin;
|
||||
import com.android.systemui.plugins.shared.SearchTarget;
|
||||
import com.android.systemui.plugins.shared.SearchTargetEvent;
|
||||
|
||||
/**
|
||||
* A view representing a stand alone shortcut search result
|
||||
*/
|
||||
public class SearchResultShortcut extends FrameLayout implements
|
||||
AllAppsSearchBarController.PayloadResultHandler<SearchTarget> {
|
||||
|
||||
private BubbleTextView mBubbleTextView;
|
||||
private View mIconView;
|
||||
private ShortcutInfo mShortcutInfo;
|
||||
private AllAppsSearchPlugin mPlugin;
|
||||
private final Object[] mTargetInfo = createTargetInfo();
|
||||
|
||||
|
||||
public SearchResultShortcut(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SearchResultShortcut(@NonNull Context context,
|
||||
@Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SearchResultShortcut(@NonNull Context context, @Nullable AttributeSet attrs,
|
||||
int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
Launcher launcher = Launcher.getLauncher(getContext());
|
||||
DeviceProfile grid = launcher.getDeviceProfile();
|
||||
mIconView = findViewById(R.id.icon);
|
||||
ViewGroup.LayoutParams iconParams = mIconView.getLayoutParams();
|
||||
iconParams.height = grid.allAppsIconSizePx;
|
||||
iconParams.width = grid.allAppsIconSizePx;
|
||||
mBubbleTextView = findViewById(R.id.bubble_text);
|
||||
setOnClickListener(v -> handleSelection(SearchTargetEvent.SELECT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyAdapterInfo(
|
||||
AllAppsGridAdapter.AdapterItemWithPayload<SearchTarget> adapterItemWithPayload) {
|
||||
SearchTarget payload = adapterItemWithPayload.getPayload();
|
||||
mPlugin = adapterItemWithPayload.getPlugin();
|
||||
mShortcutInfo = payload.shortcuts.get(0);
|
||||
WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(mShortcutInfo, getContext());
|
||||
mBubbleTextView.applyFromWorkspaceItem(workspaceItemInfo);
|
||||
mIconView.setBackground(mBubbleTextView.getIcon());
|
||||
LauncherAppState launcherAppState = LauncherAppState.getInstance(getContext());
|
||||
MODEL_EXECUTOR.execute(() -> {
|
||||
launcherAppState.getIconCache().getShortcutIcon(workspaceItemInfo, mShortcutInfo);
|
||||
mBubbleTextView.applyFromWorkspaceItem(workspaceItemInfo);
|
||||
mIconView.setBackground(mBubbleTextView.getIcon());
|
||||
});
|
||||
adapterItemWithPayload.setSelectionHandler(this::handleSelection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getTargetInfo() {
|
||||
return mTargetInfo;
|
||||
}
|
||||
|
||||
private void handleSelection(int eventType) {
|
||||
WorkspaceItemInfo itemInfo = (WorkspaceItemInfo) mBubbleTextView.getTag();
|
||||
ItemClickHandler.onClickAppShortcut(this, itemInfo, Launcher.getLauncher(getContext()));
|
||||
|
||||
SearchTargetEvent searchTargetEvent = getSearchTargetEvent(SearchTarget.ItemType.SHORTCUT,
|
||||
eventType);
|
||||
searchTargetEvent.shortcut = mShortcutInfo;
|
||||
if (mPlugin != null) {
|
||||
mPlugin.notifySearchTargetEvent(searchTargetEvent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.android.systemui.plugins.shared;
|
||||
|
||||
import android.app.RemoteAction;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
@ -25,6 +26,14 @@ import java.util.List;
|
|||
*/
|
||||
public class SearchTarget implements Comparable<SearchTarget> {
|
||||
|
||||
|
||||
/**
|
||||
* A bundle key for boolean value of whether remote action should be started in launcher or not
|
||||
*/
|
||||
public static final String REMOTE_ACTION_SHOULD_START = "should_start_for_result";
|
||||
public static final String REMOTE_ACTION_TOKEN = "action_token";
|
||||
|
||||
|
||||
public enum ViewType {
|
||||
|
||||
/**
|
||||
|
@ -74,6 +83,7 @@ public class SearchTarget implements Comparable<SearchTarget> {
|
|||
THUMBNAIL(8);
|
||||
|
||||
private final int mId;
|
||||
|
||||
ViewType(int id) {
|
||||
mId = id;
|
||||
}
|
||||
|
@ -91,7 +101,8 @@ public class SearchTarget implements Comparable<SearchTarget> {
|
|||
APP_HERO(4, "", ViewType.HERO),
|
||||
SHORTCUT(5, "Shortcuts", ViewType.SHORTCUT),
|
||||
PEOPLE(6, "People", ViewType.PEOPLE),
|
||||
SCREENSHOT(7, "Screenshots", ViewType.THUMBNAIL);
|
||||
SCREENSHOT(7, "Screenshots", ViewType.THUMBNAIL),
|
||||
REMOTE_ACTION(8, "Remote Actions", ViewType.SHORTCUT);
|
||||
|
||||
private final int mId;
|
||||
|
||||
|
@ -123,12 +134,12 @@ public class SearchTarget implements Comparable<SearchTarget> {
|
|||
public Bundle bundle;
|
||||
public float score;
|
||||
public String mSessionId;
|
||||
public RemoteAction mRemoteAction;
|
||||
|
||||
/**
|
||||
* Constructor to create the search target. Bundle is currently temporary to hold
|
||||
* search target primitives that cannot be expressed as java primitive objects
|
||||
* or AOSP native objects.
|
||||
*
|
||||
*/
|
||||
public SearchTarget(ItemType itemType, List<ShortcutInfo> shortcuts,
|
||||
Bundle bundle, float score, String sessionId) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.android.systemui.plugins.shared;
|
||||
|
||||
import android.app.RemoteAction;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.os.Bundle;
|
||||
|
||||
|
@ -29,6 +30,7 @@ public class SearchTargetEvent {
|
|||
|
||||
public SearchTarget.ItemType type;
|
||||
public ShortcutInfo shortcut;
|
||||
public RemoteAction remoteAction;
|
||||
public int eventType;
|
||||
public Bundle bundle;
|
||||
public int index;
|
||||
|
|
Loading…
Reference in New Issue