blob: 278c9d6f869992e153f3f670d262f0f484820ee0 [file] [log] [blame]
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.appwidget;
18
Svetoslav8e1d2992014-08-08 12:48:06 -070019import android.annotation.Nullable;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070020import android.content.ComponentName;
21import android.content.Context;
Winson Chung81f39eb2011-01-11 18:05:01 -080022import android.content.Intent;
Hyunyoung Songccf6c682015-06-17 15:23:31 -070023import android.content.pm.ParceledListSlice;
Adam Cohene8724c82012-04-19 17:11:40 -070024import android.os.Bundle;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070025import android.os.IBinder;
Svetoslav976e8bd2014-07-16 15:12:03 -070026import android.os.Process;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070027import android.os.RemoteException;
Amith Yamasanic566b432012-11-30 15:26:21 -080028import android.os.UserHandle;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -070029import android.util.DisplayMetrics;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -070030import android.util.TypedValue;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070031import android.widget.RemoteViews;
32
33import com.android.internal.appwidget.IAppWidgetService;
34
Svetoslav976e8bd2014-07-16 15:12:03 -070035import java.util.Collections;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070036import java.util.List;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070037
38/**
39 * Updates AppWidget state; gets information about installed AppWidget providers and other
40 * AppWidget related state.
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080041 *
42 * <div class="special reference">
43 * <h3>Developer Guides</h3>
44 * <p>For more information about creating app widgets, read the
45 * <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a> developer guide.</p>
46 * </div>
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070047 */
48public class AppWidgetManager {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070049
50 /**
Dianne Hackborna40cfeb2013-03-25 17:49:36 -070051 * Activity action to launch from your {@link AppWidgetHost} activity when you want to
52 * pick an AppWidget to display. The AppWidget picker activity will be launched.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070053 * <p>
54 * You must supply the following extras:
55 * <table>
56 * <tr>
57 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
58 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
59 * once the user has selected one.</td>
60 * </tr>
61 * </table>
62 *
63 * <p>
64 * The system will respond with an onActivityResult call with the following extras in
65 * the intent:
66 * <table>
67 * <tr>
68 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
69 * <td>The appWidgetId that you supplied in the original intent.</td>
70 * </tr>
71 * </table>
72 * <p>
73 * When you receive the result from the AppWidget pick activity, if the resultCode is
74 * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected. You should then
Svetoslav976e8bd2014-07-16 15:12:03 -070075 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
76 * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you
77 * should delete the appWidgetId.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070078 *
79 * @see #ACTION_APPWIDGET_CONFIGURE
80 */
81 public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
82
83 /**
Michael Jurkafc753c02012-10-30 18:30:52 -070084 * Similar to ACTION_APPWIDGET_PICK, but used from keyguard
85 * @hide
86 */
87 public static final String
88 ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK";
89
90 /**
Dianne Hackborna40cfeb2013-03-25 17:49:36 -070091 * Activity action to launch from your {@link AppWidgetHost} activity when you want to bind
92 * an AppWidget to display and bindAppWidgetIdIfAllowed returns false.
Michael Jurka61a5b012012-04-13 10:39:45 -070093 * <p>
94 * You must supply the following extras:
95 * <table>
96 * <tr>
97 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
98 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
99 * you provide.</td>
100 * </tr>
101 * <tr>
102 * <td>{@link #EXTRA_APPWIDGET_PROVIDER}</td>
103 * <td>The BroadcastReceiver that will be the AppWidget provider for this AppWidget.
104 * </td>
105 * </tr>
Svetoslav976e8bd2014-07-16 15:12:03 -0700106 * <tr>
107 * <td>{@link #EXTRA_APPWIDGET_PROVIDER_PROFILE}</td>
108 * <td>An optional handle to a user profile under which runs the provider
109 * for this AppWidget.
110 * </td>
111 * </tr>
Michael Jurka61a5b012012-04-13 10:39:45 -0700112 * </table>
113 *
114 * <p>
115 * The system will respond with an onActivityResult call with the following extras in
116 * the intent:
117 * <table>
118 * <tr>
119 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
120 * <td>The appWidgetId that you supplied in the original intent.</td>
121 * </tr>
122 * </table>
123 * <p>
124 * When you receive the result from the AppWidget bind activity, if the resultCode is
125 * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound. You should then
126 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
127 * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you
Svetoslav976e8bd2014-07-16 15:12:03 -0700128 * should delete the appWidgetId.
Michael Jurka61a5b012012-04-13 10:39:45 -0700129 *
130 * @see #ACTION_APPWIDGET_CONFIGURE
131 *
132 */
133 public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND";
134
135 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700136 * Sent when it is time to configure your AppWidget while it is being added to a host.
137 * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity
Svetoslav976e8bd2014-07-16 15:12:03 -0700138 * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo
139 * meta-data}.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700140 *
141 * <p>
142 * The intent will contain the following extras:
143 * <table>
144 * <tr>
145 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
146 * <td>The appWidgetId to configure.</td>
147 * </tr>
148 * </table>
149 *
150 * <p>If you return {@link android.app.Activity#RESULT_OK} using
151 * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added,
152 * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget.
153 * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
Svetoslav976e8bd2014-07-16 15:12:03 -0700154 * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED}
155 * broadcast.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700156 */
157 public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
158
159 /**
160 * An intent extra that contains one appWidgetId.
161 * <p>
162 * The value will be an int that can be retrieved like this:
163 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID}
164 */
165 public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
166
167 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700168 * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700169 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700170 public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
Adam Cohene8724c82012-04-19 17:11:40 -0700171
172 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700173 * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700174 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700175 public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
Adam Cohene8724c82012-04-19 17:11:40 -0700176
177 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700178 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700179 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700180 public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
Adam Cohene8724c82012-04-19 17:11:40 -0700181
182 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700183 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700184 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700185 public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
Adam Cohene8724c82012-04-19 17:11:40 -0700186
187 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700188 * A bundle extra that hints to the AppWidgetProvider the category of host that owns this
189 * this widget. Can have the value {@link
190 * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link
Winson Chungda5b84c2014-05-05 12:06:28 -0700191 * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD} or {@link
Winson Chungee0b1212014-09-04 16:42:53 +0200192 * AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}.
Adam Cohen0aa2d422012-09-07 17:37:26 -0700193 */
194 public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
195
196 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700197 * An intent extra which points to a bundle of extra information for a particular widget id.
Svetoslav976e8bd2014-07-16 15:12:03 -0700198 * In particular this bundle can contain {@link #OPTION_APPWIDGET_MIN_WIDTH},
199 * {@link #OPTION_APPWIDGET_MIN_HEIGHT}, {@link #OPTION_APPWIDGET_MAX_WIDTH},
200 * {@link #OPTION_APPWIDGET_MAX_HEIGHT}.
Adam Cohene8724c82012-04-19 17:11:40 -0700201 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700202 public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
Adam Cohene8724c82012-04-19 17:11:40 -0700203
204 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700205 * An intent extra that contains multiple appWidgetIds.
206 * <p>
207 * The value will be an int array that can be retrieved like this:
208 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
209 */
210 public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
211
212 /**
Michael Jurka61a5b012012-04-13 10:39:45 -0700213 * An intent extra that contains the component name of a AppWidget provider.
214 * <p>
Svetoslav976e8bd2014-07-16 15:12:03 -0700215 * The value will be an {@link android.content.ComponentName}.
Michael Jurka61a5b012012-04-13 10:39:45 -0700216 */
217 public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
218
219 /**
Svetoslav976e8bd2014-07-16 15:12:03 -0700220 * An intent extra that contains the user handle of the profile under
221 * which an AppWidget provider is registered.
222 * <p>
223 * The value will be a {@link android.os.UserHandle}.
224 */
225 public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
226
227 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700228 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
229 * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are
230 * installed. (This is how the launcher shows the search widget).
231 */
232 public static final String EXTRA_CUSTOM_INFO = "customInfo";
233
234 /**
Christopher Tateadfe8b82014-02-04 16:23:32 -0800235 * An intent extra attached to the {@link #ACTION_APPWIDGET_HOST_RESTORED} broadcast,
236 * indicating the integer ID of the host whose widgets have just been restored.
237 */
238 public static final String EXTRA_HOST_ID = "hostId";
239
240 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700241 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
242 * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are
243 * installed. It will be added to the extras object on the {@link android.content.Intent}
244 * that is returned from the picker activity.
245 *
246 * {@more}
247 */
248 public static final String EXTRA_CUSTOM_EXTRAS = "customExtras";
249
250 /**
Adam Cohen8c09f632012-09-11 18:23:35 -0700251 * An intent extra to pass to the AppWidget picker which allows the picker to filter
252 * the list based on the {@link AppWidgetProviderInfo#widgetCategory}.
Jim Millerf229e4d2012-09-12 20:32:50 -0700253 *
254 * @hide
Adam Cohen8c09f632012-09-11 18:23:35 -0700255 */
Adam Cohen8c09f632012-09-11 18:23:35 -0700256 public static final String EXTRA_CATEGORY_FILTER = "categoryFilter";
257
258 /**
Jim Millerf229e4d2012-09-12 20:32:50 -0700259 * An intent extra to pass to the AppWidget picker to specify whether or not to sort
260 * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets
261 * @hide
262 */
263 public static final String EXTRA_CUSTOM_SORT = "customSort";
264
265 /**
Scott Main6aad9952013-01-07 18:51:49 -0800266 * A sentinel value that the AppWidget manager will never return as a appWidgetId.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700267 */
268 public static final int INVALID_APPWIDGET_ID = 0;
269
270 /**
271 * Sent when it is time to update your AppWidget.
272 *
273 * <p>This may be sent in response to a new instance for this AppWidget provider having
274 * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval}
275 * having lapsed, or the system booting.
276 *
277 * <p>
278 * The intent will contain the following extras:
279 * <table>
280 * <tr>
281 * <td>{@link #EXTRA_APPWIDGET_IDS}</td>
282 * <td>The appWidgetIds to update. This may be all of the AppWidgets created for this
283 * provider, or just a subset. The system tries to send updates for as few AppWidget
284 * instances as possible.</td>
285 * </tr>
286 * </table>
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200287 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700288 * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
289 */
290 public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
291
292 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700293 * Sent when the custom extras for an AppWidget change.
294 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700295 * <p class="note">This is a protected intent that can only be sent
296 * by the system.
297 *
Jim Millera75a8832013-02-07 16:53:32 -0800298 * @see AppWidgetProvider#onAppWidgetOptionsChanged
299 * AppWidgetProvider.onAppWidgetOptionsChanged(Context context,
Katie McCormick0e9f34b2012-09-10 15:32:46 -0700300 * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
Adam Cohene8724c82012-04-19 17:11:40 -0700301 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700302 public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
Adam Cohene8724c82012-04-19 17:11:40 -0700303
304 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700305 * Sent when an instance of an AppWidget is deleted from its host.
306 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700307 * <p class="note">This is a protected intent that can only be sent
308 * by the system.
309 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700310 * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
311 */
312 public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
313
314 /**
Svetoslav976e8bd2014-07-16 15:12:03 -0700315 * Sent when the last AppWidget of this provider is removed from the last host.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200316 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700317 * <p class="note">This is a protected intent that can only be sent
318 * by the system.
319 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700320 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context)
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700321 */
322 public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
323
324 /**
325 * Sent when an instance of an AppWidget is added to a host for the first time.
326 * This broadcast is sent at boot time if there is a AppWidgetHost installed with
327 * an instance for this provider.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200328 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700329 * <p class="note">This is a protected intent that can only be sent
330 * by the system.
331 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700332 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
333 */
334 public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
335
336 /**
Christopher Tatec04e9aa2014-05-28 17:56:53 -0700337 * Sent to an {@link AppWidgetProvider} after AppWidget state related to that provider has
338 * been restored from backup. The intent contains information about how to translate AppWidget
339 * ids from the restored data to their new equivalents.
Christopher Tateadfe8b82014-02-04 16:23:32 -0800340 *
341 * <p>The intent will contain the following extras:
342 *
343 * <table>
344 * <tr>
345 * <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
346 * <td>The set of appWidgetIds represented in a restored backup that have been successfully
347 * incorporated into the current environment. This may be all of the AppWidgets known
348 * to this application, or just a subset. Each entry in this array of appWidgetIds has
349 * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
350 * </tr>
351 * <tr>
352 * <td>{@link #EXTRA_APPWIDGET_IDS}</td>
353 * <td>The set of appWidgetIds now valid for this application. The app should look at
354 * its restored widget configuration and translate each appWidgetId in the
355 * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
356 * index within this array.</td>
357 * </tr>
358 * </table>
359 *
360 * <p class="note">This is a protected intent that can only be sent
361 * by the system.
362 *
Christopher Tatec04e9aa2014-05-28 17:56:53 -0700363 * @see #ACTION_APPWIDGET_HOST_RESTORED
Christopher Tateadfe8b82014-02-04 16:23:32 -0800364 */
365 public static final String ACTION_APPWIDGET_RESTORED
366 = "android.appwidget.action.APPWIDGET_RESTORED";
367
368 /**
369 * Sent to widget hosts after AppWidget state related to the host has been restored from
370 * backup. The intent contains information about how to translate AppWidget ids from the
371 * restored data to their new equivalents. If an application maintains multiple separate
Christopher Tatec04e9aa2014-05-28 17:56:53 -0700372 * widget host instances, it will receive this broadcast separately for each one.
Christopher Tateadfe8b82014-02-04 16:23:32 -0800373 *
374 * <p>The intent will contain the following extras:
375 *
376 * <table>
377 * <tr>
378 * <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
379 * <td>The set of appWidgetIds represented in a restored backup that have been successfully
380 * incorporated into the current environment. This may be all of the AppWidgets known
381 * to this application, or just a subset. Each entry in this array of appWidgetIds has
382 * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
383 * </tr>
384 * <tr>
385 * <td>{@link #EXTRA_APPWIDGET_IDS}</td>
386 * <td>The set of appWidgetIds now valid for this application. The app should look at
387 * its restored widget configuration and translate each appWidgetId in the
388 * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
389 * index within this array.</td>
390 * </tr>
391 * <tr>
392 * <td>{@link #EXTRA_HOST_ID}</td>
393 * <td>The integer ID of the widget host instance whose state has just been restored.</td>
394 * </tr>
395 * </table>
396 *
397 * <p class="note">This is a protected intent that can only be sent
398 * by the system.
399 *
Christopher Tatec04e9aa2014-05-28 17:56:53 -0700400 * @see #ACTION_APPWIDGET_RESTORED
Christopher Tateadfe8b82014-02-04 16:23:32 -0800401 */
402 public static final String ACTION_APPWIDGET_HOST_RESTORED
403 = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
404
405 /**
406 * An intent extra that contains multiple appWidgetIds. These are id values as
407 * they were provided to the application during a recent restore from backup. It is
408 * attached to the {@link #ACTION_APPWIDGET_RESTORED} broadcast intent.
409 *
410 * <p>
411 * The value will be an int array that can be retrieved like this:
412 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
413 */
414 public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
415
416 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700417 * Field for the manifest meta-data tag.
418 *
419 * @see AppWidgetProviderInfo
420 */
421 public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200422
Svetoslav976e8bd2014-07-16 15:12:03 -0700423 private final String mPackageName;
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200424
Svetoslav976e8bd2014-07-16 15:12:03 -0700425 private final IAppWidgetService mService;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700426
Svetoslav976e8bd2014-07-16 15:12:03 -0700427 private final DisplayMetrics mDisplayMetrics;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700428
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700429 /**
430 * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
431 * Context} object.
432 */
433 public static AppWidgetManager getInstance(Context context) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700434 return (AppWidgetManager) context.getSystemService(Context.APPWIDGET_SERVICE);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700435 }
436
Svetoslav976e8bd2014-07-16 15:12:03 -0700437 /**
438 * Creates a new instance.
439 *
440 * @param context The current context in which to operate.
441 * @param service The backing system service.
442 * @hide
443 */
444 public AppWidgetManager(Context context, IAppWidgetService service) {
Svet Ganov5771ad72014-08-23 21:10:29 -0700445 mPackageName = context.getOpPackageName();
Svetoslav976e8bd2014-07-16 15:12:03 -0700446 mService = service;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700447 mDisplayMetrics = context.getResources().getDisplayMetrics();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700448 }
449
450 /**
451 * Set the RemoteViews to use for the specified appWidgetIds.
Svetoslav976e8bd2014-07-16 15:12:03 -0700452 * <p>
Adam Cohen2dd21972010-08-15 18:20:04 -0700453 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
454 * contain a complete representation of the widget. For performing partial widget updates, see
455 * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}.
456 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700457 * <p>
458 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
459 * and outside of the handler.
460 * This method will only work when called from the uid that owns the AppWidget provider.
Jim Millera75a8832013-02-07 16:53:32 -0800461 *
Adam Cohen311c79c2012-05-10 14:44:38 -0700462 * <p>
463 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
Michael Jurkaf25ab442012-06-25 15:11:21 -0700464 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700465 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700466 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
467 * @param views The RemoteViews object to show.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700468 */
469 public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700470 if (mService == null) {
471 return;
472 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700473 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700474 mService.updateAppWidgetIds(mPackageName, appWidgetIds, views);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700475 }
476 catch (RemoteException e) {
477 throw new RuntimeException("system server dead?", e);
478 }
479 }
480
481 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700482 * Update the extras for a given widget instance.
Svetoslav976e8bd2014-07-16 15:12:03 -0700483 * <p>
Adam Cohene8724c82012-04-19 17:11:40 -0700484 * The extras can be used to embed additional information about this widget to be accessed
485 * by the associated widget's AppWidgetProvider.
486 *
Adam Cohend2097eb2012-05-01 18:10:28 -0700487 * @see #getAppWidgetOptions(int)
Adam Cohene8724c82012-04-19 17:11:40 -0700488 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700489 * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
490 * @param options The options to associate with this widget
Adam Cohene8724c82012-04-19 17:11:40 -0700491 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700492 public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700493 if (mService == null) {
494 return;
495 }
Adam Cohene8724c82012-04-19 17:11:40 -0700496 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700497 mService.updateAppWidgetOptions(mPackageName, appWidgetId, options);
Adam Cohene8724c82012-04-19 17:11:40 -0700498 }
499 catch (RemoteException e) {
500 throw new RuntimeException("system server dead?", e);
501 }
502 }
503
504 /**
505 * Get the extras associated with a given widget instance.
Svetoslav976e8bd2014-07-16 15:12:03 -0700506 * <p>
Adam Cohene8724c82012-04-19 17:11:40 -0700507 * The extras can be used to embed additional information about this widget to be accessed
508 * by the associated widget's AppWidgetProvider.
509 *
Adam Cohend2097eb2012-05-01 18:10:28 -0700510 * @see #updateAppWidgetOptions(int, Bundle)
Adam Cohene8724c82012-04-19 17:11:40 -0700511 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700512 * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
513 * @return The options associated with the given widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700514 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700515 public Bundle getAppWidgetOptions(int appWidgetId) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700516 if (mService == null) {
517 return Bundle.EMPTY;
518 }
Adam Cohene8724c82012-04-19 17:11:40 -0700519 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700520 return mService.getAppWidgetOptions(mPackageName, appWidgetId);
Adam Cohene8724c82012-04-19 17:11:40 -0700521 }
522 catch (RemoteException e) {
523 throw new RuntimeException("system server dead?", e);
524 }
525 }
526
527 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700528 * Set the RemoteViews to use for the specified appWidgetId.
Svetoslav976e8bd2014-07-16 15:12:03 -0700529 * <p>
Adam Cohen2dd21972010-08-15 18:20:04 -0700530 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
531 * contain a complete representation of the widget. For performing partial widget updates, see
532 * {@link #partiallyUpdateAppWidget(int, RemoteViews)}.
533 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700534 * <p>
535 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
536 * and outside of the handler.
537 * This method will only work when called from the uid that owns the AppWidget provider.
538 *
Adam Cohen311c79c2012-05-10 14:44:38 -0700539 * <p>
540 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
Michael Jurkaf25ab442012-06-25 15:11:21 -0700541 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
Adam Cohen311c79c2012-05-10 14:44:38 -0700542 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700543 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
544 * @param views The RemoteViews object to show.
545 */
546 public void updateAppWidget(int appWidgetId, RemoteViews views) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700547 if (mService == null) {
548 return;
549 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700550 updateAppWidget(new int[] { appWidgetId }, views);
551 }
552
553 /**
Adam Cohen2dd21972010-08-15 18:20:04 -0700554 * Perform an incremental update or command on the widget(s) specified by appWidgetIds.
Svetoslav976e8bd2014-07-16 15:12:03 -0700555 * <p>
Adam Cohen2dd21972010-08-15 18:20:04 -0700556 * This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
Jim Millera75a8832013-02-07 16:53:32 -0800557 * RemoteViews object which is passed is understood to be an incomplete representation of the
Adam Cohenfbe44b72012-09-19 20:36:23 -0700558 * widget, and hence does not replace the cached representation of the widget. As of API
559 * level 17, the new properties set within the views objects will be appended to the cached
560 * representation of the widget, and hence will persist.
Adam Cohen2dd21972010-08-15 18:20:04 -0700561 *
562 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
563 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
564 *
565 * <p>
566 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
567 * and outside of the handler.
568 * This method will only work when called from the uid that owns the AppWidget provider.
569 *
Winson Chung66119882012-10-11 14:26:25 -0700570 * <p>
571 * This method will be ignored if a widget has not received a full update via
572 * {@link #updateAppWidget(int[], RemoteViews)}.
573 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700574 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
575 * @param views The RemoteViews object containing the incremental update / command.
576 */
577 public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700578 if (mService == null) {
579 return;
580 }
Adam Cohen2dd21972010-08-15 18:20:04 -0700581 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700582 mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views);
Adam Cohen2dd21972010-08-15 18:20:04 -0700583 } catch (RemoteException e) {
584 throw new RuntimeException("system server dead?", e);
585 }
586 }
587
588 /**
589 * Perform an incremental update or command on the widget specified by appWidgetId.
Svetoslav976e8bd2014-07-16 15:12:03 -0700590 * <p>
Adam Cohen2dd21972010-08-15 18:20:04 -0700591 * This update differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews
592 * object which is passed is understood to be an incomplete representation of the widget, and
593 * hence is not cached by the AppWidgetService. Note that because these updates are not cached,
594 * any state that they modify that is not restored by restoreInstanceState will not persist in
595 * the case that the widgets are restored using the cached version in AppWidgetService.
596 *
597 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
598 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
599 *
600 * <p>
601 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
602 * and outside of the handler.
603 * This method will only work when called from the uid that owns the AppWidget provider.
604 *
Winson Chung66119882012-10-11 14:26:25 -0700605 * <p>
606 * This method will be ignored if a widget has not received a full update via
607 * {@link #updateAppWidget(int[], RemoteViews)}.
608 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700609 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
610 * @param views The RemoteViews object containing the incremental update / command.
611 */
612 public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700613 if (mService == null) {
614 return;
615 }
Adam Cohen2dd21972010-08-15 18:20:04 -0700616 partiallyUpdateAppWidget(new int[] { appWidgetId }, views);
617 }
618
619 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700620 * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider.
621 *
622 * <p>
623 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
624 * and outside of the handler.
625 * This method will only work when called from the uid that owns the AppWidget provider.
626 *
627 * @param provider The {@link ComponentName} for the {@link
628 * android.content.BroadcastReceiver BroadcastReceiver} provider
629 * for your AppWidget.
630 * @param views The RemoteViews object to show.
631 */
632 public void updateAppWidget(ComponentName provider, RemoteViews views) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700633 if (mService == null) {
634 return;
635 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700636 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700637 mService.updateAppWidgetProvider(provider, views);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700638 }
639 catch (RemoteException e) {
640 throw new RuntimeException("system server dead?", e);
641 }
642 }
643
644 /**
Winson Chung499cb9f2010-07-16 11:18:17 -0700645 * Notifies the specified collection view in all the specified AppWidget instances
John Spurlock77624cd2013-06-03 09:47:01 -0400646 * to invalidate their data.
Winson Chung499cb9f2010-07-16 11:18:17 -0700647 *
John Spurlock77624cd2013-06-03 09:47:01 -0400648 * @param appWidgetIds The AppWidget instances to notify of view data changes.
Winson Chung499cb9f2010-07-16 11:18:17 -0700649 * @param viewId The collection view id.
650 */
Winson Chung6394c0e2010-08-16 10:14:56 -0700651 public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700652 if (mService == null) {
653 return;
654 }
Winson Chung499cb9f2010-07-16 11:18:17 -0700655 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700656 mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId);
Winson Chung499cb9f2010-07-16 11:18:17 -0700657 }
658 catch (RemoteException e) {
659 throw new RuntimeException("system server dead?", e);
660 }
661 }
662
663 /**
John Spurlock77624cd2013-06-03 09:47:01 -0400664 * Notifies the specified collection view in the specified AppWidget instance
665 * to invalidate its data.
Winson Chung499cb9f2010-07-16 11:18:17 -0700666 *
John Spurlock77624cd2013-06-03 09:47:01 -0400667 * @param appWidgetId The AppWidget instance to notify of view data changes.
668 * @param viewId The collection view id.
Winson Chung499cb9f2010-07-16 11:18:17 -0700669 */
Winson Chung6394c0e2010-08-16 10:14:56 -0700670 public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700671 if (mService == null) {
672 return;
673 }
Winson Chung6394c0e2010-08-16 10:14:56 -0700674 notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
Winson Chung499cb9f2010-07-16 11:18:17 -0700675 }
676
677 /**
Svetoslav8e1d2992014-08-08 12:48:06 -0700678 * Gets the AppWidget providers for the given user profile. User profile can only
Svetoslav976e8bd2014-07-16 15:12:03 -0700679 * be the current user or a profile of the current user. For example, the current
680 * user may have a corporate profile. In this case the parent user profile has a
681 * child profile, the corporate one.
682 *
Svetoslav8e1d2992014-08-08 12:48:06 -0700683 * @param profile The profile for which to get providers. Passing null is equivaled
Svetoslav976e8bd2014-07-16 15:12:03 -0700684 * to passing only the current user handle.
685 * @return The intalled providers.
686 *
687 * @see android.os.Process#myUserHandle()
688 * @see android.os.UserManager#getUserProfiles()
689 */
Svetoslav8e1d2992014-08-08 12:48:06 -0700690 public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(@Nullable UserHandle profile) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700691 if (mService == null) {
692 return Collections.emptyList();
693 }
Svetoslav8e1d2992014-08-08 12:48:06 -0700694 return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
695 profile);
Svetoslav976e8bd2014-07-16 15:12:03 -0700696 }
697
698 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700699 * Return a list of the AppWidget providers that are currently installed.
700 */
701 public List<AppWidgetProviderInfo> getInstalledProviders() {
Svetoslav976e8bd2014-07-16 15:12:03 -0700702 if (mService == null) {
703 return Collections.emptyList();
704 }
Svetoslav8e1d2992014-08-08 12:48:06 -0700705 return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
Svetoslav976e8bd2014-07-16 15:12:03 -0700706 null);
Adam Cohend9e5af32012-11-28 16:34:57 -0800707 }
708
709 /**
Svetoslav976e8bd2014-07-16 15:12:03 -0700710 * Gets the AppWidget providers for the current user.
Adam Cohend9e5af32012-11-28 16:34:57 -0800711 *
712 * @param categoryFilter Will only return providers which register as any of the specified
713 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
Svetoslav976e8bd2014-07-16 15:12:03 -0700714 * @return The intalled providers.
715 *
716 * @see android.os.Process#myUserHandle()
717 * @see android.os.UserManager#getUserProfiles()
718 *
Adam Cohend9e5af32012-11-28 16:34:57 -0800719 * @hide
720 */
721 public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700722 if (mService == null) {
723 return Collections.emptyList();
724 }
Svetoslav8e1d2992014-08-08 12:48:06 -0700725 return getInstalledProvidersForProfile(categoryFilter, null);
Svetoslav976e8bd2014-07-16 15:12:03 -0700726 }
727
728 /**
Svetoslav8e1d2992014-08-08 12:48:06 -0700729 * Gets the AppWidget providers for the given user profile. User profile can only
Svetoslav976e8bd2014-07-16 15:12:03 -0700730 * be the current user or a profile of the current user. For example, the current
731 * user may have a corporate profile. In this case the parent user profile has a
732 * child profile, the corporate one.
733 *
734 * @param categoryFilter Will only return providers which register as any of the specified
735 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
Svetoslav8e1d2992014-08-08 12:48:06 -0700736 * @param profile A profile of the current user which to be queried. The user
Svetoslav976e8bd2014-07-16 15:12:03 -0700737 * is itself also a profile. If null, the providers only for the current user
738 * are returned.
739 * @return The intalled providers.
740 *
741 * @see android.os.Process#myUserHandle()
742 * @see android.os.UserManager#getUserProfiles()
743 *
744 * @hide
745 */
Svetoslav8e1d2992014-08-08 12:48:06 -0700746 public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
747 UserHandle profile) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700748 if (mService == null) {
749 return Collections.emptyList();
750 }
751
Svetoslav8e1d2992014-08-08 12:48:06 -0700752 if (profile == null) {
753 profile = Process.myUserHandle();
Svetoslav976e8bd2014-07-16 15:12:03 -0700754 }
755
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700756 try {
Hyunyoung Songccf6c682015-06-17 15:23:31 -0700757 ParceledListSlice<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile(
Svetoslav8e1d2992014-08-08 12:48:06 -0700758 categoryFilter, profile.getIdentifier());
Svetoslav976e8bd2014-07-16 15:12:03 -0700759 if (providers == null) {
760 return Collections.emptyList();
761 }
Hyunyoung Songccf6c682015-06-17 15:23:31 -0700762 for (AppWidgetProviderInfo info : providers.getList()) {
Patrick Dubroy5d140912010-07-12 10:25:27 -0700763 // Converting complex to dp.
Svetoslav976e8bd2014-07-16 15:12:03 -0700764 convertSizesToPixels(info);
Patrick Dubroy5d140912010-07-12 10:25:27 -0700765 }
Hyunyoung Songccf6c682015-06-17 15:23:31 -0700766 return providers.getList();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700767 }
768 catch (RemoteException e) {
769 throw new RuntimeException("system server dead?", e);
770 }
771 }
772
773 /**
774 * Get the available info about the AppWidget.
775 *
776 * @return A appWidgetId. If the appWidgetId has not been bound to a provider yet, or
777 * you don't have access to that appWidgetId, null is returned.
778 */
779 public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700780 if (mService == null) {
781 return null;
782 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700783 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700784 AppWidgetProviderInfo info = mService.getAppWidgetInfo(mPackageName, appWidgetId);
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700785 if (info != null) {
786 // Converting complex to dp.
Svetoslav976e8bd2014-07-16 15:12:03 -0700787 convertSizesToPixels(info);
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700788 }
789 return info;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700790 }
791 catch (RemoteException e) {
792 throw new RuntimeException("system server dead?", e);
793 }
794 }
795
796 /**
797 * Set the component for a given appWidgetId.
798 *
Michael Jurka61a5b012012-04-13 10:39:45 -0700799 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
800 * widgets always for your component. This method is used by the AppWidget picker and
801 * should not be used by other apps.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700802 *
803 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
804 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
805 * provider for this AppWidget.
Michael Jurka61a5b012012-04-13 10:39:45 -0700806 * @hide
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700807 */
808 public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700809 if (mService == null) {
810 return;
Adam Cohen0aa2d422012-09-07 17:37:26 -0700811 }
Svetoslav976e8bd2014-07-16 15:12:03 -0700812 bindAppWidgetId(appWidgetId, provider, null);
Adam Cohen0aa2d422012-09-07 17:37:26 -0700813 }
814
815 /**
816 * Set the component for a given appWidgetId.
817 *
818 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
819 * widgets always for your component. This method is used by the AppWidget picker and
820 * should not be used by other apps.
821 *
822 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
823 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
824 * provider for this AppWidget.
825 * @param options Bundle containing options for the AppWidget. See also
826 * {@link #updateAppWidgetOptions(int, Bundle)}
827 *
828 * @hide
829 */
830 public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700831 if (mService == null) {
832 return;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700833 }
Svetoslav976e8bd2014-07-16 15:12:03 -0700834 bindAppWidgetIdIfAllowed(appWidgetId, Process.myUserHandle(), provider, options);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700835 }
836
837 /**
Michael Jurka61a5b012012-04-13 10:39:45 -0700838 * Set the component for a given appWidgetId.
839 *
840 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
841 * widgets always for your component. Should be used by apps that host widgets; if this
842 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
843 * bind
844 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700845 * @param appWidgetId The AppWidget id under which to bind the provider.
Michael Jurka61a5b012012-04-13 10:39:45 -0700846 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
847 * provider for this AppWidget.
848 * @return true if this component has permission to bind the AppWidget
849 */
850 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700851 if (mService == null) {
Michael Jurka61a5b012012-04-13 10:39:45 -0700852 return false;
853 }
Svetoslav976e8bd2014-07-16 15:12:03 -0700854 return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, null);
Adam Cohen0aa2d422012-09-07 17:37:26 -0700855 }
856
857 /**
858 * Set the component for a given appWidgetId.
859 *
860 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
861 * widgets always for your component. Should be used by apps that host widgets; if this
862 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
863 * bind
864 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700865 * @param appWidgetId The AppWidget id under which to bind the provider.
Adam Cohen0aa2d422012-09-07 17:37:26 -0700866 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
867 * provider for this AppWidget.
868 * @param options Bundle containing options for the AppWidget. See also
869 * {@link #updateAppWidgetOptions(int, Bundle)}
870 *
871 * @return true if this component has permission to bind the AppWidget
872 */
873 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
874 Bundle options) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700875 if (mService == null) {
876 return false;
877 }
878 return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, options);
879 }
880
881 /**
882 * Set the provider for a given appWidgetId if the caller has a permission.
883 * <p>
884 * <strong>Note:</strong> You need the {@link android.Manifest.permission#BIND_APPWIDGET}
885 * permission or the user must have enabled binding widgets always for your component.
886 * Should be used by apps that host widgets. If this method returns false, call {@link
887 * #ACTION_APPWIDGET_BIND} to request permission to bind.
888 * </p>
889 *
890 * @param appWidgetId The AppWidget id under which to bind the provider.
891 * @param user The user id in which the provider resides.
892 * @param provider The component name of the provider.
893 * @param options An optional Bundle containing options for the AppWidget.
894 *
895 * @return true if this component has permission to bind the AppWidget
896 */
897 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, UserHandle user,
898 ComponentName provider, Bundle options) {
899 if (mService == null) {
900 return false;
901 }
902 return bindAppWidgetIdIfAllowed(appWidgetId, user.getIdentifier(), provider, options);
903 }
904
905 /**
906 * Query if a given package was granted permission by the user to bind app widgets
907 *
908 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
909 *
910 * @param packageName The package for which the permission is being queried
911 * @param userId The user id of the user under which the package runs.
912 * @return true if the package was granted permission by the user to bind app widgets
913 * @hide
914 */
915 public boolean hasBindAppWidgetPermission(String packageName, int userId) {
916 if (mService == null) {
Adam Cohen0aa2d422012-09-07 17:37:26 -0700917 return false;
918 }
919 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700920 return mService.hasBindAppWidgetPermission(packageName, userId);
Michael Jurka61a5b012012-04-13 10:39:45 -0700921 }
922 catch (RemoteException e) {
923 throw new RuntimeException("system server dead?", e);
924 }
925 }
926
927 /**
928 * Query if a given package was granted permission by the user to bind app widgets
929 *
930 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
931 *
932 * @param packageName The package for which the permission is being queried
933 * @return true if the package was granted permission by the user to bind app widgets
934 * @hide
935 */
936 public boolean hasBindAppWidgetPermission(String packageName) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700937 if (mService == null) {
938 return false;
939 }
Michael Jurka61a5b012012-04-13 10:39:45 -0700940 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700941 return mService.hasBindAppWidgetPermission(packageName, UserHandle.myUserId());
Michael Jurka61a5b012012-04-13 10:39:45 -0700942 }
943 catch (RemoteException e) {
944 throw new RuntimeException("system server dead?", e);
945 }
946 }
947
948 /**
949 * Changes any user-granted permission for the given package to bind app widgets
950 *
951 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
952 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700953 * @param packageName The package whose permission is being changed
954 * @param permission Whether to give the package permission to bind widgets
955 *
Michael Jurka61a5b012012-04-13 10:39:45 -0700956 * @hide
957 */
958 public void setBindAppWidgetPermission(String packageName, boolean permission) {
Svetoslav976e8bd2014-07-16 15:12:03 -0700959 if (mService == null) {
960 return;
961 }
962 setBindAppWidgetPermission(packageName, UserHandle.myUserId(), permission);
963 }
964
965 /**
966 * Changes any user-granted permission for the given package to bind app widgets
967 *
968 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
969 *
970 * @param packageName The package whose permission is being changed
971 * @param userId The user under which the package is running.
972 * @param permission Whether to give the package permission to bind widgets
973 *
974 * @hide
975 */
976 public void setBindAppWidgetPermission(String packageName, int userId, boolean permission) {
977 if (mService == null) {
978 return;
979 }
Michael Jurka61a5b012012-04-13 10:39:45 -0700980 try {
Svetoslav976e8bd2014-07-16 15:12:03 -0700981 mService.setBindAppWidgetPermission(packageName, userId, permission);
Michael Jurka61a5b012012-04-13 10:39:45 -0700982 }
983 catch (RemoteException e) {
984 throw new RuntimeException("system server dead?", e);
985 }
986 }
987
988 /**
Winson Chung81f39eb2011-01-11 18:05:01 -0800989 * Binds the RemoteViewsService for a given appWidgetId and intent.
990 *
991 * The appWidgetId specified must already be bound to the calling AppWidgetHost via
992 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
993 *
Svetoslav976e8bd2014-07-16 15:12:03 -0700994 * @param packageName The package from which the binding is requested.
Winson Chung81f39eb2011-01-11 18:05:01 -0800995 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
996 * @param intent The intent of the service which will be providing the data to the
997 * RemoteViewsAdapter.
998 * @param connection The callback interface to be notified when a connection is made or lost.
999 * @hide
1000 */
Svetoslav976e8bd2014-07-16 15:12:03 -07001001 public void bindRemoteViewsService(String packageName, int appWidgetId, Intent intent,
1002 IBinder connection) {
1003 if (mService == null) {
1004 return;
1005 }
Winson Chung81f39eb2011-01-11 18:05:01 -08001006 try {
Svetoslav976e8bd2014-07-16 15:12:03 -07001007 mService.bindRemoteViewsService(packageName, appWidgetId, intent, connection);
Winson Chung81f39eb2011-01-11 18:05:01 -08001008 }
1009 catch (RemoteException e) {
1010 throw new RuntimeException("system server dead?", e);
1011 }
1012 }
1013
1014 /**
1015 * Unbinds the RemoteViewsService for a given appWidgetId and intent.
1016 *
1017 * The appWidgetId specified muse already be bound to the calling AppWidgetHost via
1018 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
1019 *
Svetoslav976e8bd2014-07-16 15:12:03 -07001020 * @param packageName The package from which the binding is requested.
Winson Chung81f39eb2011-01-11 18:05:01 -08001021 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
1022 * @param intent The intent of the service which will be providing the data to the
1023 * RemoteViewsAdapter.
1024 * @hide
1025 */
Svetoslav976e8bd2014-07-16 15:12:03 -07001026 public void unbindRemoteViewsService(String packageName, int appWidgetId, Intent intent) {
1027 if (mService == null) {
1028 return;
1029 }
Winson Chung81f39eb2011-01-11 18:05:01 -08001030 try {
Svetoslav976e8bd2014-07-16 15:12:03 -07001031 mService.unbindRemoteViewsService(packageName, appWidgetId, intent);
Winson Chung81f39eb2011-01-11 18:05:01 -08001032 }
1033 catch (RemoteException e) {
1034 throw new RuntimeException("system server dead?", e);
1035 }
1036 }
1037
1038 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07001039 * Get the list of appWidgetIds that have been bound to the given AppWidget
1040 * provider.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +02001041 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07001042 * @param provider The {@link android.content.BroadcastReceiver} that is the
1043 * AppWidget provider to find appWidgetIds for.
1044 */
1045 public int[] getAppWidgetIds(ComponentName provider) {
Svetoslav976e8bd2014-07-16 15:12:03 -07001046 if (mService == null) {
1047 return new int[0];
1048 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07001049 try {
Svetoslav976e8bd2014-07-16 15:12:03 -07001050 return mService.getAppWidgetIds(provider);
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07001051 }
1052 catch (RemoteException e) {
1053 throw new RuntimeException("system server dead?", e);
1054 }
1055 }
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07001056
Amith Yamasanie4a8da82015-04-30 17:32:25 -07001057 /**
1058 * @hide
1059 */
1060 public boolean isBoundWidgetPackage(String packageName, int userId) {
1061 if (mService == null) {
1062 return false;
1063 }
1064 try {
1065 return mService.isBoundWidgetPackage(packageName, userId);
1066 } catch (RemoteException re) {
1067 throw new RuntimeException("system server dead?", re);
1068 }
1069 }
1070
Svetoslav976e8bd2014-07-16 15:12:03 -07001071 private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId,
1072 ComponentName provider, Bundle options) {
1073 if (mService == null) {
1074 return false;
1075 }
1076 try {
1077 return mService.bindAppWidgetId(mPackageName, appWidgetId,
1078 profileId, provider, options);
1079 }
1080 catch (RemoteException e) {
1081 throw new RuntimeException("system server dead?", e);
1082 }
1083 }
1084
1085 private void convertSizesToPixels(AppWidgetProviderInfo info) {
1086 // Converting complex to dp.
1087 info.minWidth = TypedValue.complexToDimensionPixelSize(info.minWidth,
1088 mDisplayMetrics);
1089 info.minHeight = TypedValue.complexToDimensionPixelSize(info.minHeight,
1090 mDisplayMetrics);
1091 info.minResizeWidth = TypedValue.complexToDimensionPixelSize(info.minResizeWidth,
1092 mDisplayMetrics);
1093 info.minResizeHeight = TypedValue.complexToDimensionPixelSize(info.minResizeHeight,
1094 mDisplayMetrics);
1095 }
1096}