2 * Copyright (C) 2009 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package android.appwidget;
19 import android.content.Context;
20 import android.os.Handler;
21 import android.os.IBinder;
22 import android.os.Looper;
23 import android.os.Message;
24 import android.os.RemoteException;
25 import android.os.ServiceManager;
26 import android.widget.RemoteViews;
28 import java.util.ArrayList;
29 import java.util.HashMap;
31 import com.android.internal.appwidget.IAppWidgetHost;
32 import com.android.internal.appwidget.IAppWidgetService;
35 * AppWidgetHost provides the interaction with the AppWidget service for apps,
36 * like the home screen, that want to embed AppWidgets in their UI.
38 public class AppWidgetHost {
40 static final int HANDLE_UPDATE = 1;
41 static final int HANDLE_PROVIDER_CHANGED = 2;
43 final static Object sServiceLock = new Object();
44 static IAppWidgetService sService;
49 class Callbacks extends IAppWidgetHost.Stub {
50 public void updateAppWidget(int appWidgetId, RemoteViews views) {
51 Message msg = mHandler.obtainMessage(HANDLE_UPDATE);
52 msg.arg1 = appWidgetId;
57 public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
58 Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED);
59 msg.arg1 = appWidgetId;
65 class UpdateHandler extends Handler {
66 public UpdateHandler(Looper looper) {
70 public void handleMessage(Message msg) {
73 updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj);
76 case HANDLE_PROVIDER_CHANGED: {
77 onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj);
87 Callbacks mCallbacks = new Callbacks();
88 final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<Integer, AppWidgetHostView>();
90 public AppWidgetHost(Context context, int hostId) {
93 mHandler = new UpdateHandler(context.getMainLooper());
94 synchronized (sServiceLock) {
95 if (sService == null) {
96 IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
97 sService = IAppWidgetService.Stub.asInterface(b);
103 * Start receiving onAppWidgetChanged calls for your AppWidgets. Call this when your activity
104 * becomes visible, i.e. from onStart() in your Activity.
106 public void startListening() {
108 ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>();
111 if (mPackageName == null) {
112 mPackageName = mContext.getPackageName();
114 updatedIds = sService.startListening(mCallbacks, mPackageName, mHostId, updatedViews);
116 catch (RemoteException e) {
117 throw new RuntimeException("system server dead?", e);
120 final int N = updatedIds.length;
121 for (int i=0; i<N; i++) {
122 updateAppWidgetView(updatedIds[i], updatedViews.get(i));
127 * Stop receiving onAppWidgetChanged calls for your AppWidgets. Call this when your activity is
128 * no longer visible, i.e. from onStop() in your Activity.
130 public void stopListening() {
132 sService.stopListening(mHostId);
134 catch (RemoteException e) {
135 throw new RuntimeException("system server dead?", e);
140 * Get a appWidgetId for a host in the calling process.
142 * @return a appWidgetId
144 public int allocateAppWidgetId() {
146 if (mPackageName == null) {
147 mPackageName = mContext.getPackageName();
149 return sService.allocateAppWidgetId(mPackageName, mHostId);
151 catch (RemoteException e) {
152 throw new RuntimeException("system server dead?", e);
157 * Stop listening to changes for this AppWidget.
159 public void deleteAppWidgetId(int appWidgetId) {
160 synchronized (mViews) {
161 mViews.remove(appWidgetId);
163 sService.deleteAppWidgetId(appWidgetId);
165 catch (RemoteException e) {
166 throw new RuntimeException("system server dead?", e);
172 * Remove all records about this host from the AppWidget manager.
174 * <li>Call this when initializing your database, as it might be because of a data wipe.</li>
175 * <li>Call this to have the AppWidget manager release all resources associated with your
176 * host. Any future calls about this host will cause the records to be re-allocated.</li>
179 public void deleteHost() {
181 sService.deleteHost(mHostId);
183 catch (RemoteException e) {
184 throw new RuntimeException("system server dead?", e);
189 * Remove all records about all hosts for your package.
191 * <li>Call this when initializing your database, as it might be because of a data wipe.</li>
192 * <li>Call this to have the AppWidget manager release all resources associated with your
193 * host. Any future calls about this host will cause the records to be re-allocated.</li>
196 public static void deleteAllHosts() {
198 sService.deleteAllHosts();
200 catch (RemoteException e) {
201 throw new RuntimeException("system server dead?", e);
205 public final AppWidgetHostView createView(Context context, int appWidgetId,
206 AppWidgetProviderInfo appWidget) {
207 AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget);
208 view.setAppWidget(appWidgetId, appWidget);
209 synchronized (mViews) {
210 mViews.put(appWidgetId, view);
214 views = sService.getAppWidgetViews(appWidgetId);
215 } catch (RemoteException e) {
216 throw new RuntimeException("system server dead?", e);
218 view.updateAppWidget(views);
223 * Called to create the AppWidgetHostView. Override to return a custom subclass if you
226 protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
227 AppWidgetProviderInfo appWidget) {
228 return new AppWidgetHostView(context);
232 * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk.
234 protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) {
236 synchronized (mViews) {
237 v = mViews.get(appWidgetId);
240 v.resetAppWidget(appWidget);
244 void updateAppWidgetView(int appWidgetId, RemoteViews views) {
246 synchronized (mViews) {
247 v = mViews.get(appWidgetId);
250 v.updateAppWidget(views);