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