1 package com.android.launcher3; 2 3 import android.appwidget.AppWidgetHostView; 4 import android.appwidget.AppWidgetProviderInfo; 5 import android.content.ComponentName; 6 import android.content.Context; 7 import android.content.pm.PackageManager; 8 import android.graphics.Point; 9 import android.graphics.Rect; 10 import android.graphics.drawable.Drawable; 11 import android.os.Parcel; 12 import android.os.UserHandle; 13 14 import com.android.launcher3.icons.ComponentWithLabelAndIcon; 15 import com.android.launcher3.icons.IconCache; 16 import com.android.launcher3.model.data.LauncherAppWidgetInfo; 17 18 /** 19 * This class is a thin wrapper around the framework AppWidgetProviderInfo class. This class affords 20 * a common object for describing both framework provided AppWidgets as well as custom widgets 21 * (who's implementation is owned by the launcher). This object represents a widget type / class, 22 * as opposed to a widget instance, and so should not be confused with {@link LauncherAppWidgetInfo} 23 */ 24 public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo 25 implements ComponentWithLabelAndIcon { 26 27 public static final String CLS_CUSTOM_WIDGET_PREFIX = "#custom-widget-"; 28 29 public int spanX; 30 public int spanY; 31 public int minSpanX; 32 public int minSpanY; 33 fromProviderInfo(Context context, AppWidgetProviderInfo info)34 public static LauncherAppWidgetProviderInfo fromProviderInfo(Context context, 35 AppWidgetProviderInfo info) { 36 final LauncherAppWidgetProviderInfo launcherInfo; 37 if (info instanceof LauncherAppWidgetProviderInfo) { 38 launcherInfo = (LauncherAppWidgetProviderInfo) info; 39 } else { 40 41 // In lieu of a public super copy constructor, we first write the AppWidgetProviderInfo 42 // into a parcel, and then construct a new LauncherAppWidgetProvider info from the 43 // associated super parcel constructor. This allows us to copy non-public members without 44 // using reflection. 45 Parcel p = Parcel.obtain(); 46 info.writeToParcel(p, 0); 47 p.setDataPosition(0); 48 launcherInfo = new LauncherAppWidgetProviderInfo(p); 49 p.recycle(); 50 } 51 launcherInfo.initSpans(context); 52 return launcherInfo; 53 } 54 LauncherAppWidgetProviderInfo()55 protected LauncherAppWidgetProviderInfo() {} 56 LauncherAppWidgetProviderInfo(Parcel in)57 protected LauncherAppWidgetProviderInfo(Parcel in) { 58 super(in); 59 } 60 initSpans(Context context)61 public void initSpans(Context context) { 62 InvariantDeviceProfile idp = LauncherAppState.getIDP(context); 63 64 Point landCellSize = idp.landscapeProfile.getCellSize(); 65 Point portCellSize = idp.portraitProfile.getCellSize(); 66 67 // Always assume we're working with the smallest span to make sure we 68 // reserve enough space in both orientations. 69 float smallestCellWidth = Math.min(landCellSize.x, portCellSize.x); 70 float smallestCellHeight = Math.min(landCellSize.y, portCellSize.y); 71 72 // We want to account for the extra amount of padding that we are adding to the widget 73 // to ensure that it gets the full amount of space that it has requested. 74 Rect widgetPadding = AppWidgetHostView.getDefaultPaddingForWidget( 75 context, provider, null); 76 spanX = Math.max(1, (int) Math.ceil( 77 (minWidth + widgetPadding.left + widgetPadding.right) / smallestCellWidth)); 78 spanY = Math.max(1, (int) Math.ceil( 79 (minHeight + widgetPadding.top + widgetPadding.bottom) / smallestCellHeight)); 80 81 minSpanX = Math.max(1, (int) Math.ceil( 82 (minResizeWidth + widgetPadding.left + widgetPadding.right) / smallestCellWidth)); 83 minSpanY = Math.max(1, (int) Math.ceil( 84 (minResizeHeight + widgetPadding.top + widgetPadding.bottom) / smallestCellHeight)); 85 } 86 getLabel(PackageManager packageManager)87 public String getLabel(PackageManager packageManager) { 88 return super.loadLabel(packageManager); 89 } 90 getMinSpans()91 public Point getMinSpans() { 92 return new Point((resizeMode & RESIZE_HORIZONTAL) != 0 ? minSpanX : -1, 93 (resizeMode & RESIZE_VERTICAL) != 0 ? minSpanY : -1); 94 } 95 isCustomWidget()96 public boolean isCustomWidget() { 97 return provider.getClassName().startsWith(CLS_CUSTOM_WIDGET_PREFIX); 98 } 99 getWidgetFeatures()100 public int getWidgetFeatures() { 101 if (Utilities.ATLEAST_P) { 102 return widgetFeatures; 103 } else { 104 return 0; 105 } 106 } 107 108 @Override getComponent()109 public final ComponentName getComponent() { 110 return provider; 111 } 112 113 @Override getUser()114 public final UserHandle getUser() { 115 return getProfile(); 116 } 117 118 @Override getFullResIcon(IconCache cache)119 public Drawable getFullResIcon(IconCache cache) { 120 return cache.getFullResIcon(provider.getPackageName(), icon); 121 } 122 } 123