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      */
getInstance(Context context)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      */
AppWidgetManager(Context context, IAppWidgetService service)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      */
updateAppWidget(int[] appWidgetIds, RemoteViews views)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      */
updateAppWidgetOptions(int appWidgetId, Bundle options)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      */
getAppWidgetOptions(int appWidgetId)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      */
updateAppWidget(int appWidgetId, RemoteViews views)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      */
partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views)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      */
partiallyUpdateAppWidget(int appWidgetId, RemoteViews views)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      */
updateAppWidget(ComponentName provider, RemoteViews views)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      */
notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId)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      */
notifyAppWidgetViewDataChanged(int appWidgetId, int viewId)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      */
getInstalledProvidersForProfile( @ullable UserHandle profile)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      */
getInstalledProvidersForPackage( @onNull String packageName, @Nullable UserHandle profile)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      */
getInstalledProviders()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      */
getInstalledProviders(int categoryFilter)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      */
getInstalledProvidersForProfile(int categoryFilter, @Nullable UserHandle profile, @Nullable String packageName)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      */
getAppWidgetInfo(int appWidgetId)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      */
bindAppWidgetId(int appWidgetId, ComponentName provider)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      */
bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options)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      */
bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider)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      */
bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider, Bundle options)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      */
bindAppWidgetIdIfAllowed(int appWidgetId, UserHandle user, ComponentName provider, Bundle options)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      */
hasBindAppWidgetPermission(String packageName, int userId)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      */
hasBindAppWidgetPermission(String packageName)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      */
setBindAppWidgetPermission(String packageName, boolean permission)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      */
setBindAppWidgetPermission(String packageName, int userId, boolean permission)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      */
bindRemoteViewsService(String packageName, int appWidgetId, Intent intent, IBinder connection)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      */
unbindRemoteViewsService(String packageName, int appWidgetId, Intent intent)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      */
getAppWidgetIds(ComponentName provider)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      */
isBoundWidgetPackage(String packageName, int userId)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 
bindAppWidgetIdIfAllowed(int appWidgetId, int profileId, ComponentName provider, Bundle options)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      */
isRequestPinAppWidgetSupported()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      */
requestPinAppWidget(@onNull ComponentName provider, @Nullable PendingIntent successCallback)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      */
requestPinAppWidget(@onNull ComponentName provider, @Nullable Bundle extras, @Nullable PendingIntent successCallback)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