summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--res/layout/deep_shortcut.xml5
-rw-r--r--res/layout/system_shortcut.xml50
-rw-r--r--res/layout/system_shortcut_icon_only.xml23
-rw-r--r--res/layout/system_shortcut_icons.xml25
-rw-r--r--res/layout/widgets_list_row_view.xml16
-rw-r--r--res/values/colors.xml4
-rw-r--r--res/values/dimens.xml2
-rw-r--r--src/com/android/launcher3/AbstractFloatingView.java3
-rw-r--r--src/com/android/launcher3/Launcher.java15
-rw-r--r--src/com/android/launcher3/WidgetPreviewLoader.java11
-rw-r--r--src/com/android/launcher3/popup/PopupContainerWithArrow.java55
-rw-r--r--src/com/android/launcher3/popup/PopupDataProvider.java6
-rw-r--r--src/com/android/launcher3/popup/PopupItemView.java3
-rw-r--r--src/com/android/launcher3/popup/PopupPopulator.java84
-rw-r--r--src/com/android/launcher3/popup/SystemShortcut.java89
-rw-r--r--src/com/android/launcher3/shortcuts/DeepShortcutView.java7
-rw-r--r--src/com/android/launcher3/shortcuts/ShortcutsItemView.java102
-rw-r--r--src/com/android/launcher3/util/PackageUserKey.java4
-rw-r--r--src/com/android/launcher3/widget/WidgetCell.java10
-rw-r--r--src/com/android/launcher3/widget/WidgetsAndMore.java35
-rw-r--r--src/com/android/launcher3/widget/WidgetsContainerView.java7
-rw-r--r--src/com/android/launcher3/widget/WidgetsListAdapter.java23
-rw-r--r--tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java2
-rw-r--r--tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java2
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);