OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / core / java / android / appwidget / AppWidgetHost.java
1 /*
2  * Copyright (C) 2009 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.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;
27
28 import java.util.ArrayList;
29 import java.util.HashMap;
30
31 import com.android.internal.appwidget.IAppWidgetHost;
32 import com.android.internal.appwidget.IAppWidgetService;
33
34 /**
35  * AppWidgetHost provides the interaction with the AppWidget service for apps,
36  * like the home screen, that want to embed AppWidgets in their UI.
37  */
38 public class AppWidgetHost {
39
40     static final int HANDLE_UPDATE = 1;
41     static final int HANDLE_PROVIDER_CHANGED = 2;
42
43     final static Object sServiceLock = new Object();
44     static IAppWidgetService sService;
45
46     Context mContext;
47     String mPackageName;
48
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;
53             msg.obj = views;
54             msg.sendToTarget();
55         }
56
57         public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
58             Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED);
59             msg.arg1 = appWidgetId;
60             msg.obj = info;
61             msg.sendToTarget();
62         }
63     }
64
65     class UpdateHandler extends Handler {
66         public UpdateHandler(Looper looper) {
67             super(looper);
68         }
69         
70         public void handleMessage(Message msg) {
71             switch (msg.what) {
72                 case HANDLE_UPDATE: {
73                     updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj);
74                     break;
75                 }
76                 case HANDLE_PROVIDER_CHANGED: {
77                     onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj);
78                     break;
79                 }
80             }
81         }
82     }
83     
84     Handler mHandler;
85
86     int mHostId;
87     Callbacks mCallbacks = new Callbacks();
88     final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<Integer, AppWidgetHostView>();
89
90     public AppWidgetHost(Context context, int hostId) {
91         mContext = context;
92         mHostId = 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);
98             }
99         }
100     }
101
102     /**
103      * Start receiving onAppWidgetChanged calls for your AppWidgets.  Call this when your activity
104      * becomes visible, i.e. from onStart() in your Activity.
105      */
106     public void startListening() {
107         int[] updatedIds;
108         ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>();
109         
110         try {
111             if (mPackageName == null) {
112                 mPackageName = mContext.getPackageName();
113             }
114             updatedIds = sService.startListening(mCallbacks, mPackageName, mHostId, updatedViews);
115         }
116         catch (RemoteException e) {
117             throw new RuntimeException("system server dead?", e);
118         }
119
120         final int N = updatedIds.length;
121         for (int i=0; i<N; i++) {
122             updateAppWidgetView(updatedIds[i], updatedViews.get(i));
123         }
124     }
125
126     /**
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.
129      */
130     public void stopListening() {
131         try {
132             sService.stopListening(mHostId);
133         }
134         catch (RemoteException e) {
135             throw new RuntimeException("system server dead?", e);
136         }
137     }
138
139     /**
140      * Get a appWidgetId for a host in the calling process.
141      *
142      * @return a appWidgetId
143      */
144     public int allocateAppWidgetId() {
145         try {
146             if (mPackageName == null) {
147                 mPackageName = mContext.getPackageName();
148             }
149             return sService.allocateAppWidgetId(mPackageName, mHostId);
150         }
151         catch (RemoteException e) {
152             throw new RuntimeException("system server dead?", e);
153         }
154     }
155
156     /**
157      * Stop listening to changes for this AppWidget.  
158      */
159     public void deleteAppWidgetId(int appWidgetId) {
160         synchronized (mViews) {
161             mViews.remove(appWidgetId);
162             try {
163                 sService.deleteAppWidgetId(appWidgetId);
164             }
165             catch (RemoteException e) {
166                 throw new RuntimeException("system server dead?", e);
167             }
168         }
169     }
170
171     /**
172      * Remove all records about this host from the AppWidget manager.
173      * <ul>
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>
177      * </ul>
178      */
179     public void deleteHost() {
180         try {
181             sService.deleteHost(mHostId);
182         }
183         catch (RemoteException e) {
184             throw new RuntimeException("system server dead?", e);
185         }
186     }
187
188     /**
189      * Remove all records about all hosts for your package.
190      * <ul>
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>
194      * </ul>
195      */
196     public static void deleteAllHosts() {
197         try {
198             sService.deleteAllHosts();
199         }
200         catch (RemoteException e) {
201             throw new RuntimeException("system server dead?", e);
202         }
203     }
204
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);
211         }
212         RemoteViews views;
213         try {
214             views = sService.getAppWidgetViews(appWidgetId);
215         } catch (RemoteException e) {
216             throw new RuntimeException("system server dead?", e);
217         }
218         view.updateAppWidget(views);
219         return view;
220     }
221
222     /**
223      * Called to create the AppWidgetHostView.  Override to return a custom subclass if you
224      * need it.  {@more}
225      */
226     protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
227             AppWidgetProviderInfo appWidget) {
228         return new AppWidgetHostView(context);
229     }
230     
231     /**
232      * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk.
233      */
234     protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) {
235         AppWidgetHostView v;
236         synchronized (mViews) {
237             v = mViews.get(appWidgetId);
238         }
239         if (v != null) {
240             v.resetAppWidget(appWidget);
241         }
242     }
243
244     void updateAppWidgetView(int appWidgetId, RemoteViews views) {
245         AppWidgetHostView v;
246         synchronized (mViews) {
247             v = mViews.get(appWidgetId);
248         }
249         if (v != null) {
250             v.updateAppWidget(views);
251         }
252     }
253 }
254
255