/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.appwidget; import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ParceledListSlice; import android.os.Bundle; import android.os.IBinder; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.util.DisplayMetrics; import android.util.TypedValue; import android.widget.RemoteViews; import com.android.internal.appwidget.IAppWidgetService; import java.util.Collections; import java.util.List; /** * Updates AppWidget state; gets information about installed AppWidget providers and other * AppWidget related state. * *
For more information about creating app widgets, read the * App Widgets developer guide.
** You must supply the following extras: *
{@link #EXTRA_APPWIDGET_ID} | *A newly allocated appWidgetId, which will be bound to the AppWidget provider * once the user has selected one. | *
* The system will respond with an onActivityResult call with the following extras in * the intent: *
{@link #EXTRA_APPWIDGET_ID} | *The appWidgetId that you supplied in the original intent. | *
* When you receive the result from the AppWidget pick activity, if the resultCode is * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected. You should then * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you * should delete the appWidgetId. * * @see #ACTION_APPWIDGET_CONFIGURE */ public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK"; /** * Similar to ACTION_APPWIDGET_PICK, but used from keyguard * @hide */ public static final String ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK"; /** * Activity action to launch from your {@link AppWidgetHost} activity when you want to bind * an AppWidget to display and bindAppWidgetIdIfAllowed returns false. *
* You must supply the following extras: *
{@link #EXTRA_APPWIDGET_ID} | *A newly allocated appWidgetId, which will be bound to the AppWidget provider * you provide. | *
{@link #EXTRA_APPWIDGET_PROVIDER} | *The BroadcastReceiver that will be the AppWidget provider for this AppWidget. * | *
{@link #EXTRA_APPWIDGET_PROVIDER_PROFILE} | *An optional handle to a user profile under which runs the provider * for this AppWidget. * | *
* The system will respond with an onActivityResult call with the following extras in * the intent: *
{@link #EXTRA_APPWIDGET_ID} | *The appWidgetId that you supplied in the original intent. | *
* When you receive the result from the AppWidget bind activity, if the resultCode is * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound. You should then * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you * should delete the appWidgetId. * * @see #ACTION_APPWIDGET_CONFIGURE * */ public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND"; /** * Sent when it is time to configure your AppWidget while it is being added to a host. * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo * meta-data}. * *
* The intent will contain the following extras: *
{@link #EXTRA_APPWIDGET_ID} | *The appWidgetId to configure. | *
If you return {@link android.app.Activity#RESULT_OK} using * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added, * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget. * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} * broadcast. */ public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE"; /** * An intent extra that contains one appWidgetId. *
* The value will be an int that can be retrieved like this: * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID} */ public static final String EXTRA_APPWIDGET_ID = "appWidgetId"; /** * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance. */ public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth"; /** * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance. */ public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight"; /** * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. */ public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth"; /** * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. */ public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight"; /** * A bundle extra that hints to the AppWidgetProvider the category of host that owns this * this widget. Can have the value {@link * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD} or {@link * AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}. */ public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory"; /** * An intent extra which points to a bundle of extra information for a particular widget id. * In particular this bundle can contain {@link #OPTION_APPWIDGET_MIN_WIDTH}, * {@link #OPTION_APPWIDGET_MIN_HEIGHT}, {@link #OPTION_APPWIDGET_MAX_WIDTH}, * {@link #OPTION_APPWIDGET_MAX_HEIGHT}. */ public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions"; /** * An intent extra that contains multiple appWidgetIds. *
* The value will be an int array that can be retrieved like this: * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS} */ public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds"; /** * An intent extra that contains the component name of a AppWidget provider. *
* The value will be an {@link android.content.ComponentName}. */ public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider"; /** * An intent extra that contains the user handle of the profile under * which an AppWidget provider is registered. *
* The value will be a {@link android.os.UserHandle}. */ public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile"; /** * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are * installed. (This is how the launcher shows the search widget). */ public static final String EXTRA_CUSTOM_INFO = "customInfo"; /** * An intent extra attached to the {@link #ACTION_APPWIDGET_HOST_RESTORED} broadcast, * indicating the integer ID of the host whose widgets have just been restored. */ public static final String EXTRA_HOST_ID = "hostId"; /** * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are * installed. It will be added to the extras object on the {@link android.content.Intent} * that is returned from the picker activity. * * {@more} */ public static final String EXTRA_CUSTOM_EXTRAS = "customExtras"; /** * An intent extra to pass to the AppWidget picker which allows the picker to filter * the list based on the {@link AppWidgetProviderInfo#widgetCategory}. * * @hide */ public static final String EXTRA_CATEGORY_FILTER = "categoryFilter"; /** * An intent extra to pass to the AppWidget picker to specify whether or not to sort * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets * @hide */ public static final String EXTRA_CUSTOM_SORT = "customSort"; /** * A sentinel value that the AppWidget manager will never return as a appWidgetId. */ public static final int INVALID_APPWIDGET_ID = 0; /** * Sent when it is time to update your AppWidget. * *
This may be sent in response to a new instance for this AppWidget provider having * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval} * having lapsed, or the system booting. * *
* The intent will contain the following extras: *
{@link #EXTRA_APPWIDGET_IDS} | *The appWidgetIds to update. This may be all of the AppWidgets created for this * provider, or just a subset. The system tries to send updates for as few AppWidget * instances as possible. | *
This is a protected intent that can only be sent * by the system. * * @see AppWidgetProvider#onAppWidgetOptionsChanged * AppWidgetProvider.onAppWidgetOptionsChanged(Context context, * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras) */ public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS"; /** * Sent when an instance of an AppWidget is deleted from its host. * *
This is a protected intent that can only be sent * by the system. * * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds) */ public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"; /** * Sent when the last AppWidget of this provider is removed from the last host. * *
This is a protected intent that can only be sent * by the system. * * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context) */ public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"; /** * Sent when an instance of an AppWidget is added to a host for the first time. * This broadcast is sent at boot time if there is a AppWidgetHost installed with * an instance for this provider. * *
This is a protected intent that can only be sent * by the system. * * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context) */ public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED"; /** * Sent to an {@link AppWidgetProvider} after AppWidget state related to that provider has * been restored from backup. The intent contains information about how to translate AppWidget * ids from the restored data to their new equivalents. * *
The intent will contain the following extras: * *
{@link #EXTRA_APPWIDGET_OLD_IDS} | *The set of appWidgetIds represented in a restored backup that have been successfully * incorporated into the current environment. This may be all of the AppWidgets known * to this application, or just a subset. Each entry in this array of appWidgetIds has * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra. | *
{@link #EXTRA_APPWIDGET_IDS} | *The set of appWidgetIds now valid for this application. The app should look at * its restored widget configuration and translate each appWidgetId in the * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding * index within this array. | *
This is a protected intent that can only be sent * by the system. * * @see #ACTION_APPWIDGET_HOST_RESTORED */ public static final String ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED"; /** * Sent to widget hosts after AppWidget state related to the host has been restored from * backup. The intent contains information about how to translate AppWidget ids from the * restored data to their new equivalents. If an application maintains multiple separate * widget host instances, it will receive this broadcast separately for each one. * *
The intent will contain the following extras: * *
{@link #EXTRA_APPWIDGET_OLD_IDS} | *The set of appWidgetIds represented in a restored backup that have been successfully * incorporated into the current environment. This may be all of the AppWidgets known * to this application, or just a subset. Each entry in this array of appWidgetIds has * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra. | *
{@link #EXTRA_APPWIDGET_IDS} | *The set of appWidgetIds now valid for this application. The app should look at * its restored widget configuration and translate each appWidgetId in the * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding * index within this array. | *
{@link #EXTRA_HOST_ID} | *The integer ID of the widget host instance whose state has just been restored. | *
This is a protected intent that can only be sent * by the system. * * @see #ACTION_APPWIDGET_RESTORED */ public static final String ACTION_APPWIDGET_HOST_RESTORED = "android.appwidget.action.APPWIDGET_HOST_RESTORED"; /** * An intent extra that contains multiple appWidgetIds. These are id values as * they were provided to the application during a recent restore from backup. It is * attached to the {@link #ACTION_APPWIDGET_RESTORED} broadcast intent. * *
* The value will be an int array that can be retrieved like this: * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS} */ public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds"; /** * Field for the manifest meta-data tag. * * @see AppWidgetProviderInfo */ public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider"; private final String mPackageName; private final IAppWidgetService mService; private final DisplayMetrics mDisplayMetrics; /** * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context * Context} object. */ public static AppWidgetManager getInstance(Context context) { return (AppWidgetManager) context.getSystemService(Context.APPWIDGET_SERVICE); } /** * Creates a new instance. * * @param context The current context in which to operate. * @param service The backing system service. * @hide */ public AppWidgetManager(Context context, IAppWidgetService service) { mPackageName = context.getOpPackageName(); mService = service; mDisplayMetrics = context.getResources().getDisplayMetrics(); } /** * Set the RemoteViews to use for the specified appWidgetIds. *
* Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should * contain a complete representation of the widget. For performing partial widget updates, see * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}. * *
* It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, * and outside of the handler. * This method will only work when called from the uid that owns the AppWidget provider. * *
* The total Bitmap memory used by the RemoteViews object cannot exceed that required to * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. * * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. * @param views The RemoteViews object to show. */ public void updateAppWidget(int[] appWidgetIds, RemoteViews views) { if (mService == null) { return; } try { mService.updateAppWidgetIds(mPackageName, appWidgetIds, views); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * 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 #getAppWidgetOptions(int) * * @param appWidgetId The AppWidget instances for which to set the RemoteViews. * @param options The options to associate with this widget */ public void updateAppWidgetOptions(int appWidgetId, Bundle options) { if (mService == null) { return; } try { mService.updateAppWidgetOptions(mPackageName, appWidgetId, options); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * 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 #updateAppWidgetOptions(int, Bundle) * * @param appWidgetId The AppWidget instances for which to set the RemoteViews. * @return The options associated with the given widget instance. */ public Bundle getAppWidgetOptions(int appWidgetId) { if (mService == null) { return Bundle.EMPTY; } try { return mService.getAppWidgetOptions(mPackageName, appWidgetId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Set the RemoteViews to use for the specified appWidgetId. *
* Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should * contain a complete representation of the widget. For performing partial widget updates, see * {@link #partiallyUpdateAppWidget(int, RemoteViews)}. * *
* It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, * and outside of the handler. * This method will only work when called from the uid that owns the AppWidget provider. * *
* The total Bitmap memory used by the RemoteViews object cannot exceed that required to * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. * * @param appWidgetId The AppWidget instance for which to set the RemoteViews. * @param views The RemoteViews object to show. */ public void updateAppWidget(int appWidgetId, RemoteViews views) { if (mService == null) { return; } updateAppWidget(new int[] { appWidgetId }, views); } /** * Perform an incremental update or command on the widget(s) specified by appWidgetIds. *
* This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the * RemoteViews object which is passed is understood to be an incomplete representation of the * widget, and hence does not replace the cached representation of the widget. As of API * level 17, the new properties set within the views objects will be appended to the cached * representation of the widget, and hence will persist. * * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. * *
* It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, * and outside of the handler. * This method will only work when called from the uid that owns the AppWidget provider. * *
* This method will be ignored if a widget has not received a full update via * {@link #updateAppWidget(int[], RemoteViews)}. * * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. * @param views The RemoteViews object containing the incremental update / command. */ public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) { if (mService == null) { return; } try { mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Perform an incremental update or command on the widget specified by appWidgetId. *
* This update differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews * object which is passed is understood to be an incomplete representation of the widget, and * hence is not cached by the AppWidgetService. Note that because these updates are not cached, * any state that they modify that is not restored by restoreInstanceState will not persist in * the case that the widgets are restored using the cached version in AppWidgetService. * * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. * *
* It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, * and outside of the handler. * This method will only work when called from the uid that owns the AppWidget provider. * *
* This method will be ignored if a widget has not received a full update via * {@link #updateAppWidget(int[], RemoteViews)}. * * @param appWidgetId The AppWidget instance for which to set the RemoteViews. * @param views The RemoteViews object containing the incremental update / command. */ public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) { if (mService == null) { return; } partiallyUpdateAppWidget(new int[] { appWidgetId }, views); } /** * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider. * *
* It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
* and outside of the handler.
* This method will only work when called from the uid that owns the AppWidget provider.
*
* @param provider The {@link ComponentName} for the {@link
* android.content.BroadcastReceiver BroadcastReceiver} provider
* for your AppWidget.
* @param views The RemoteViews object to show.
*/
public void updateAppWidget(ComponentName provider, RemoteViews views) {
if (mService == null) {
return;
}
try {
mService.updateAppWidgetProvider(provider, views);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Notifies the specified collection view in all the specified AppWidget instances
* to invalidate their data.
*
* @param appWidgetIds The AppWidget instances to notify of view data changes.
* @param viewId The collection view id.
*/
public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
if (mService == null) {
return;
}
try {
mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Notifies the specified collection view in the specified AppWidget instance
* to invalidate its data.
*
* @param appWidgetId The AppWidget instance to notify of view data changes.
* @param viewId The collection view id.
*/
public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
if (mService == null) {
return;
}
notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
}
/**
* Gets the AppWidget providers for the given user profile. User profile can only
* be the current user or a profile of the current user. For example, the current
* user may have a corporate profile. In this case the parent user profile has a
* child profile, the corporate one.
*
* @param profile The profile for which to get providers. Passing null is equivaled
* to passing only the current user handle.
* @return The intalled providers.
*
* @see android.os.Process#myUserHandle()
* @see android.os.UserManager#getUserProfiles()
*/
public List You need the BIND_APPWIDGET permission or the user must have enabled binding
* widgets always for your component. This method is used by the AppWidget picker and
* should not be used by other apps.
*
* @param appWidgetId The AppWidget instance for which to set the RemoteViews.
* @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
* provider for this AppWidget.
* @hide
*/
public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
if (mService == null) {
return;
}
bindAppWidgetId(appWidgetId, provider, null);
}
/**
* Set the component for a given appWidgetId.
*
* You need the BIND_APPWIDGET permission or the user must have enabled binding
* widgets always for your component. This method is used by the AppWidget picker and
* should not be used by other apps.
*
* @param appWidgetId The AppWidget instance for which to set the RemoteViews.
* @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
* provider for this AppWidget.
* @param options Bundle containing options for the AppWidget. See also
* {@link #updateAppWidgetOptions(int, Bundle)}
*
* @hide
*/
public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
if (mService == null) {
return;
}
bindAppWidgetIdIfAllowed(appWidgetId, Process.myUserHandle(), provider, options);
}
/**
* Set the component for a given appWidgetId.
*
* You need the BIND_APPWIDGET permission or the user must have enabled binding
* widgets always for your component. Should be used by apps that host widgets; if this
* method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
* bind
*
* @param appWidgetId The AppWidget id under which to bind the provider.
* @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
* provider for this AppWidget.
* @return true if this component has permission to bind the AppWidget
*/
public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
if (mService == null) {
return false;
}
return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, null);
}
/**
* Set the component for a given appWidgetId.
*
* You need the BIND_APPWIDGET permission or the user must have enabled binding
* widgets always for your component. Should be used by apps that host widgets; if this
* method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
* bind
*
* @param appWidgetId The AppWidget id under which to bind the provider.
* @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
* provider for this AppWidget.
* @param options Bundle containing options for the AppWidget. See also
* {@link #updateAppWidgetOptions(int, Bundle)}
*
* @return true if this component has permission to bind the AppWidget
*/
public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
Bundle options) {
if (mService == null) {
return false;
}
return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, options);
}
/**
* Set the provider for a given appWidgetId if the caller has a permission.
*
* Note: You need the {@link android.Manifest.permission#BIND_APPWIDGET}
* permission or the user must have enabled binding widgets always for your component.
* Should be used by apps that host widgets. If this method returns false, call {@link
* #ACTION_APPWIDGET_BIND} to request permission to bind.
* You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
*
* @param packageName The package for which the permission is being queried
* @param userId The user id of the user under which the package runs.
* @return true if the package was granted permission by the user to bind app widgets
* @hide
*/
public boolean hasBindAppWidgetPermission(String packageName, int userId) {
if (mService == null) {
return false;
}
try {
return mService.hasBindAppWidgetPermission(packageName, userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Query if a given package was granted permission by the user to bind app widgets
*
* You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
*
* @param packageName The package for which the permission is being queried
* @return true if the package was granted permission by the user to bind app widgets
* @hide
*/
public boolean hasBindAppWidgetPermission(String packageName) {
if (mService == null) {
return false;
}
try {
return mService.hasBindAppWidgetPermission(packageName, UserHandle.myUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Changes any user-granted permission for the given package to bind app widgets
*
* You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
*
* @param packageName The package whose permission is being changed
* @param permission Whether to give the package permission to bind widgets
*
* @hide
*/
public void setBindAppWidgetPermission(String packageName, boolean permission) {
if (mService == null) {
return;
}
setBindAppWidgetPermission(packageName, UserHandle.myUserId(), permission);
}
/**
* Changes any user-granted permission for the given package to bind app widgets
*
* You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
*
* @param packageName The package whose permission is being changed
* @param userId The user under which the package is running.
* @param permission Whether to give the package permission to bind widgets
*
* @hide
*/
public void setBindAppWidgetPermission(String packageName, int userId, boolean permission) {
if (mService == null) {
return;
}
try {
mService.setBindAppWidgetPermission(packageName, userId, permission);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Binds the RemoteViewsService for a given appWidgetId and intent.
*
* The appWidgetId specified must already be bound to the calling AppWidgetHost via
* {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
*
* @param packageName The package from which the binding is requested.
* @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
* @param intent The intent of the service which will be providing the data to the
* RemoteViewsAdapter.
* @param connection The callback interface to be notified when a connection is made or lost.
* @hide
*/
public void bindRemoteViewsService(String packageName, int appWidgetId, Intent intent,
IBinder connection) {
if (mService == null) {
return;
}
try {
mService.bindRemoteViewsService(packageName, appWidgetId, intent, connection);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Unbinds the RemoteViewsService for a given appWidgetId and intent.
*
* The appWidgetId specified muse already be bound to the calling AppWidgetHost via
* {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
*
* @param packageName The package from which the binding is requested.
* @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
* @param intent The intent of the service which will be providing the data to the
* RemoteViewsAdapter.
* @hide
*/
public void unbindRemoteViewsService(String packageName, int appWidgetId, Intent intent) {
if (mService == null) {
return;
}
try {
mService.unbindRemoteViewsService(packageName, appWidgetId, intent);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* Get the list of appWidgetIds that have been bound to the given AppWidget
* provider.
*
* @param provider The {@link android.content.BroadcastReceiver} that is the
* AppWidget provider to find appWidgetIds for.
*/
public int[] getAppWidgetIds(ComponentName provider) {
if (mService == null) {
return new int[0];
}
try {
return mService.getAppWidgetIds(provider);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* @hide
*/
public boolean isBoundWidgetPackage(String packageName, int userId) {
if (mService == null) {
return false;
}
try {
return mService.isBoundWidgetPackage(packageName, userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId,
ComponentName provider, Bundle options) {
if (mService == null) {
return false;
}
try {
return mService.bindAppWidgetId(mPackageName, appWidgetId,
profileId, provider, options);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
private void convertSizesToPixels(AppWidgetProviderInfo info) {
// Converting complex to dp.
info.minWidth = TypedValue.complexToDimensionPixelSize(info.minWidth,
mDisplayMetrics);
info.minHeight = TypedValue.complexToDimensionPixelSize(info.minHeight,
mDisplayMetrics);
info.minResizeWidth = TypedValue.complexToDimensionPixelSize(info.minResizeWidth,
mDisplayMetrics);
info.minResizeHeight = TypedValue.complexToDimensionPixelSize(info.minResizeHeight,
mDisplayMetrics);
}
}