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