diff options
author | Tony Wickham <twickham@google.com> | 2017-03-20 17:12:24 -0700 |
---|---|---|
committer | Tony <twickham@google.com> | 2017-03-30 16:35:56 -0700 |
commit | 26b1746593851e239bfff65ae7a69b809ad87b99 (patch) | |
tree | 4f5a73f3253d52304a0f105aa03c2a882038b14a | |
parent | 4a907d0f9d1c80661c086aa95a8509698f38b324 (diff) | |
download | packages_apps_Trebuchet-26b1746593851e239bfff65ae7a69b809ad87b99.tar.gz packages_apps_Trebuchet-26b1746593851e239bfff65ae7a69b809ad87b99.tar.bz2 packages_apps_Trebuchet-26b1746593851e239bfff65ae7a69b809ad87b99.zip |
Add support for system shortcuts in popup container
- Currently the system shortcuts are just widgets and app info
- As shortcuts, they live in ShortcutsItemView
- They are populated either as icons only (if there are deep
shortcuts) or as icons + text
- Widgets are disabled until binding them is complete (we request for
them to be bound on long-press now). We should revisit this.
Bug: 34940468
Change-Id: Ia51d002c3b3ede87658bdab57abfc3eeca1ed242
24 files changed, 488 insertions, 95 deletions
diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml index b2ed709e2..60131e4fb 100644 --- a/res/layout/deep_shortcut.xml +++ b/res/layout/deep_shortcut.xml @@ -22,7 +22,7 @@ <com.android.launcher3.shortcuts.DeepShortcutTextView style="@style/BaseIcon" - android:id="@+id/deep_shortcut" + android:id="@+id/bubble_text" android:background="?android:attr/selectableItemBackground" android:gravity="start|center_vertical" android:textAlignment="viewStart" @@ -34,8 +34,7 @@ android:fontFamily="sans-serif" launcher:layoutHorizontal="true" launcher:iconDisplay="shortcut_popup" - launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" - android:elevation="@dimen/deep_shortcuts_elevation" /> + launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size" /> <View android:id="@+id/icon" diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml new file mode 100644 index 000000000..3baddc480 --- /dev/null +++ b/res/layout/system_shortcut.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<com.android.launcher3.shortcuts.DeepShortcutView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:launcher="http://schemas.android.com/apk/res-auto" + android:layout_width="@dimen/bg_popup_item_width" + android:layout_height="@dimen/bg_popup_item_height" > + + <com.android.launcher3.BubbleTextView + style="@style/BaseIcon" + android:id="@+id/bubble_text" + android:background="?android:attr/selectableItemBackground" + android:gravity="start|center_vertical" + android:textAlignment="viewStart" + android:paddingStart="@dimen/bg_popup_item_height" + android:paddingEnd="@dimen/deep_shortcut_padding_end" + android:textSize="14sp" + android:fontFamily="sans-serif" + launcher:layoutHorizontal="true" /> + + <View + android:id="@+id/icon" + android:layout_width="@dimen/system_shortcut_icon_size" + android:layout_height="@dimen/system_shortcut_icon_size" + android:layout_margin="@dimen/system_shortcut_padding_start" + android:layout_gravity="start" /> + + <View + android:id="@+id/divider" + android:layout_width="@dimen/deep_shortcuts_divider_width" + android:layout_height="@dimen/popup_item_divider_height" + android:layout_gravity="end|bottom" + android:visibility="gone" + android:background="?android:attr/listDivider" /> + +</com.android.launcher3.shortcuts.DeepShortcutView> diff --git a/res/layout/system_shortcut_icon_only.xml b/res/layout/system_shortcut_icon_only.xml new file mode 100644 index 000000000..02d4ef818 --- /dev/null +++ b/res/layout/system_shortcut_icon_only.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<ImageView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="@dimen/deep_shortcut_icon_size" + android:layout_height="@dimen/deep_shortcut_icon_size" + android:background="?android:attr/selectableItemBackground" + android:layout_marginEnd="@dimen/deep_shortcut_padding_start" + android:padding="4dp" /> diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml new file mode 100644 index 000000000..bf0a2512a --- /dev/null +++ b/res/layout/system_shortcut_icons.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/system_shortcut_icons" + android:layout_width="match_parent" + android:layout_height="@dimen/bg_popup_item_height" + android:paddingEnd="@dimen/deep_shortcut_padding_start" + android:orientation="horizontal" + android:gravity="end|center_vertical" + android:background="@color/notification_header_background_color" /> diff --git a/res/layout/widgets_list_row_view.xml b/res/layout/widgets_list_row_view.xml index 4067503b7..b6e0a0bd7 100644 --- a/res/layout/widgets_list_row_view.xml +++ b/res/layout/widgets_list_row_view.xml @@ -47,19 +47,5 @@ launcher:iconSizeOverride="@dimen/widget_section_icon_size" launcher:layoutHorizontal="true" /> - <HorizontalScrollView - android:id="@+id/widgets_scroll_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="?android:attr/colorPrimaryDark" - android:scrollbars="none"> - <LinearLayout - android:id="@+id/widgets_cell_list" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:paddingStart="@dimen/widget_row_padding" - android:paddingEnd="0dp" - android:orientation="horizontal" - android:showDividers="none"/> - </HorizontalScrollView> + <include layout="@layout/widgets_scroll_container" /> </LinearLayout> diff --git a/res/values/colors.xml b/res/values/colors.xml index 83a44d7b9..028c98206 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -35,10 +35,14 @@ <color name="spring_loaded_panel_color">#40FFFFFF</color> <color name="spring_loaded_highlighted_panel_border_color">#FFF</color> + <!-- Notifications --> <color name="notification_icon_default_color">#757575</color> <!-- Gray 600 --> <color name="notification_header_background_color">#F5F5F5</color> <!-- Gray 100 --> <color name="notification_background_color">#FFF</color> <color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 --> <color name="divider_color">@color/notification_color_beneath</color> <color name="icon_background">#E0E0E0</color> <!-- Gray 300 --> + + <!-- System shortcuts --> + <color name="system_shortcuts_icon_color">@android:color/tertiary_text_light</color> </resources> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 132ae0700..7b1d24720 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -172,6 +172,8 @@ <dimen name="deep_shortcuts_arrow_horizontal_offset">19dp</dimen> <!-- popup_item_width - icon_size - padding_start - drawable_padding --> <dimen name="deep_shortcuts_divider_width">158dp</dimen> + <dimen name="system_shortcut_icon_size">28dp</dimen> + <dimen name="system_shortcut_padding_start">10dp</dimen> <!-- Icon badges (with notification counts) --> <dimen name="badge_size">24dp</dimen> diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index dbef05411..1f1203498 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -92,6 +92,9 @@ public abstract class AbstractFloatingView extends LinearLayout { return mIsOpen; } + protected void onWidgetsBound() { + } + protected abstract boolean isOfType(@FloatingViewType int type); protected static <T extends AbstractFloatingView> T getOpenView( diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index eccfab93f..4eeb3c0b6 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -3916,11 +3916,24 @@ public class Launcher extends BaseActivity mWidgetsView.setWidgets(allWidgets); mAllWidgets = null; } + + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this); + if (topView != null) { + topView.onWidgetsBound(); + } + } + + public List<WidgetItem> getWidgetsForPackageUser(PackageUserKey packageUserKey) { + return mWidgetsView.getWidgetsForPackageUser(packageUserKey); } @Override public void notifyWidgetProvidersChanged() { - if (mWorkspace.getState().shouldUpdateWidget) { + notifyWidgetProvidersChanged(false); + } + + public void notifyWidgetProvidersChanged(boolean force) { + if (force || mWorkspace.getState().shouldUpdateWidget) { mModel.refreshAndBindWidgetsAndShortcuts(this, mWidgetsView.isEmpty()); } } diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java index 0e9106201..49e68d75a 100644 --- a/src/com/android/launcher3/WidgetPreviewLoader.java +++ b/src/com/android/launcher3/WidgetPreviewLoader.java @@ -91,11 +91,12 @@ public class WidgetPreviewLoader { * @return a request id which can be used to cancel the request. */ public CancellationSignal getPreview(WidgetItem item, int previewWidth, - int previewHeight, WidgetCell caller) { + int previewHeight, WidgetCell caller, boolean animate) { String size = previewWidth + "x" + previewHeight; WidgetCacheKey key = new WidgetCacheKey(item.componentName, item.user, size); - PreviewLoadTask task = new PreviewLoadTask(key, item, previewWidth, previewHeight, caller); + PreviewLoadTask task = new PreviewLoadTask(key, item, previewWidth, previewHeight, caller, + animate); task.executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR); CancellationSignal signal = new CancellationSignal(); @@ -521,17 +522,19 @@ public class WidgetPreviewLoader { private final int mPreviewHeight; private final int mPreviewWidth; private final WidgetCell mCaller; + private final boolean mAnimatePreviewIn; private final BaseActivity mActivity; @Thunk long[] mVersions; @Thunk Bitmap mBitmapToRecycle; PreviewLoadTask(WidgetCacheKey key, WidgetItem info, int previewWidth, - int previewHeight, WidgetCell caller) { + int previewHeight, WidgetCell caller, boolean animate) { mKey = key; mInfo = info; mPreviewHeight = previewHeight; mPreviewWidth = previewWidth; mCaller = caller; + mAnimatePreviewIn = animate; mActivity = BaseActivity.fromContext(mCaller.getContext()); if (DEBUG) { Log.d(TAG, String.format("%s, %s, %d, %d", @@ -587,7 +590,7 @@ public class WidgetPreviewLoader { @Override protected void onPostExecute(final Bitmap preview) { - mCaller.applyPreview(preview); + mCaller.applyPreview(preview, mAnimatePreviewIn); // Write the generated preview to the DB in the worker thread if (mVersions != null) { diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index fffcb7107..b92814fab 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -22,7 +22,6 @@ import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; -import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; import android.content.res.Resources; @@ -66,6 +65,7 @@ import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.graphics.TriangleShape; import com.android.launcher3.notification.NotificationItemView; import com.android.launcher3.notification.NotificationKeyData; +import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.shortcuts.ShortcutsItemView; import com.android.launcher3.util.PackageUserKey; @@ -138,19 +138,21 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra return null; } ItemInfo itemInfo = (ItemInfo) icon.getTag(); + if (!DeepShortcutManager.supportsShortcuts(itemInfo)) { + return null; + } + List<String> shortcutIds = launcher.getPopupDataProvider().getShortcutIdsForItem(itemInfo); List<NotificationKeyData> notificationKeys = launcher.getPopupDataProvider() .getNotificationKeysForItem(itemInfo); - if (shortcutIds.size() > 0 || notificationKeys.size() > 0) { - final PopupContainerWithArrow container = - (PopupContainerWithArrow) launcher.getLayoutInflater().inflate( - R.layout.popup_container, launcher.getDragLayer(), false); - container.setVisibility(View.INVISIBLE); - launcher.getDragLayer().addView(container); - container.populateAndShow(icon, shortcutIds, notificationKeys); - return container; - } - return null; + + final PopupContainerWithArrow container = + (PopupContainerWithArrow) launcher.getLayoutInflater().inflate( + R.layout.popup_container, launcher.getDragLayer(), false); + container.setVisibility(View.INVISIBLE); + launcher.getDragLayer().addView(container); + container.populateAndShow(icon, shortcutIds, notificationKeys); + return container; } public void populateAndShow(final BubbleTextView originalIcon, final List<String> shortcutIds, @@ -187,6 +189,9 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra List<DeepShortcutView> shortcutViews = mShortcutsItemView == null ? Collections.EMPTY_LIST : mShortcutsItemView.getDeepShortcutViews(reverseOrder); + List<View> systemShortcutViews = mShortcutsItemView == null + ? Collections.EMPTY_LIST + : mShortcutsItemView.getSystemShortcutViews(reverseOrder); if (mNotificationItemView != null) { BadgeInfo badgeInfo = mLauncher.getPopupDataProvider() .getBadgeInfoForItem(originalItemInfo); @@ -208,7 +213,8 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra final Looper workerLooper = LauncherModel.getWorkerLooper(); new Handler(workerLooper).postAtFrontOfQueue(PopupPopulator.createUpdateRunnable( mLauncher, originalItemInfo, new Handler(Looper.getMainLooper()), - this, shortcutIds, shortcutViews, notificationKeys, mNotificationItemView)); + this, shortcutIds, shortcutViews, notificationKeys, mNotificationItemView, + systemShortcutViews)); } private void addDummyViews(BubbleTextView originalIcon, @@ -216,9 +222,12 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra final Resources res = getResources(); final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing); final LayoutInflater inflater = mLauncher.getLayoutInflater(); + int numItems = itemTypesToPopulate.length; for (int i = 0; i < numItems; i++) { PopupPopulator.Item itemTypeToPopulate = itemTypesToPopulate[i]; + PopupPopulator.Item nextItemTypeToPopulate = + i < numItems - 1 ? itemTypesToPopulate[i + 1] : null; final View item = inflater.inflate(itemTypeToPopulate.layoutId, this, false); if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) { @@ -228,23 +237,23 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra item.findViewById(R.id.footer).getLayoutParams().height = footerHeight; } - boolean itemIsFollowedByDifferentType = i < numItems - 1 - && itemTypesToPopulate[i + 1] != itemTypeToPopulate; + boolean shouldAddBottomMargin = nextItemTypeToPopulate != null + && itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut; item.setAccessibilityDelegate(mAccessibilityDelegate); - if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) { + if (itemTypeToPopulate.isShortcut) { if (mShortcutsItemView == null) { mShortcutsItemView = (ShortcutsItemView) inflater.inflate( R.layout.shortcuts_item, this, false); addView(mShortcutsItemView); } - mShortcutsItemView.addDeepShortcutView((DeepShortcutView) item); - if (itemIsFollowedByDifferentType) { + mShortcutsItemView.addShortcutView(item, itemTypeToPopulate, mIsAboveIcon); + if (shouldAddBottomMargin) { ((LayoutParams) mShortcutsItemView.getLayoutParams()).bottomMargin = spacing; } } else { addView(item); - if (itemIsFollowedByDifferentType) { + if (shouldAddBottomMargin) { ((LayoutParams) item.getLayoutParams()).bottomMargin = spacing; } } @@ -602,6 +611,16 @@ public class PopupContainerWithArrow extends AbstractFloatingView implements Dra badgeInfo.getNotificationKeys())); } + @Override + protected void onWidgetsBound() { + enableWidgets(); + } + + public boolean enableWidgets() { + return mShortcutsItemView != null && mShortcutsItemView.enableWidgets( + (ItemInfo) mOriginalIcon.getTag()); + } + private ObjectAnimator createArrowScaleAnim(float scale) { return LauncherAnimUtils.ofPropertyValuesHolder( mArrow, new PropertyListBuilder().scale(scale).build()); diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java index 9c4faedbd..b101bc5ae 100644 --- a/src/com/android/launcher3/popup/PopupDataProvider.java +++ b/src/com/android/launcher3/popup/PopupDataProvider.java @@ -48,6 +48,12 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan private static final boolean LOGD = false; private static final String TAG = "PopupDataProvider"; + /** Note that these are in order of priority. */ + public static final SystemShortcut[] SYSTEM_SHORTCUTS = new SystemShortcut[] { + new SystemShortcut.Widgets(), + new SystemShortcut.AppInfo(), + }; + private final Launcher mLauncher; /** Maps launcher activity components to their list of shortcut ids. */ diff --git a/src/com/android/launcher3/popup/PopupItemView.java b/src/com/android/launcher3/popup/PopupItemView.java index b839d99ff..71daae936 100644 --- a/src/com/android/launcher3/popup/PopupItemView.java +++ b/src/com/android/launcher3/popup/PopupItemView.java @@ -156,7 +156,8 @@ public abstract class PopupItemView extends FrameLayout * Returns the position of the center of the icon relative to the container. */ public Point getIconCenter() { - sTempPoint.y = sTempPoint.x = getMeasuredHeight() / 2; + sTempPoint.y = getMeasuredHeight() / 2; + sTempPoint.x = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_height) / 2; if (Utilities.isRtl(getResources())) { sTempPoint.x = getMeasuredWidth() - sTempPoint.x; } diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java index 9b2141f12..a9f219b38 100644 --- a/src/com/android/launcher3/popup/PopupPopulator.java +++ b/src/com/android/launcher3/popup/PopupPopulator.java @@ -17,12 +17,15 @@ package com.android.launcher3.popup; import android.content.ComponentName; +import android.content.res.Resources; import android.os.Handler; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; +import android.view.View; +import android.widget.ImageView; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; @@ -52,13 +55,17 @@ public class PopupPopulator { @VisibleForTesting static final int NUM_DYNAMIC = 2; public enum Item { - SHORTCUT(R.layout.deep_shortcut), - NOTIFICATION(R.layout.notification); + SHORTCUT(R.layout.deep_shortcut, true), + NOTIFICATION(R.layout.notification, false), + SYSTEM_SHORTCUT(R.layout.system_shortcut, true), + SYSTEM_SHORTCUT_ICON(R.layout.system_shortcut_icon_only, true); public final int layoutId; + public final boolean isShortcut; - Item(int layoutId) { + Item(int layoutId, boolean isShortcut) { this.layoutId = layoutId; + this.isShortcut = isShortcut; } } @@ -66,7 +73,8 @@ public class PopupPopulator { @NonNull List<NotificationKeyData> notificationKeys) { boolean hasNotifications = notificationKeys.size() > 0; int numNotificationItems = hasNotifications ? 1 : 0; - int numItems = Math.min(MAX_ITEMS, shortcutIds.size() + numNotificationItems); + int numItems = Math.min(MAX_ITEMS, shortcutIds.size() + numNotificationItems) + + PopupDataProvider.SYSTEM_SHORTCUTS.length; Item[] items = new Item[numItems]; for (int i = 0; i < numItems; i++) { items[i] = Item.SHORTCUT; @@ -75,6 +83,11 @@ public class PopupPopulator { // The notification layout is always first. items[0] = Item.NOTIFICATION; } + // The system shortcuts are always last. + boolean iconsOnly = !shortcutIds.isEmpty(); + for (int i = 0; i < PopupDataProvider.SYSTEM_SHORTCUTS.length; i++) { + items[numItems - 1 - i] = iconsOnly ? Item.SYSTEM_SHORTCUT_ICON : Item.SYSTEM_SHORTCUT; + } return items; } @@ -159,11 +172,11 @@ public class PopupPopulator { return filteredShortcuts; } - public static Runnable createUpdateRunnable(final Launcher launcher, ItemInfo originalInfo, + public static Runnable createUpdateRunnable(final Launcher launcher, final ItemInfo originalInfo, final Handler uiHandler, final PopupContainerWithArrow container, final List<String> shortcutIds, final List<DeepShortcutView> shortcutViews, final List<NotificationKeyData> notificationKeys, - final NotificationItemView notificationView) { + final NotificationItemView notificationView, final List<View> systemShortcutViews) { final ComponentName activity = originalInfo.getTargetComponent(); final UserHandle user = originalInfo.user; return new Runnable() { @@ -195,11 +208,20 @@ public class PopupPopulator { uiHandler.post(new UpdateShortcutChild(container, shortcutViews.get(i), si, shortcut)); } + + // This ensures that mLauncher.getWidgetsForPackageUser() + // doesn't return null (it puts all the widgets in memory). + launcher.notifyWidgetProvidersChanged(true /* force */); + for (int i = 0; i < PopupDataProvider.SYSTEM_SHORTCUTS.length; i++) { + final SystemShortcut systemShortcut = PopupDataProvider.SYSTEM_SHORTCUTS[i]; + uiHandler.post(new UpdateSystemShortcutChild(container, + systemShortcutViews.get(i), systemShortcut, launcher, originalInfo)); + } } }; } - /** Updates the child of this container at the given index based on the given shortcut info. */ + /** Updates the shortcut child of this container based on the given shortcut info. */ private static class UpdateShortcutChild implements Runnable { private final PopupContainerWithArrow mContainer; private final DeepShortcutView mShortcutChild; @@ -221,7 +243,7 @@ public class PopupPopulator { } } - /** Updates the child of this container at the given index based on the given shortcut info. */ + /** Updates the notification child based on the given notification info. */ private static class UpdateNotificationChild implements Runnable { private NotificationItemView mNotificationView; private List<NotificationInfo> mNotificationInfos; @@ -237,4 +259,50 @@ public class PopupPopulator { mNotificationView.applyNotificationInfos(mNotificationInfos); } } + + /** Updates the system shortcut child based on the given shortcut info. */ + private static class UpdateSystemShortcutChild implements Runnable { + private static final float DISABLED_ALPHA = 0.38f; + + private final PopupContainerWithArrow mContainer; + private final View mSystemShortcutChild; + private final SystemShortcut mSystemShortcutInfo; + private final Launcher mLauncher; + private final ItemInfo mItemInfo; + + public UpdateSystemShortcutChild(PopupContainerWithArrow container, View systemShortcutChild, + SystemShortcut systemShortcut, Launcher launcher, ItemInfo originalInfo) { + mContainer = container; + mSystemShortcutChild = systemShortcutChild; + mSystemShortcutInfo = systemShortcut; + mLauncher = launcher; + mItemInfo = originalInfo; + } + + @Override + public void run() { + final Resources res = mSystemShortcutChild.getResources(); + if (mSystemShortcutChild instanceof DeepShortcutView) { + final DeepShortcutView shortcutView = (DeepShortcutView) mSystemShortcutChild; + shortcutView.getIconView().setBackground(mSystemShortcutInfo.getIcon(res)); + shortcutView.getBubbleText().setText(mSystemShortcutInfo.getLabel(res)); + } else if (mSystemShortcutChild instanceof ImageView) { + final ImageView shortcutIcon = (ImageView) mSystemShortcutChild; + shortcutIcon.setImageDrawable(mSystemShortcutInfo.getIcon(res)); + shortcutIcon.setContentDescription(mSystemShortcutInfo.getLabel(res)); + } + if (!(mSystemShortcutInfo instanceof SystemShortcut.Widgets)) { + mSystemShortcutChild.setOnClickListener(mSystemShortcutInfo + .getOnClickListener(mLauncher, mItemInfo)); + } else { + mSystemShortcutChild.setTag(mSystemShortcutInfo); + // Widgets might not be enabled right away. + if (mContainer.enableWidgets()) { + return; + } + // Disable Widgets (we might be able to re-enable when widgets are bound). + mSystemShortcutChild.setAlpha(DISABLED_ALPHA); + } + } + } } diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java new file mode 100644 index 000000000..d94db43b8 --- /dev/null +++ b/src/com/android/launcher3/popup/SystemShortcut.java @@ -0,0 +1,89 @@ +package com.android.launcher3.popup; + +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.view.View; + +import com.android.launcher3.InfoDropTarget; +import com.android.launcher3.ItemInfo; +import com.android.launcher3.Launcher; +import com.android.launcher3.R; +import com.android.launcher3.model.WidgetItem; +import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.widget.WidgetsAndMore; + +import java.util.List; + +/** + * Represents a system shortcut for a given app. The shortcut should have a static label and + * icon, and an onClickListener that depends on the item that the shortcut services. + * + * Example system shortcuts, defined as inner classes, include Widgets and AppInfo. + */ +public abstract class SystemShortcut { + private final int mIconResId; + private final int mLabelResId; + + public SystemShortcut(int iconResId, int labelResId) { + mIconResId = iconResId; + mLabelResId = labelResId; + } + + public Drawable getIcon(Resources resources) { + Drawable icon = resources.getDrawable(mIconResId); + icon.setTint(resources.getColor(R.color.system_shortcuts_icon_color)); + return icon; + } + + public String getLabel(Resources resources) { + return resources.getString(mLabelResId); + } + + public abstract View.OnClickListener getOnClickListener(final Launcher launcher, + final ItemInfo itemInfo); + + + public static class Widgets extends SystemShortcut { + + public Widgets() { + super(R.drawable.ic_widget, R.string.widgets_and_more); + } + + @Override + public View.OnClickListener getOnClickListener(final Launcher launcher, + final ItemInfo itemInfo) { + final List<WidgetItem> widgets = launcher.getWidgetsForPackageUser(new PackageUserKey( + itemInfo.getTargetComponent().getPackageName(), itemInfo.user)); + if (widgets == null) { + return null; + } + return new View.OnClickListener() { + @Override + public void onClick(View view) { + PopupContainerWithArrow.getOpen(launcher).close(true); + WidgetsAndMore widgetsAndMore = + (WidgetsAndMore) launcher.getLayoutInflater().inflate( + R.layout.widgets_and_more, launcher.getDragLayer(), false); + widgetsAndMore.populateAndShow(itemInfo); + } + }; + } + } + + public static class AppInfo extends SystemShortcut { + public AppInfo() { + super(R.drawable.ic_info_launcher, R.string.app_info_drop_target_label); + } + + @Override + public View.OnClickListener getOnClickListener(final Launcher launcher, + final ItemInfo itemInfo) { + return new View.OnClickListener() { + @Override + public void onClick(View view) { + InfoDropTarget.startDetailsActivityForInfo(itemInfo, launcher, null); + } + }; + } + } +} diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java index 47a023e25..75a48861b 100644 --- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java +++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java @@ -24,6 +24,7 @@ import android.util.AttributeSet; import android.view.View; import android.widget.FrameLayout; +import com.android.launcher3.BubbleTextView; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.ShortcutInfo; @@ -39,7 +40,7 @@ public class DeepShortcutView extends FrameLayout { private final Rect mPillRect; - private DeepShortcutTextView mBubbleText; + private BubbleTextView mBubbleText; private View mIconView; private ShortcutInfo mInfo; @@ -62,11 +63,11 @@ public class DeepShortcutView extends FrameLayout { @Override protected void onFinishInflate() { super.onFinishInflate(); - mBubbleText = (DeepShortcutTextView) findViewById(R.id.deep_shortcut); + mBubbleText = findViewById(R.id.bubble_text); mIconView = findViewById(R.id.icon); } - public DeepShortcutTextView getBubbleText() { + public BubbleTextView getBubbleText() { return mBubbleText; } diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java index 349c4c946..2255007d3 100644 --- a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java +++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java @@ -36,21 +36,28 @@ import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.popup.PopupItemView; +import com.android.launcher3.popup.PopupPopulator; +import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.userevent.nano.LauncherLogProto; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** - * A {@link PopupItemView} that contains all of the {@link DeepShortcutView}s for an app. + * A {@link PopupItemView} that contains all of the {@link DeepShortcutView}s for an app, + * as well as the system shortcuts such as Widgets and App Info. */ public class ShortcutsItemView extends PopupItemView implements View.OnLongClickListener, View.OnTouchListener, LogContainerProvider { private Launcher mLauncher; - private LinearLayout mDeepShortcutsLayout; + private LinearLayout mShortcutsLayout; + private LinearLayout mSystemShortcutIcons; private final Point mIconShift = new Point(); private final Point mIconLastTouchPos = new Point(); + private final List<DeepShortcutView> mDeepShortcutViews = new ArrayList<>(); + private final List<View> mSystemShortcutViews = new ArrayList<>(); public ShortcutsItemView(Context context) { this(context, null, 0); @@ -69,7 +76,7 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick @Override protected void onFinishInflate() { super.onFinishInflate(); - mDeepShortcutsLayout = (LinearLayout) findViewById(R.id.deep_shortcuts); + mShortcutsLayout = findViewById(R.id.deep_shortcuts); } @Override @@ -111,42 +118,81 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick return false; } - public void addDeepShortcutView(DeepShortcutView deepShortcutView) { - if (getNumDeepShortcuts() > 0) { - getDeepShortcutAt(getNumDeepShortcuts() - 1).findViewById(R.id.divider) - .setVisibility(VISIBLE); + public void addShortcutView(View shortcutView, PopupPopulator.Item shortcutType, + boolean isAboveIcon) { + if (shortcutType == PopupPopulator.Item.SHORTCUT) { + mDeepShortcutViews.add((DeepShortcutView) shortcutView); + } else { + mSystemShortcutViews.add(shortcutView); + } + if (shortcutType == PopupPopulator.Item.SYSTEM_SHORTCUT_ICON) { + // System shortcut icons are added to a header that is separate from the full shortcuts. + if (mSystemShortcutIcons == null) { + mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate( + R.layout.system_shortcut_icons, mShortcutsLayout, false); + if (isAboveIcon) { + mShortcutsLayout.addView(mSystemShortcutIcons, 0); + } else { + mShortcutsLayout.addView(mSystemShortcutIcons); + } + } + mSystemShortcutIcons.addView(shortcutView); + } else { + if (mShortcutsLayout.getChildCount() > 0) { + View prevChild = mShortcutsLayout.getChildAt(mShortcutsLayout.getChildCount() - 1); + if (prevChild instanceof DeepShortcutView) { + prevChild.findViewById(R.id.divider).setVisibility(VISIBLE); + } + } + mShortcutsLayout.addView(shortcutView); } - mDeepShortcutsLayout.addView(deepShortcutView); } - private DeepShortcutView getDeepShortcutAt(int index) { - return (DeepShortcutView) mDeepShortcutsLayout.getChildAt(index); + public List<DeepShortcutView> getDeepShortcutViews(boolean reverseOrder) { + if (reverseOrder) { + Collections.reverse(mDeepShortcutViews); + } + return mDeepShortcutViews; } - private int getNumDeepShortcuts() { - return mDeepShortcutsLayout.getChildCount(); + public List<View> getSystemShortcutViews(boolean reverseOrder) { + if (reverseOrder) { + Collections.reverse(mSystemShortcutViews); + } + return mSystemShortcutViews; } - public List<DeepShortcutView> getDeepShortcutViews(boolean reverseOrder) { - int numDeepShortcuts = getNumDeepShortcuts(); - List<DeepShortcutView> deepShortcutViews = new ArrayList<>(numDeepShortcuts); - for (int i = 0; i < numDeepShortcuts; i++) { - DeepShortcutView deepShortcut = getDeepShortcutAt(i); - if (reverseOrder) { - deepShortcutViews.add(0, deepShortcut); - } else { - deepShortcutViews.add(deepShortcut); + /** + * Sets the onClickListener on widgets system shortcut child, and updates alpha to 1. + * @return whether widgets is enabled, i.e. the onClickListener is not null. + */ + public boolean enableWidgets(ItemInfo itemInfo) { + for (View systemShortcut : mSystemShortcutViews) { + if (systemShortcut.getTag() instanceof SystemShortcut.Widgets) { + View.OnClickListener onClickListener = + ((SystemShortcut.Widgets) systemShortcut.getTag()).getOnClickListener( + mLauncher, itemInfo); + if (onClickListener != null) { + systemShortcut.setAlpha(1f); + systemShortcut.setOnClickListener(onClickListener); + return true; + } + return false; } } - return deepShortcutViews; + return false; } @Override public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) { AnimatorSet openAnimation = LauncherAnimUtils.createAnimatorSet(); openAnimation.play(super.createOpenAnimation(isContainerAboveIcon, pivotLeft)); - for (int i = 0; i < getNumDeepShortcuts(); i++) { - View deepShortcutIcon = getDeepShortcutAt(i).getIconView(); + for (int i = 0; i < mShortcutsLayout.getChildCount(); i++) { + if (!(mShortcutsLayout.getChildAt(i) instanceof DeepShortcutView)) { + continue; + } + DeepShortcutView shortcutView = ((DeepShortcutView) mShortcutsLayout.getChildAt(i)); + View deepShortcutIcon = shortcutView.getIconView(); deepShortcutIcon.setScaleX(0); deepShortcutIcon.setScaleY(0); openAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder( @@ -160,8 +206,12 @@ public class ShortcutsItemView extends PopupItemView implements View.OnLongClick long duration) { AnimatorSet closeAnimation = LauncherAnimUtils.createAnimatorSet(); closeAnimation.play(super.createCloseAnimation(isContainerAboveIcon, pivotLeft, duration)); - for (int i = 0; i < getNumDeepShortcuts(); i++) { - View deepShortcutIcon = getDeepShortcutAt(i).getIconView(); + for (int i = 0; i < mShortcutsLayout.getChildCount(); i++) { + if (!(mShortcutsLayout.getChildAt(i) instanceof DeepShortcutView)) { + continue; + } + DeepShortcutView shortcutView = ((DeepShortcutView) mShortcutsLayout.getChildAt(i)); + View deepShortcutIcon = shortcutView.getIconView(); deepShortcutIcon.setScaleX(1); deepShortcutIcon.setScaleY(1); closeAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder( diff --git a/src/com/android/launcher3/util/PackageUserKey.java b/src/com/android/launcher3/util/PackageUserKey.java index 3fb240117..1ce282210 100644 --- a/src/com/android/launcher3/util/PackageUserKey.java +++ b/src/com/android/launcher3/util/PackageUserKey.java @@ -11,8 +11,8 @@ import java.util.Arrays; /** Creates a hash key based on package name and user. */ public class PackageUserKey { - private String mPackageName; - private UserHandle mUser; + public String mPackageName; + public UserHandle mUser; private int mHashCode; public static PackageUserKey fromItemInfo(ItemInfo info) { diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index 72effd471..40dbd523c 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -155,6 +155,10 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { } public void applyPreview(Bitmap bitmap) { + applyPreview(bitmap, true); + } + + public void applyPreview(Bitmap bitmap, boolean animate) { if (bitmap != null) { mWidgetImage.setBitmap(bitmap, DrawableFactory.get(getContext()).getBadgeForUser(mItem.user, getContext())); @@ -169,11 +173,15 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { } public void ensurePreview() { + ensurePreview(true); + } + + public void ensurePreview(boolean animate) { if (mActiveRequest != null) { return; } mActiveRequest = mWidgetPreviewLoader.getPreview( - mItem, mPresetPreviewSize, mPresetPreviewSize, this); + mItem, mPresetPreviewSize, mPresetPreviewSize, this, animate); } @Override diff --git a/src/com/android/launcher3/widget/WidgetsAndMore.java b/src/com/android/launcher3/widget/WidgetsAndMore.java index 3ed2530b3..1aea534fd 100644 --- a/src/com/android/launcher3/widget/WidgetsAndMore.java +++ b/src/com/android/launcher3/widget/WidgetsAndMore.java @@ -46,12 +46,15 @@ import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.userevent.nano.LauncherLogProto; +import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.TouchController; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import static android.R.attr.bottom; + /** * Bottom sheet for the "Widgets & more" long-press option. */ @@ -64,6 +67,7 @@ public class WidgetsAndMore extends AbstractFloatingView implements Insettable, private float mTranslationYRange; private Launcher mLauncher; + private ItemInfo mOriginalItemInfo; private ObjectAnimator mOpenCloseAnimator; private Interpolator mFastOutSlowInInterpolator; private VerticalPullDetector.ScrollInterpolator mScrollInterpolator; @@ -95,9 +99,25 @@ public class WidgetsAndMore extends AbstractFloatingView implements Insettable, mTranslationYRange = mTranslationYClosed - mTranslationYOpen; } - public void populateAndShow(ItemInfo itemInfo, List<WidgetItem> widgets) { - ((TextView) findViewById(R.id.title)).setText(itemInfo.title); + public void populateAndShow(ItemInfo itemInfo) { + mOriginalItemInfo = itemInfo; + ((TextView) findViewById(R.id.title)).setText(mOriginalItemInfo.title); + + onWidgetsBound(); + + mWasNavBarLight = (mLauncher.getWindow().getDecorView().getSystemUiVisibility() + & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0; + mLauncher.getDragLayer().addView(this); + measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); + setTranslationY(mTranslationYClosed); + mIsOpen = false; + open(true); + } + @Override + protected void onWidgetsBound() { + List<WidgetItem> widgets = mLauncher.getWidgetsForPackageUser(new PackageUserKey( + mOriginalItemInfo.getTargetComponent().getPackageName(), mOriginalItemInfo.user)); List<WidgetItem> shortcuts = new ArrayList<>(); // Transfer configurable widgets to shortcuts Iterator<WidgetItem> widgetsIter = widgets.iterator(); @@ -116,6 +136,9 @@ public class WidgetsAndMore extends AbstractFloatingView implements Insettable, ViewGroup shortcutRow = (ViewGroup) findViewById(R.id.shortcuts); ViewGroup shortcutCells = (ViewGroup) shortcutRow.findViewById(R.id.widgets_cell_list); + widgetCells.removeAllViews(); + shortcutCells.removeAllViews(); + for (int i = 0; i < widgets.size(); i++) { addItemCell(widgetCells); if (i < widgets.size() - 1) { @@ -152,14 +175,6 @@ public class WidgetsAndMore extends AbstractFloatingView implements Insettable, } else { removeView(findViewById(R.id.shortcuts_header)); } - - mWasNavBarLight = (mLauncher.getWindow().getDecorView().getSystemUiVisibility() - & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0; - mLauncher.getDragLayer().addView(this); - measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); - setTranslationY(mTranslationYClosed); - mIsOpen = false; - open(true); } private void addDivider(ViewGroup parent) { diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java index ba6ed41f6..4e296bf41 100644 --- a/src/com/android/launcher3/widget/WidgetsContainerView.java +++ b/src/com/android/launcher3/widget/WidgetsContainerView.java @@ -40,8 +40,11 @@ import com.android.launcher3.model.WidgetItem; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; import com.android.launcher3.util.MultiHashMap; +import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.Thunk; +import java.util.List; + /** * The widgets list view container. */ @@ -243,6 +246,10 @@ public class WidgetsContainerView extends BaseContainerView return mAdapter.getItemCount() == 0; } + public List<WidgetItem> getWidgetsForPackageUser(PackageUserKey packageUserKey) { + return mAdapter.copyWidgetsForPackageUser(packageUserKey); + } + @Override public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) { targetParent.containerType = ContainerType.WIDGETS; diff --git a/src/com/android/launcher3/widget/WidgetsListAdapter.java b/src/com/android/launcher3/widget/WidgetsListAdapter.java index 38210fc97..a1eb0ab12 100644 --- a/src/com/android/launcher3/widget/WidgetsListAdapter.java +++ b/src/com/android/launcher3/widget/WidgetsListAdapter.java @@ -22,7 +22,6 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.LinearLayout; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; @@ -32,10 +31,12 @@ import com.android.launcher3.model.PackageItemInfo; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.util.LabelComparator; import com.android.launcher3.util.MultiHashMap; +import com.android.launcher3.util.PackageUserKey; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -99,6 +100,26 @@ public class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { return mEntries.get(pos).titleSectionName; } + /** + * Copies and returns the widgets associated with the package and user of the ComponentKey. + */ + public List<WidgetItem> copyWidgetsForPackageUser(PackageUserKey packageUserKey) { + for (WidgetListRowEntry entry : mEntries) { + if (entry.pkgItem.packageName.equals(packageUserKey.mPackageName)) { + ArrayList<WidgetItem> widgets = new ArrayList<>(entry.widgets); + // Remove widgets not associated with the correct user. + Iterator<WidgetItem> iterator = widgets.iterator(); + while (iterator.hasNext()) { + if (!iterator.next().user.equals(packageUserKey.mUser)) { + iterator.remove(); + } + } + return widgets.isEmpty() ? null : widgets; + } + } + return null; + } + @Override public void onBindViewHolder(WidgetsRowViewHolder holder, int pos) { WidgetListRowEntry entry = mEntries.get(pos); diff --git a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java index ee3a62803..3a0b6132c 100644 --- a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java +++ b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java @@ -60,7 +60,7 @@ public class ShortcutsLaunchTest extends LauncherInstrumentationTestCase { // Verify that launching a shortcut opens a page with the same text assertTrue(deepShortcutsContainer.getChildCount() > 0); UiObject2 shortcut = deepShortcutsContainer.getChildren().get(0) - .findObject(getSelectorForId(R.id.deep_shortcut)); + .findObject(getSelectorForId(R.id.bubble_text)); shortcut.click(); assertTrue(mDevice.wait(Until.hasObject(By.pkg( mSettingsApp.getComponentName().getPackageName()) diff --git a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java index 061e86530..5d86d1ec6 100644 --- a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java +++ b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java @@ -61,7 +61,7 @@ public class ShortcutsToHomeTest extends LauncherInstrumentationTestCase { // Drag the first shortcut to the home screen. assertTrue(deepShortcutsContainer.getChildCount() > 0); UiObject2 shortcut = deepShortcutsContainer.getChildren().get(0) - .findObject(getSelectorForId(R.id.deep_shortcut)); + .findObject(getSelectorForId(R.id.bubble_text)); String shortcutName = shortcut.getText(); dragToWorkspace(shortcut, false); |