diff options
-rw-r--r-- | api/current.txt | 11 | ||||
-rw-r--r-- | core/java/android/appwidget/AppWidgetHostView.java | 40 | ||||
-rw-r--r-- | core/java/android/appwidget/AppWidgetManager.java | 75 | ||||
-rwxr-xr-x | core/java/android/appwidget/AppWidgetProvider.java | 33 | ||||
-rw-r--r-- | core/java/com/android/internal/appwidget/IAppWidgetService.aidl | 3 | ||||
-rw-r--r-- | services/java/com/android/server/AppWidgetService.java | 11 | ||||
-rw-r--r-- | services/java/com/android/server/AppWidgetServiceImpl.java | 33 |
7 files changed, 204 insertions, 2 deletions
diff --git a/api/current.txt b/api/current.txt index 6d8e9a0..c4d8968 100644 --- a/api/current.txt +++ b/api/current.txt @@ -4301,10 +4301,13 @@ package android.appwidget { method protected void prepareView(android.view.View); method public void setAppWidget(int, android.appwidget.AppWidgetProviderInfo); method public void updateAppWidget(android.widget.RemoteViews); + method public void updateAppWidgetExtras(android.os.Bundle); + method public void updateAppWidgetSize(android.os.Bundle, int, int, int, int); } public class AppWidgetManager { method public void bindAppWidgetId(int, android.content.ComponentName); + method public android.os.Bundle getAppWidgetExtras(int); method public int[] getAppWidgetIds(android.content.ComponentName); method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int); method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders(); @@ -4316,14 +4319,21 @@ package android.appwidget { method public void updateAppWidget(int[], android.widget.RemoteViews); method public void updateAppWidget(int, android.widget.RemoteViews); method public void updateAppWidget(android.content.ComponentName, android.widget.RemoteViews); + method public void updateAppWidgetExtras(int, android.os.Bundle); field public static final java.lang.String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE"; field public static final java.lang.String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"; field public static final java.lang.String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"; field public static final java.lang.String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED"; + field public static final java.lang.String ACTION_APPWIDGET_EXTRAS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_EXTRAS"; field public static final java.lang.String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK"; field public static final java.lang.String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; + field public static final java.lang.String EXTRA_APPWIDGET_EXTRAS = "appWidgetExtras"; field public static final java.lang.String EXTRA_APPWIDGET_ID = "appWidgetId"; field public static final java.lang.String EXTRA_APPWIDGET_IDS = "appWidgetIds"; + field public static final java.lang.String EXTRA_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight"; + field public static final java.lang.String EXTRA_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth"; + field public static final java.lang.String EXTRA_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight"; + field public static final java.lang.String EXTRA_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth"; field public static final java.lang.String EXTRA_CUSTOM_EXTRAS = "customExtras"; field public static final java.lang.String EXTRA_CUSTOM_INFO = "customInfo"; field public static final int INVALID_APPWIDGET_ID = 0; // 0x0 @@ -4332,6 +4342,7 @@ package android.appwidget { public class AppWidgetProvider extends android.content.BroadcastReceiver { ctor public AppWidgetProvider(); + method public void onAppWidgetExtrasChanged(android.content.Context, android.appwidget.AppWidgetManager, int, android.os.Bundle); method public void onDeleted(android.content.Context, int[]); method public void onDisabled(android.content.Context); method public void onEnabled(android.content.Context); diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 61a9dce..c1b8e7c 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -28,6 +28,7 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.os.Build; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; @@ -206,6 +207,45 @@ public class AppWidgetHostView extends FrameLayout { super.dispatchRestoreInstanceState(jail); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int oldWidth = getMeasuredWidth(); + int oldHeight = getMeasuredHeight(); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int newWidth = getMeasuredWidth(); + int newHeight = getMeasuredHeight(); + + // TODO: this is just a hack for now -- we actually have the AppWidgetHost + // be responsible for updating the size of the widget. + if (oldWidth != newWidth || oldHeight != newHeight) { + final float density = mContext.getResources().getDisplayMetrics().density; + final int newWidthDips = (int) (newWidth / density); + final int newHeightDips = (int) (newHeight / density); + updateAppWidgetSize(null, newWidthDips, newHeightDips, newWidthDips, newHeightDips); + } + } + + /** + * Provide guidance about the size of this widget to the AppWidgetManager. This information + * gets embedded into the AppWidgetExtras and causes a callback to the AppWidgetProvider. + * + * @see AppWidgetProvider#onAppWidgetExtrasChanged(Context, AppWidgetManager, int, Bundle) + */ + public void updateAppWidgetSize(Bundle extras, int minWidth, int minHeight, int maxWidth, int maxHeight) { + if (extras == null) { + extras = new Bundle(); + } + extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MIN_WIDTH, minWidth); + extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MIN_HEIGHT, minHeight); + extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MAX_WIDTH, maxWidth); + extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_MAX_HEIGHT, maxHeight); + updateAppWidgetExtras(extras); + } + + public void updateAppWidgetExtras(Bundle extras) { + AppWidgetManager.getInstance(mContext).updateAppWidgetExtras(mAppWidgetId, extras); + } + /** {@inheritDoc} */ @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java index a7f7792..83ab817 100644 --- a/core/java/android/appwidget/AppWidgetManager.java +++ b/core/java/android/appwidget/AppWidgetManager.java @@ -19,6 +19,7 @@ package android.appwidget; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -109,6 +110,32 @@ public class AppWidgetManager { public static final String EXTRA_APPWIDGET_ID = "appWidgetId"; /** + * An bundle extra that contains the lower bound on the current width, in dips, of a widget instance. + */ + public static final String EXTRA_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth"; + + /** + * An bundle extra that contains the lower bound on the current height, in dips, of a widget instance. + */ + public static final String EXTRA_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight"; + + /** + * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance. + */ + public static final String EXTRA_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth"; + + /** + * An bundle extra that contains the upper bound on the current width, in dips, of a widget instance. + */ + public static final String EXTRA_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight"; + + /** + * An intent extra which points to a bundle of extra information for a particular widget id. + * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT. + */ + public static final String EXTRA_APPWIDGET_EXTRAS = "appWidgetExtras"; + + /** * An intent extra that contains multiple appWidgetIds. * <p> * The value will be an int array that can be retrieved like this: @@ -161,6 +188,14 @@ public class AppWidgetManager { public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; /** + * Sent when the custom extras for an AppWidget change. + * + * @see AppWidgetProvider#onAppWidgetExtrasChanged AppWidgetProvider#onAppWidgetExtrasChanged( + * Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras) + */ + public static final String ACTION_APPWIDGET_EXTRAS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_EXTRAS"; + + /** * Sent when an instance of an AppWidget is deleted from its host. * * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds) @@ -252,6 +287,46 @@ public class AppWidgetManager { } /** + * Update the extras for a given widget instance. + * + * The extras can be used to embed additional information about this widget to be accessed + * by the associated widget's AppWidgetProvider. + * + * @see #getAppWidgetExtras(int) + * + * @param appWidgetId The AppWidget instances for which to set the RemoteViews. + * @param extras The extras to associate with this widget + */ + public void updateAppWidgetExtras(int appWidgetId, Bundle extras) { + try { + sService.updateAppWidgetExtras(appWidgetId, extras); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + /** + * Get the extras associated with a given widget instance. + * + * The extras can be used to embed additional information about this widget to be accessed + * by the associated widget's AppWidgetProvider. + * + * @see #updateAppWidgetExtras(int, Bundle) + * + * @param appWidgetId The AppWidget instances for which to set the RemoteViews. + * @return The extras associated with the given widget instance. + */ + public Bundle getAppWidgetExtras(int appWidgetId) { + try { + return sService.getAppWidgetExtras(appWidgetId); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + /** * Set the RemoteViews to use for the specified appWidgetId. * * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java index 00a5f0c..3cf40ae 100755 --- a/core/java/android/appwidget/AppWidgetProvider.java +++ b/core/java/android/appwidget/AppWidgetProvider.java @@ -74,6 +74,16 @@ public class AppWidgetProvider extends BroadcastReceiver { this.onDeleted(context, new int[] { appWidgetId }); } } + else if (AppWidgetManager.ACTION_APPWIDGET_EXTRAS_CHANGED.equals(action)) { + Bundle extras = intent.getExtras(); + if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID) + && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS)) { + int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID); + Bundle widgetExtras = extras.getBundle(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS); + this.onAppWidgetExtrasChanged(context, AppWidgetManager.getInstance(context), + appWidgetId, widgetExtras); + } + } else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) { this.onEnabled(context); } @@ -82,7 +92,7 @@ public class AppWidgetProvider extends BroadcastReceiver { } } // END_INCLUDE(onReceive) - + /** * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} broadcast when * this AppWidget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews} @@ -102,7 +112,26 @@ public class AppWidgetProvider extends BroadcastReceiver { */ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { } - + + /** + * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_EXTRAS_CHANGED} + * broadcast when this widget has been layed out at a new size. + * + * {@more} + * + * @param context The {@link android.content.Context Context} in which this receiver is + * running. + * @param appWidgetManager A {@link AppWidgetManager} object you can call {@link + * AppWidgetManager#updateAppWidget} on. + * @param appWidgetId The appWidgetId of the widget who's size changed. + * @param newExtras The appWidgetId of the widget who's size changed. + * + * @see AppWidgetManager#ACTION_APPWIDGET_EXTRAS_CHANGED + */ + public void onAppWidgetExtrasChanged(Context context, AppWidgetManager appWidgetManager, + int appWidgetId, Bundle newExtras) { + } + /** * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_DELETED} broadcast when * one or more AppWidget instances have been deleted. Override this method to implement diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl index fa0873d..b1b57e7 100644 --- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl +++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl @@ -20,6 +20,7 @@ import android.content.ComponentName; import android.content.Intent; import android.appwidget.AppWidgetProviderInfo; import com.android.internal.appwidget.IAppWidgetHost; +import android.os.Bundle; import android.os.IBinder; import android.widget.RemoteViews; @@ -42,6 +43,8 @@ interface IAppWidgetService { // for AppWidgetManager // void updateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views); + void updateAppWidgetExtras(int appWidgetId, in Bundle extras); + Bundle getAppWidgetExtras(int appWidgetId); void partiallyUpdateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views); void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views); void notifyAppWidgetViewDataChanged(in int[] appWidgetIds, int viewId); diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index eb024e9..bf958a5 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -28,6 +28,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Pair; @@ -260,6 +261,16 @@ class AppWidgetService extends IAppWidgetService.Stub return getImplForUser().getAppWidgetViews(appWidgetId); } + @Override + public void updateAppWidgetExtras(int appWidgetId, Bundle extras) { + getImplForUser().updateAppWidgetExtras(appWidgetId, extras); + } + + @Override + public Bundle getAppWidgetExtras(int appWidgetId) { + return getImplForUser().getAppWidgetExtras(appWidgetId); + } + static int[] getAppWidgetIds(Provider p) { int instancesSize = p.instances.size(); int appWidgetIds[] = new int[instancesSize]; diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index b24823e..3b43b9b 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -113,6 +113,7 @@ class AppWidgetServiceImpl { int appWidgetId; Provider provider; RemoteViews views; + Bundle extras; Host host; } @@ -760,6 +761,38 @@ class AppWidgetServiceImpl { } } + public void updateAppWidgetExtras(int appWidgetId, Bundle extras) { + synchronized (mAppWidgetIds) { + ensureStateLoadedLocked(); + AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); + + if (id == null) { + return; + } + Provider p = id.provider; + id.extras = extras; + + // send the broacast saying that this appWidgetId has been deleted + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_EXTRAS_CHANGED); + intent.setComponent(p.info.provider); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_EXTRAS, extras); + mContext.sendBroadcast(intent, mUserId); + } + } + + public Bundle getAppWidgetExtras(int appWidgetId) { + synchronized (mAppWidgetIds) { + ensureStateLoadedLocked(); + AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId); + if (id != null && id.extras != null) { + return id.extras; + } else { + return Bundle.EMPTY; + } + } + } + public void partiallyUpdateAppWidgetIds(int[] appWidgetIds, RemoteViews views) { if (appWidgetIds == null) { return; |