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