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
17package android.appwidget;
18
19import android.annotation.BroadcastBehavior;
20import android.annotation.NonNull;
21import android.annotation.Nullable;
22import android.annotation.RequiresFeature;
23import android.annotation.SdkConstant;
24import android.annotation.SdkConstant.SdkConstantType;
25import android.annotation.SystemService;
26import android.app.IServiceConnection;
27import android.app.PendingIntent;
28import android.content.ComponentName;
29import android.content.Context;
30import android.content.Intent;
31import android.content.IntentSender;
32import android.content.ServiceConnection;
33import android.content.pm.PackageManager;
34import android.content.pm.ParceledListSlice;
35import android.content.pm.ShortcutInfo;
36import android.os.Bundle;
37import android.os.Handler;
38import android.os.RemoteException;
39import android.os.UserHandle;
40import android.util.DisplayMetrics;
41import android.widget.RemoteViews;
42
43import com.android.internal.appwidget.IAppWidgetService;
44
45import java.util.Collections;
46import 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)
60public 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