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