Home | History | Annotate | Download | only in appwidget
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.appwidget;
     18 
     19 import android.annotation.BroadcastBehavior;
     20 import android.annotation.NonNull;
     21 import android.annotation.Nullable;
     22 import android.annotation.RequiresFeature;
     23 import android.annotation.SdkConstant;
     24 import android.annotation.SdkConstant.SdkConstantType;
     25 import android.annotation.SystemService;
     26 import android.annotation.UnsupportedAppUsage;
     27 import android.app.IServiceConnection;
     28 import android.app.PendingIntent;
     29 import android.content.ComponentName;
     30 import android.content.Context;
     31 import android.content.Intent;
     32 import android.content.IntentSender;
     33 import android.content.ServiceConnection;
     34 import android.content.pm.PackageManager;
     35 import android.content.pm.ParceledListSlice;
     36 import android.content.pm.ShortcutInfo;
     37 import android.os.Bundle;
     38 import android.os.Handler;
     39 import android.os.RemoteException;
     40 import android.os.UserHandle;
     41 import android.util.DisplayMetrics;
     42 import android.widget.RemoteViews;
     43 
     44 import com.android.internal.appwidget.IAppWidgetService;
     45 
     46 import java.util.Collections;
     47 import java.util.List;
     48 
     49 /**
     50  * Updates AppWidget state; gets information about installed AppWidget providers and other
     51  * AppWidget related state.
     52  *
     53  * <div class="special reference">
     54  * <h3>Developer Guides</h3>
     55  * <p>For more information about creating app widgets, read the
     56  * <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a> developer guide.</p>
     57  * </div>
     58  */
     59 @SystemService(Context.APPWIDGET_SERVICE)
     60 @RequiresFeature(PackageManager.FEATURE_APP_WIDGETS)
     61 public class AppWidgetManager {
     62 
     63     /**
     64      * Activity action to launch from your {@link AppWidgetHost} activity when you want to
     65      * pick an AppWidget to display.  The AppWidget picker activity will be launched.
     66      * <p>
     67      * You must supply the following extras:
     68      * <table>
     69      *   <tr>
     70      *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
     71      *     <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
     72      *         once the user has selected one.</td>
     73      *  </tr>
     74      * </table>
     75      *
     76      * <p>
     77      * The system will respond with an onActivityResult call with the following extras in
     78      * the intent:
     79      * <table>
     80      *   <tr>
     81      *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
     82      *     <td>The appWidgetId that you supplied in the original intent.</td>
     83      *  </tr>
     84      * </table>
     85      * <p>
     86      * When you receive the result from the AppWidget pick activity, if the resultCode is
     87      * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected.  You should then
     88      * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
     89      * configuration activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you
     90      * should delete the appWidgetId.
     91      *
     92      * @see #ACTION_APPWIDGET_CONFIGURE
     93      */
     94     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     95     public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
     96 
     97     /**
     98      * Similar to ACTION_APPWIDGET_PICK, but used from keyguard
     99      * @hide
    100      */
    101     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    102     public static final String
    103             ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK";
    104 
    105     /**
    106      * Activity action to launch from your {@link AppWidgetHost} activity when you want to bind
    107      * an AppWidget to display and bindAppWidgetIdIfAllowed returns false.
    108      * <p>
    109      * You must supply the following extras:
    110      * <table>
    111      *   <tr>
    112      *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
    113      *     <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
    114      *         you provide.</td>
    115      *  </tr>
    116      *  <tr>
    117      *     <td>{@link #EXTRA_APPWIDGET_PROVIDER}</td>
    118      *     <td>The BroadcastReceiver that will be the AppWidget provider for this AppWidget.
    119      *     </td>
    120      *  </tr>
    121      *  <tr>
    122      *     <td>{@link #EXTRA_APPWIDGET_PROVIDER_PROFILE}</td>
    123      *     <td>An optional handle to a user profile under which runs the provider
    124      *     for this AppWidget.
    125      *     </td>
    126      *  </tr>
    127      * </table>
    128      *
    129      * <p>
    130      * The system will respond with an onActivityResult call with the following extras in
    131      * the intent:
    132      * <table>
    133      *   <tr>
    134      *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
    135      *     <td>The appWidgetId that you supplied in the original intent.</td>
    136      *  </tr>
    137      * </table>
    138      * <p>
    139      * When you receive the result from the AppWidget bind activity, if the resultCode is
    140      * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound.  You should then
    141      * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
    142      * configuration activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you
    143      * should delete the appWidgetId.
    144      *
    145      * @see #ACTION_APPWIDGET_CONFIGURE
    146      *
    147      */
    148     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    149     public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND";
    150 
    151     /**
    152      * Sent when it is time to configure your AppWidget while it is being added to a host.
    153      * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity
    154      * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo
    155      * meta-data}.
    156      *
    157      * <p>
    158      * The intent will contain the following extras:
    159      * <table>
    160      *   <tr>
    161      *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
    162      *     <td>The appWidgetId to configure.</td>
    163      *  </tr>
    164      * </table>
    165      *
    166      * <p>If you return {@link android.app.Activity#RESULT_OK} using
    167      * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added,
    168      * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget.
    169      * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
    170      * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED}
    171      * broadcast.
    172      */
    173     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    174     public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
    175 
    176     /**
    177      * An intent extra that contains one appWidgetId.
    178      * <p>
    179      * The value will be an int that can be retrieved like this:
    180      * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID}
    181      */
    182     public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
    183 
    184     /**
    185      * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance.
    186      */
    187     public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
    188 
    189     /**
    190      * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance.
    191      */
    192     public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
    193 
    194     /**
    195      * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
    196      */
    197     public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
    198 
    199     /**
    200      * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
    201      */
    202     public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
    203 
    204     /**
    205      * A bundle extra that hints to the AppWidgetProvider the category of host that owns this
    206      * this widget. Can have the value {@link
    207      * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link
    208      * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD} or {@link
    209      * AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}.
    210      */
    211     public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
    212 
    213     /**
    214      * An intent extra which points to a bundle of extra information for a particular widget id.
    215      * In particular this bundle can contain {@link #OPTION_APPWIDGET_MIN_WIDTH},
    216      * {@link #OPTION_APPWIDGET_MIN_HEIGHT}, {@link #OPTION_APPWIDGET_MAX_WIDTH},
    217      * {@link #OPTION_APPWIDGET_MAX_HEIGHT}.
    218      */
    219     public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
    220 
    221     /**
    222      * An intent extra that contains multiple appWidgetIds.
    223      * <p>
    224      * The value will be an int array that can be retrieved like this:
    225      * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
    226      */
    227     public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
    228 
    229     /**
    230      * An intent extra that contains the component name of a AppWidget provider.
    231      * <p>
    232      * The value will be an {@link android.content.ComponentName}.
    233      */
    234     public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
    235 
    236     /**
    237      * An intent extra that contains the user handle of the profile under
    238      * which an AppWidget provider is registered.
    239      * <p>
    240      * The value will be a {@link android.os.UserHandle}.
    241      */
    242     public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
    243 
    244     /**
    245      * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
    246      * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are
    247      * installed.  (This is how the launcher shows the search widget).
    248      */
    249     public static final String EXTRA_CUSTOM_INFO = "customInfo";
    250 
    251     /**
    252      * An intent extra attached to the {@link #ACTION_APPWIDGET_HOST_RESTORED} broadcast,
    253      * indicating the integer ID of the host whose widgets have just been restored.
    254      */
    255     public static final String EXTRA_HOST_ID = "hostId";
    256 
    257     /**
    258      * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
    259      * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are
    260      * installed.  It will be added to the extras object on the {@link android.content.Intent}
    261      * that is returned from the picker activity.
    262      *
    263      * {@more}
    264      */
    265     public static final String EXTRA_CUSTOM_EXTRAS = "customExtras";
    266 
    267     /**
    268      * An intent extra to pass to the AppWidget picker which allows the picker to filter
    269      * the list based on the {@link AppWidgetProviderInfo#widgetCategory}.
    270      *
    271      * @hide
    272      */
    273     public static final String EXTRA_CATEGORY_FILTER = "categoryFilter";
    274 
    275     /**
    276      * An intent extra to pass to the AppWidget picker to specify whether or not to sort
    277      * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets
    278      * @hide
    279      */
    280     public static final String EXTRA_CUSTOM_SORT = "customSort";
    281 
    282     /**
    283      * A sentinel value that the AppWidget manager will never return as a appWidgetId.
    284      */
    285     public static final int INVALID_APPWIDGET_ID = 0;
    286 
    287     /**
    288      * Sent when it is time to update your AppWidget.
    289      *
    290      * <p>This may be sent in response to a new instance for this AppWidget provider having
    291      * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval}
    292      * having lapsed, or the system booting.
    293      *
    294      * <p>
    295      * The intent will contain the following extras:
    296      * <table>
    297      *   <tr>
    298      *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
    299      *     <td>The appWidgetIds to update.  This may be all of the AppWidgets created for this
    300      *     provider, or just a subset.  The system tries to send updates for as few AppWidget
    301      *     instances as possible.</td>
    302      *  </tr>
    303      * </table>
    304      *
    305      * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
    306      */
    307     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    308     @BroadcastBehavior(explicitOnly = true)
    309     public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
    310 
    311     /**
    312      * Sent when the custom extras for an AppWidget change.
    313      *
    314      * <p class="note">This is a protected intent that can only be sent
    315      * by the system.
    316      *
    317      * @see AppWidgetProvider#onAppWidgetOptionsChanged
    318      *      AppWidgetProvider.onAppWidgetOptionsChanged(Context context,
    319      *      AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
    320      */
    321     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    322     @BroadcastBehavior(explicitOnly = true)
    323     public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
    324 
    325     /**
    326      * Sent when an instance of an AppWidget is deleted from its host.
    327      *
    328      * <p class="note">This is a protected intent that can only be sent
    329      * by the system.
    330      *
    331      * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
    332      */
    333     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    334     @BroadcastBehavior(explicitOnly = true)
    335     public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
    336 
    337     /**
    338      * Sent when the last AppWidget of this provider is removed from the last host.
    339      *
    340      * <p class="note">This is a protected intent that can only be sent
    341      * by the system.
    342      *
    343      * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context)
    344      */
    345     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    346     @BroadcastBehavior(explicitOnly = true)
    347     public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
    348 
    349     /**
    350      * Sent when an instance of an AppWidget is added to a host for the first time.
    351      * This broadcast is sent at boot time if there is a AppWidgetHost installed with
    352      * an instance for this provider.
    353      *
    354      * <p class="note">This is a protected intent that can only be sent
    355      * by the system.
    356      *
    357      * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
    358      */
    359     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    360     @BroadcastBehavior(explicitOnly = true)
    361     public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
    362 
    363     /**
    364      * Sent to an {@link AppWidgetProvider} after AppWidget state related to that provider has
    365      * been restored from backup. The intent contains information about how to translate AppWidget
    366      * ids from the restored data to their new equivalents.
    367      *
    368      * <p>The intent will contain the following extras:
    369      *
    370      * <table>
    371      *   <tr>
    372      *     <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
    373      *     <td>The set of appWidgetIds represented in a restored backup that have been successfully
    374      *     incorporated into the current environment.  This may be all of the AppWidgets known
    375      *     to this application, or just a subset.  Each entry in this array of appWidgetIds has
    376      *     a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
    377      *  </tr>
    378      *   <tr>
    379      *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
    380      *     <td>The set of appWidgetIds now valid for this application.  The app should look at
    381      *     its restored widget configuration and translate each appWidgetId in the
    382      *     {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
    383      *     index within this array.</td>
    384      *  </tr>
    385      * </table>
    386      *
    387      * <p class="note">This is a protected intent that can only be sent
    388      * by the system.
    389      *
    390      * @see #ACTION_APPWIDGET_HOST_RESTORED
    391      */
    392     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    393     @BroadcastBehavior(explicitOnly = true)
    394     public static final String ACTION_APPWIDGET_RESTORED
    395             = "android.appwidget.action.APPWIDGET_RESTORED";
    396 
    397     /**
    398      * Sent to widget hosts after AppWidget state related to the host has been restored from
    399      * backup. The intent contains information about how to translate AppWidget ids from the
    400      * restored data to their new equivalents.  If an application maintains multiple separate
    401      * widget host instances, it will receive this broadcast separately for each one.
    402      *
    403      * <p>The intent will contain the following extras:
    404      *
    405      * <table>
    406      *   <tr>
    407      *     <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
    408      *     <td>The set of appWidgetIds represented in a restored backup that have been successfully
    409      *     incorporated into the current environment.  This may be all of the AppWidgets known
    410      *     to this application, or just a subset.  Each entry in this array of appWidgetIds has
    411      *     a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
    412      *  </tr>
    413      *   <tr>
    414      *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
    415      *     <td>The set of appWidgetIds now valid for this application.  The app should look at
    416      *     its restored widget configuration and translate each appWidgetId in the
    417      *     {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
    418      *     index within this array.</td>
    419      *  </tr>
    420      *  <tr>
    421      *     <td>{@link #EXTRA_HOST_ID}</td>
    422      *     <td>The integer ID of the widget host instance whose state has just been restored.</td>
    423      *  </tr>
    424      * </table>
    425      *
    426      * <p class="note">This is a protected intent that can only be sent
    427      * by the system.
    428      *
    429      * @see #ACTION_APPWIDGET_RESTORED
    430      */
    431     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    432     @BroadcastBehavior(explicitOnly = true)
    433     public static final String ACTION_APPWIDGET_HOST_RESTORED
    434             = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
    435 
    436     /**
    437      * An intent extra that contains multiple appWidgetIds.  These are id values as
    438      * they were provided to the application during a recent restore from backup.  It is
    439      * attached to the {@link #ACTION_APPWIDGET_RESTORED} broadcast intent.
    440      *
    441      * <p>
    442      * The value will be an int array that can be retrieved like this:
    443      * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
    444      */
    445     public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
    446 
    447     /**
    448      * An extra that can be passed to
    449      * {@link #requestPinAppWidget(ComponentName, Bundle, PendingIntent)}. This would allow the
    450      * launcher app to present a custom preview to the user.
    451      *
    452      * <p>
    453      * The value should be a {@link RemoteViews} similar to what is used with
    454      * {@link #updateAppWidget} calls.
    455      */
    456     public static final String EXTRA_APPWIDGET_PREVIEW = "appWidgetPreview";
    457 
    458     /**
    459      * Field for the manifest meta-data tag.
    460      *
    461      * @see AppWidgetProviderInfo
    462      */
    463     public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
    464 
    465     private final Context mContext;
    466     private final String mPackageName;
    467     @UnsupportedAppUsage
    468     private final IAppWidgetService mService;
    469     private final DisplayMetrics mDisplayMetrics;
    470 
    471     /**
    472      * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
    473      * Context} object.
    474      */
    475     public static AppWidgetManager getInstance(Context context) {
    476         return (AppWidgetManager) context.getSystemService(Context.APPWIDGET_SERVICE);
    477     }
    478 
    479     /**
    480      * Creates a new instance.
    481      *
    482      * @param context The current context in which to operate.
    483      * @param service The backing system service.
    484      * @hide
    485      */
    486     public AppWidgetManager(Context context, IAppWidgetService service) {
    487         mContext = context;
    488         mPackageName = context.getOpPackageName();
    489         mService = service;
    490         mDisplayMetrics = context.getResources().getDisplayMetrics();
    491     }
    492 
    493     /**
    494      * Set the RemoteViews to use for the specified appWidgetIds.
    495      * <p>
    496      * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
    497      * contain a complete representation of the widget. For performing partial widget updates, see
    498      * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}.
    499      *
    500      * <p>
    501      * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
    502      * and outside of the handler.
    503      * This method will only work when called from the uid that owns the AppWidget provider.
    504      *
    505      * <p>
    506      * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
    507      * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
    508      *
    509      * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
    510      * @param views The RemoteViews object to show.
    511      */
    512     public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
    513         if (mService == null) {
    514             return;
    515         }
    516         try {
    517             mService.updateAppWidgetIds(mPackageName, appWidgetIds, views);
    518         } catch (RemoteException e) {
    519             throw e.rethrowFromSystemServer();
    520         }
    521     }
    522 
    523     /**
    524      * Update the extras for a given widget instance.
    525      * <p>
    526      * The extras can be used to embed additional information about this widget to be accessed
    527      * by the associated widget's AppWidgetProvider.
    528      *
    529      * @see #getAppWidgetOptions(int)
    530      *
    531      * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
    532      * @param options The options to associate with this widget
    533      */
    534     public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
    535         if (mService == null) {
    536             return;
    537         }
    538         try {
    539             mService.updateAppWidgetOptions(mPackageName, appWidgetId, options);
    540         } catch (RemoteException e) {
    541             throw e.rethrowFromSystemServer();
    542         }
    543     }
    544 
    545     /**
    546      * Get the extras associated with a given widget instance.
    547      * <p>
    548      * The extras can be used to embed additional information about this widget to be accessed
    549      * by the associated widget's AppWidgetProvider.
    550      *
    551      * @see #updateAppWidgetOptions(int, Bundle)
    552      *
    553      * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
    554      * @return The options associated with the given widget instance.
    555      */
    556     public Bundle getAppWidgetOptions(int appWidgetId) {
    557         if (mService == null) {
    558             return Bundle.EMPTY;
    559         }
    560         try {
    561             return mService.getAppWidgetOptions(mPackageName, appWidgetId);
    562         } catch (RemoteException e) {
    563             throw e.rethrowFromSystemServer();
    564         }
    565     }
    566 
    567     /**
    568      * Set the RemoteViews to use for the specified appWidgetId.
    569      * <p>
    570      * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
    571      * contain a complete representation of the widget. For performing partial widget updates, see
    572      * {@link #partiallyUpdateAppWidget(int, RemoteViews)}.
    573      *
    574      * <p>
    575      * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
    576      * and outside of the handler.
    577      * This method will only work when called from the uid that owns the AppWidget provider.
    578      *
    579      * <p>
    580      * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
    581      * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
    582      *
    583      * @param appWidgetId      The AppWidget instance for which to set the RemoteViews.
    584      * @param views         The RemoteViews object to show.
    585      */
    586     public void updateAppWidget(int appWidgetId, RemoteViews views) {
    587         if (mService == null) {
    588             return;
    589         }
    590         updateAppWidget(new int[] { appWidgetId }, views);
    591     }
    592 
    593     /**
    594      * Perform an incremental update or command on the widget(s) specified by appWidgetIds.
    595      * <p>
    596      * This update  differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
    597      * RemoteViews object which is passed is understood to be an incomplete representation of the
    598      * widget, and hence does not replace the cached representation of the widget. As of API
    599      * level 17, the new properties set within the views objects will be appended to the cached
    600      * representation of the widget, and hence will persist.
    601      *
    602      * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
    603      * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
    604      *
    605      * <p>
    606      * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
    607      * and outside of the handler.
    608      * This method will only work when called from the uid that owns the AppWidget provider.
    609      *
    610      * <p>
    611      * This method will be ignored if a widget has not received a full update via
    612      * {@link #updateAppWidget(int[], RemoteViews)}.
    613      *
    614      * @param appWidgetIds     The AppWidget instances for which to set the RemoteViews.
    615      * @param views            The RemoteViews object containing the incremental update / command.
    616      */
    617     public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) {
    618         if (mService == null) {
    619             return;
    620         }
    621         try {
    622             mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views);
    623         } catch (RemoteException e) {
    624             throw e.rethrowFromSystemServer();
    625         }
    626     }
    627 
    628     /**
    629      * Perform an incremental update or command on the widget specified by appWidgetId.
    630      * <p>
    631      * This update  differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews
    632      * object which is passed is understood to be an incomplete representation of the widget, and
    633      * hence is not cached by the AppWidgetService. Note that because these updates are not cached,
    634      * any state that they modify that is not restored by restoreInstanceState will not persist in
    635      * the case that the widgets are restored using the cached version in AppWidgetService.
    636      *
    637      * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
    638      * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
    639      *
    640      * <p>
    641      * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
    642      * and outside of the handler.
    643      * This method will only work when called from the uid that owns the AppWidget provider.
    644      *
    645      * <p>
    646      * This method will be ignored if a widget has not received a full update via
    647      * {@link #updateAppWidget(int[], RemoteViews)}.
    648      *
    649      * @param appWidgetId      The AppWidget instance for which to set the RemoteViews.
    650      * @param views            The RemoteViews object containing the incremental update / command.
    651      */
    652     public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) {
    653         if (mService == null) {
    654             return;
    655         }
    656         partiallyUpdateAppWidget(new int[] { appWidgetId }, views);
    657     }
    658 
    659     /**
    660      * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider.
    661      *
    662      * <p>
    663      * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
    664      * and outside of the handler.
    665      * This method will only work when called from the uid that owns the AppWidget provider.
    666      *
    667      * @param provider      The {@link ComponentName} for the {@link
    668      * android.content.BroadcastReceiver BroadcastReceiver} provider
    669      *                      for your AppWidget.
    670      * @param views         The RemoteViews object to show.
    671      */
    672     public void updateAppWidget(ComponentName provider, RemoteViews views) {
    673         if (mService == null) {
    674             return;
    675         }
    676         try {
    677             mService.updateAppWidgetProvider(provider, views);
    678         } catch (RemoteException e) {
    679             throw e.rethrowFromSystemServer();
    680         }
    681     }
    682 
    683     /**
    684      * Updates the info for the supplied AppWidget provider. Apps can use this to change the default
    685      * behavior of the widget based on the state of the app (for e.g., if the user is logged in
    686      * or not). Calling this API completely replaces the previous definition.
    687      *
    688      * <p>
    689      * The manifest entry of the provider should contain an additional meta-data tag similar to
    690      * {@link #META_DATA_APPWIDGET_PROVIDER} which should point to any alternative definitions for
    691      * the provider.
    692      *
    693      * <p>
    694      * This is persisted across device reboots and app updates. If this meta-data key is not
    695      * present in the manifest entry, the info reverts to default.
    696      *
    697      * @param provider {@link ComponentName} for the {@link
    698      *    android.content.BroadcastReceiver BroadcastReceiver} provider for your AppWidget.
    699      * @param metaDataKey key for the meta-data tag pointing to the new provider info. Use null
    700      *    to reset any previously set info.
    701      */
    702     public void updateAppWidgetProviderInfo(ComponentName provider, @Nullable String metaDataKey) {
    703         if (mService == null) {
    704             return;
    705         }
    706         try {
    707             mService.updateAppWidgetProviderInfo(provider, metaDataKey);
    708         } catch (RemoteException e) {
    709             throw e.rethrowFromSystemServer();
    710         }
    711     }
    712 
    713     /**
    714      * Notifies the specified collection view in all the specified AppWidget instances
    715      * to invalidate their data.
    716      *
    717      * @param appWidgetIds  The AppWidget instances to notify of view data changes.
    718      * @param viewId        The collection view id.
    719      */
    720     public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
    721         if (mService == null) {
    722             return;
    723         }
    724         try {
    725             mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId);
    726         } catch (RemoteException e) {
    727             throw e.rethrowFromSystemServer();
    728         }
    729     }
    730 
    731     /**
    732      * Notifies the specified collection view in the specified AppWidget instance
    733      * to invalidate its data.
    734      *
    735      * @param appWidgetId  The AppWidget instance to notify of view data changes.
    736      * @param viewId       The collection view id.
    737      */
    738     public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
    739         if (mService == null) {
    740             return;
    741         }
    742         notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
    743     }
    744 
    745     /**
    746      * Gets the AppWidget providers for the given user profile. User profile can only
    747      * be the current user or a profile of the current user. For example, the current
    748      * user may have a corporate profile. In this case the parent user profile has a
    749      * child profile, the corporate one.
    750      *
    751      * @param profile The profile for which to get providers. Passing null is equivalent
    752      *        to querying for only the calling user.
    753      * @return The installed providers, or an empty list if none are found for the given user.
    754      *
    755      * @see android.os.Process#myUserHandle()
    756      * @see android.os.UserManager#getUserProfiles()
    757      */
    758     public @NonNull List<AppWidgetProviderInfo> getInstalledProvidersForProfile(
    759             @Nullable UserHandle profile) {
    760         if (mService == null) {
    761             return Collections.emptyList();
    762         }
    763         return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    764                 profile, null);
    765     }
    766 
    767     /**
    768      * Gets the AppWidget providers for the given package and user profile. User
    769      * profile can only be the current user or a profile of the current user. For
    770      * example, the current user may have a corporate profile. In this case the
    771      * parent user profile has a child profile, the corporate one.
    772      *
    773      * @param packageName The package for which to get providers. If null, this method is
    774      *        equivalent to {@link #getInstalledProvidersForProfile(UserHandle)}.
    775      * @param profile The profile for which to get providers. Passing null is equivalent
    776      *        to querying for only the calling user.
    777      * @return The installed providers, or an empty list if none are found for the given
    778      *         package and user.
    779      * @throws NullPointerException if the provided package name is null
    780      *
    781      * @see android.os.Process#myUserHandle()
    782      * @see android.os.UserManager#getUserProfiles()
    783      */
    784     public @NonNull List<AppWidgetProviderInfo> getInstalledProvidersForPackage(
    785             @NonNull String packageName, @Nullable UserHandle profile) {
    786         if (packageName == null) {
    787             throw new NullPointerException("A non-null package must be passed to this method. " +
    788                     "If you want all widgets regardless of package, see " +
    789                     "getInstalledProvidersForProfile(UserHandle)");
    790         }
    791         if (mService == null) {
    792             return Collections.emptyList();
    793         }
    794         return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    795                 profile, packageName);
    796     }
    797 
    798     /**
    799      * Return a list of the AppWidget providers that are currently installed.
    800      */
    801     public List<AppWidgetProviderInfo> getInstalledProviders() {
    802         if (mService == null) {
    803             return Collections.emptyList();
    804         }
    805         return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    806                 null, null);
    807     }
    808 
    809     /**
    810      * Gets the AppWidget providers for the current user.
    811      *
    812      * @param categoryFilter Will only return providers which register as any of the specified
    813      *        specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
    814      * @return The intalled providers.
    815      *
    816      * @see android.os.Process#myUserHandle()
    817      * @see android.os.UserManager#getUserProfiles()
    818      *
    819      * @hide
    820      */
    821     @UnsupportedAppUsage
    822     public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
    823         if (mService == null) {
    824             return Collections.emptyList();
    825         }
    826         return getInstalledProvidersForProfile(categoryFilter, null, null);
    827     }
    828 
    829     /**
    830      * Gets the AppWidget providers for the given user profile. User profile can only
    831      * be the current user or a profile of the current user. For example, the current
    832      * user may have a corporate profile. In this case the parent user profile has a
    833      * child profile, the corporate one.
    834      *
    835      * @param categoryFilter Will only return providers which register as any of the specified
    836      *        specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
    837      * @param profile A profile of the current user which to be queried. The user
    838      *        is itself also a profile. If null, the providers only for the current user
    839      *        are returned.
    840      * @param packageName If specified, will only return providers from the given package.
    841      * @return The intalled providers.
    842      *
    843      * @see android.os.Process#myUserHandle()
    844      * @see android.os.UserManager#getUserProfiles()
    845      *
    846      * @hide
    847      */
    848     @UnsupportedAppUsage
    849     public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
    850             @Nullable UserHandle profile, @Nullable String packageName) {
    851         if (mService == null) {
    852             return Collections.emptyList();
    853         }
    854 
    855         if (profile == null) {
    856             profile = mContext.getUser();
    857         }
    858 
    859         try {
    860             ParceledListSlice<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile(
    861                     categoryFilter, profile.getIdentifier(), packageName);
    862             if (providers == null) {
    863                 return Collections.emptyList();
    864             }
    865             for (AppWidgetProviderInfo info : providers.getList()) {
    866                 // Converting complex to dp.
    867                 info.updateDimensions(mDisplayMetrics);
    868             }
    869             return providers.getList();
    870         } catch (RemoteException e) {
    871             throw e.rethrowFromSystemServer();
    872         }
    873     }
    874 
    875     /**
    876      * Get the available info about the AppWidget.
    877      *
    878      * @return A appWidgetId.  If the appWidgetId has not been bound to a provider yet, or
    879      * you don't have access to that appWidgetId, null is returned.
    880      */
    881     public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
    882         if (mService == null) {
    883             return null;
    884         }
    885         try {
    886             AppWidgetProviderInfo info = mService.getAppWidgetInfo(mPackageName, appWidgetId);
    887             if (info != null) {
    888                 // Converting complex to dp.
    889                 info.updateDimensions(mDisplayMetrics);
    890             }
    891             return info;
    892         } catch (RemoteException e) {
    893             throw e.rethrowFromSystemServer();
    894         }
    895     }
    896 
    897     /**
    898      * Set the component for a given appWidgetId.
    899      *
    900      * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
    901      *         widgets always for your component. This method is used by the AppWidget picker and
    902      *         should not be used by other apps.
    903      *
    904      * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
    905      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
    906      *                      provider for this AppWidget.
    907      * @hide
    908      */
    909     @UnsupportedAppUsage
    910     public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
    911         if (mService == null) {
    912             return;
    913         }
    914         bindAppWidgetId(appWidgetId, provider, null);
    915     }
    916 
    917     /**
    918      * Set the component for a given appWidgetId.
    919      *
    920      * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
    921      *         widgets always for your component. This method is used by the AppWidget picker and
    922      *         should not be used by other apps.
    923      *
    924      * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
    925      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
    926      *                      provider for this AppWidget.
    927      * @param options       Bundle containing options for the AppWidget. See also
    928      *                      {@link #updateAppWidgetOptions(int, Bundle)}
    929      *
    930      * @hide
    931      */
    932     @UnsupportedAppUsage
    933     public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
    934         if (mService == null) {
    935             return;
    936         }
    937         bindAppWidgetIdIfAllowed(appWidgetId, mContext.getUser(), provider, options);
    938     }
    939 
    940     /**
    941      * Set the component for a given appWidgetId.
    942      *
    943      * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
    944      *         widgets always for your component. Should be used by apps that host widgets; if this
    945      *         method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
    946      *         bind
    947      *
    948      * @param appWidgetId   The AppWidget id under which to bind the provider.
    949      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
    950      *                      provider for this AppWidget.
    951      * @return true if this component has permission to bind the AppWidget
    952      */
    953     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
    954         if (mService == null) {
    955             return false;
    956         }
    957         return bindAppWidgetIdIfAllowed(appWidgetId, mContext.getUserId(), provider, null);
    958     }
    959 
    960     /**
    961      * Set the component for a given appWidgetId.
    962      *
    963      * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
    964      *         widgets always for your component. Should be used by apps that host widgets; if this
    965      *         method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
    966      *         bind
    967      *
    968      * @param appWidgetId The AppWidget id under which to bind the provider.
    969      * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
    970      *                      provider for this AppWidget.
    971      * @param options       Bundle containing options for the AppWidget. See also
    972      *                      {@link #updateAppWidgetOptions(int, Bundle)}
    973      *
    974      * @return true if this component has permission to bind the AppWidget
    975      */
    976     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
    977             Bundle options) {
    978         if (mService == null) {
    979             return false;
    980         }
    981         return bindAppWidgetIdIfAllowed(appWidgetId, mContext.getUserId(), provider, options);
    982     }
    983 
    984     /**
    985      * Set the provider for a given appWidgetId if the caller has a permission.
    986      * <p>
    987      * <strong>Note:</strong> You need the {@link android.Manifest.permission#BIND_APPWIDGET}
    988      * permission or the user must have enabled binding widgets always for your component.
    989      * Should be used by apps that host widgets. If this method returns false, call {@link
    990      * #ACTION_APPWIDGET_BIND} to request permission to bind.
    991      * </p>
    992      *
    993      * @param appWidgetId The AppWidget id under which to bind the provider.
    994      * @param user The user id in which the provider resides.
    995      * @param provider The component name of the provider.
    996      * @param options An optional Bundle containing options for the AppWidget.
    997      *
    998      * @return true if this component has permission to bind the AppWidget
    999      */
   1000     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, UserHandle user,
   1001             ComponentName provider, Bundle options) {
   1002         if (mService == null) {
   1003             return false;
   1004         }
   1005         return bindAppWidgetIdIfAllowed(appWidgetId, user.getIdentifier(), provider, options);
   1006     }
   1007 
   1008     /**
   1009      * Query if a given package was granted permission by the user to bind app widgets
   1010      *
   1011      * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
   1012      *
   1013      * @param packageName The package for which the permission is being queried
   1014      * @param userId The user id of the user under which the package runs.
   1015      * @return true if the package was granted permission by the user to bind app widgets
   1016      * @hide
   1017      */
   1018     public boolean hasBindAppWidgetPermission(String packageName, int userId) {
   1019         if (mService == null) {
   1020             return false;
   1021         }
   1022         try {
   1023             return mService.hasBindAppWidgetPermission(packageName, userId);
   1024         } catch (RemoteException e) {
   1025             throw e.rethrowFromSystemServer();
   1026         }
   1027     }
   1028 
   1029     /**
   1030      * Query if a given package was granted permission by the user to bind app widgets
   1031      *
   1032      * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
   1033      *
   1034      * @param packageName        The package for which the permission is being queried
   1035      * @return true if the package was granted permission by the user to bind app widgets
   1036      * @hide
   1037      */
   1038     public boolean hasBindAppWidgetPermission(String packageName) {
   1039         if (mService == null) {
   1040             return false;
   1041         }
   1042         try {
   1043             return mService.hasBindAppWidgetPermission(packageName, mContext.getUserId());
   1044         } catch (RemoteException e) {
   1045             throw e.rethrowFromSystemServer();
   1046         }
   1047     }
   1048 
   1049     /**
   1050      * Changes any user-granted permission for the given package to bind app widgets
   1051      *
   1052      * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
   1053      *
   1054      * @param packageName The package whose permission is being changed
   1055      * @param permission Whether to give the package permission to bind widgets
   1056      *
   1057      * @hide
   1058      */
   1059     public void setBindAppWidgetPermission(String packageName, boolean permission) {
   1060         if (mService == null) {
   1061             return;
   1062         }
   1063         setBindAppWidgetPermission(packageName, mContext.getUserId(), permission);
   1064     }
   1065 
   1066     /**
   1067      * Changes any user-granted permission for the given package to bind app widgets
   1068      *
   1069      * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
   1070      *
   1071      * @param packageName The package whose permission is being changed
   1072      * @param userId The user under which the package is running.
   1073      * @param permission Whether to give the package permission to bind widgets
   1074      *
   1075      * @hide
   1076      */
   1077     public void setBindAppWidgetPermission(String packageName, int userId, boolean permission) {
   1078         if (mService == null) {
   1079             return;
   1080         }
   1081         try {
   1082             mService.setBindAppWidgetPermission(packageName, userId, permission);
   1083         } catch (RemoteException e) {
   1084             throw e.rethrowFromSystemServer();
   1085         }
   1086     }
   1087 
   1088     /**
   1089      * Binds the RemoteViewsService for a given appWidgetId and intent.
   1090      *
   1091      * The appWidgetId specified must already be bound to the calling AppWidgetHost via
   1092      * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
   1093      *
   1094      * @param appWidgetId   The AppWidget instance for which to bind the RemoteViewsService.
   1095      * @param intent        The intent of the service which will be providing the data to the
   1096      *                      RemoteViewsAdapter.
   1097      * @param connection    The callback interface to be notified when a connection is made or lost.
   1098      * @param flags         Flags used for binding to the service
   1099      *
   1100      * @see Context#getServiceDispatcher(ServiceConnection, Handler, int)
   1101      * @hide
   1102      */
   1103     @UnsupportedAppUsage
   1104     public boolean bindRemoteViewsService(Context context, int appWidgetId, Intent intent,
   1105             IServiceConnection connection, @Context.BindServiceFlags int flags) {
   1106         if (mService == null) {
   1107             return false;
   1108         }
   1109         try {
   1110             return mService.bindRemoteViewsService(context.getOpPackageName(), appWidgetId, intent,
   1111                     context.getIApplicationThread(), context.getActivityToken(), connection, flags);
   1112         } catch (RemoteException e) {
   1113             throw e.rethrowFromSystemServer();
   1114         }
   1115     }
   1116 
   1117     /**
   1118      * Get the list of appWidgetIds that have been bound to the given AppWidget
   1119      * provider.
   1120      *
   1121      * @param provider The {@link android.content.BroadcastReceiver} that is the
   1122      *            AppWidget provider to find appWidgetIds for.
   1123      */
   1124     public int[] getAppWidgetIds(ComponentName provider) {
   1125         if (mService == null) {
   1126             return new int[0];
   1127         }
   1128         try {
   1129             return mService.getAppWidgetIds(provider);
   1130         } catch (RemoteException e) {
   1131             throw e.rethrowFromSystemServer();
   1132         }
   1133     }
   1134 
   1135     /**
   1136      * @hide
   1137      */
   1138     public boolean isBoundWidgetPackage(String packageName, int userId) {
   1139         if (mService == null) {
   1140             return false;
   1141         }
   1142         try {
   1143             return mService.isBoundWidgetPackage(packageName, userId);
   1144         } catch (RemoteException e) {
   1145             throw e.rethrowFromSystemServer();
   1146         }
   1147     }
   1148 
   1149     @UnsupportedAppUsage
   1150     private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId,
   1151             ComponentName provider, Bundle options) {
   1152         if (mService == null) {
   1153             return false;
   1154         }
   1155         try {
   1156             return mService.bindAppWidgetId(mPackageName, appWidgetId,
   1157                     profileId, provider, options);
   1158         } catch (RemoteException e) {
   1159             throw e.rethrowFromSystemServer();
   1160         }
   1161     }
   1162 
   1163     /**
   1164      * Return {@code TRUE} if the default launcher supports
   1165      * {@link #requestPinAppWidget(ComponentName, Bundle, PendingIntent)}
   1166      */
   1167     public boolean isRequestPinAppWidgetSupported() {
   1168         try {
   1169             return mService.isRequestPinAppWidgetSupported();
   1170         } catch (RemoteException e) {
   1171             throw e.rethrowFromSystemServer();
   1172         }
   1173     }
   1174 
   1175     /**
   1176      * Only used during development. Can be deleted before release.
   1177      * @hide
   1178      */
   1179     public boolean requestPinAppWidget(@NonNull ComponentName provider,
   1180             @Nullable PendingIntent successCallback) {
   1181         return requestPinAppWidget(provider, null, successCallback);
   1182     }
   1183 
   1184     /**
   1185      * Request to pin an app widget on the current launcher. It's up to the launcher to accept this
   1186      * request (optionally showing a user confirmation). If the request is accepted, the caller will
   1187      * get a confirmation with extra {@link #EXTRA_APPWIDGET_ID}.
   1188      *
   1189      * <p>When a request is denied by the user, the caller app will not get any response.
   1190      *
   1191      * <p>Only apps with a foreground activity or a foreground service can call it.  Otherwise
   1192      * it'll throw {@link IllegalStateException}.
   1193      *
   1194      * <p>It's up to the launcher how to handle previous pending requests when the same package
   1195      * calls this API multiple times in a row.  It may ignore the previous requests,
   1196      * for example.
   1197      *
   1198      * <p>Launcher will not show the configuration activity associated with the provider in this
   1199      * case. The app could either show the configuration activity as a response to the callback,
   1200      * or show if before calling the API (various configurations can be encapsulated in
   1201      * {@code successCallback} to avoid persisting them before the widgetId is known).
   1202      *
   1203      * @param provider The {@link ComponentName} for the {@link
   1204      *    android.content.BroadcastReceiver BroadcastReceiver} provider for your AppWidget.
   1205      * @param extras In not null, this is passed to the launcher app. For eg {@link
   1206      *    #EXTRA_APPWIDGET_PREVIEW} can be used for a custom preview.
   1207      * @param successCallback If not null, this intent will be sent when the widget is created.
   1208      *
   1209      * @return {@code TRUE} if the launcher supports this feature. Note the API will return without
   1210      *    waiting for the user to respond, so getting {@code TRUE} from this API does *not* mean
   1211      *    the shortcut is pinned. {@code FALSE} if the launcher doesn't support this feature.
   1212      *
   1213      * @see android.content.pm.ShortcutManager#isRequestPinShortcutSupported()
   1214      * @see android.content.pm.ShortcutManager#requestPinShortcut(ShortcutInfo, IntentSender)
   1215      * @see #isRequestPinAppWidgetSupported()
   1216      *
   1217      * @throws IllegalStateException The caller doesn't have a foreground activity or a foreground
   1218      * service or when the user is locked.
   1219      */
   1220     public boolean requestPinAppWidget(@NonNull ComponentName provider,
   1221             @Nullable Bundle extras, @Nullable PendingIntent successCallback) {
   1222         try {
   1223             return mService.requestPinAppWidget(mPackageName, provider, extras,
   1224                     successCallback == null ? null : successCallback.getIntentSender());
   1225         } catch (RemoteException e) {
   1226             throw e.rethrowFromSystemServer();
   1227         }
   1228     }
   1229 }
   1230