• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package android.appwidget;
17 
18 import android.content.Context;
19 import android.os.Handler;
20 import android.os.IBinder;
21 import android.os.Looper;
22 import android.os.Message;
23 import android.os.RemoteException;
24 import android.os.ServiceManager;
25 import android.widget.RemoteViews;
26 
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 
30 import com.android.internal.appwidget.IAppWidgetHost;
31 import com.android.internal.appwidget.IAppWidgetService;
32 
33 /**
34  * AppWidgetHost provides the interaction with the AppWidget service for apps,
35  * like the home screen, that want to embed AppWidgets in their UI.
36  */
37 public class AppWidgetHost {
38 
39     static final int HANDLE_UPDATE = 1;
40     static final int HANDLE_PROVIDER_CHANGED = 2;
41 
42     final static Object sServiceLock = new Object();
43     static IAppWidgetService sService;
44 
45     Context mContext;
46     String mPackageName;
47 
48     class Callbacks extends IAppWidgetHost.Stub {
updateAppWidget(int appWidgetId, RemoteViews views)49         public void updateAppWidget(int appWidgetId, RemoteViews views) {
50             Message msg = mHandler.obtainMessage(HANDLE_UPDATE);
51             msg.arg1 = appWidgetId;
52             msg.obj = views;
53             msg.sendToTarget();
54         }
55 
providerChanged(int appWidgetId, AppWidgetProviderInfo info)56         public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
57             Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED);
58             msg.arg1 = appWidgetId;
59             msg.obj = info;
60             msg.sendToTarget();
61         }
62     }
63 
64     class UpdateHandler extends Handler {
UpdateHandler(Looper looper)65         public UpdateHandler(Looper looper) {
66             super(looper);
67         }
68 
handleMessage(Message msg)69         public void handleMessage(Message msg) {
70             switch (msg.what) {
71                 case HANDLE_UPDATE: {
72                     updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj);
73                     break;
74                 }
75                 case HANDLE_PROVIDER_CHANGED: {
76                     onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj);
77                     break;
78                 }
79             }
80         }
81     }
82 
83     Handler mHandler;
84 
85     int mHostId;
86     Callbacks mCallbacks = new Callbacks();
87     final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<Integer, AppWidgetHostView>();
88 
AppWidgetHost(Context context, int hostId)89     public AppWidgetHost(Context context, int hostId) {
90         mContext = context;
91         mHostId = hostId;
92         mHandler = new UpdateHandler(context.getMainLooper());
93         synchronized (sServiceLock) {
94             if (sService == null) {
95                 IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
96                 sService = IAppWidgetService.Stub.asInterface(b);
97             }
98         }
99     }
100 
101     /**
102      * Start receiving onAppWidgetChanged calls for your AppWidgets.  Call this when your activity
103      * becomes visible, i.e. from onStart() in your Activity.
104      */
startListening()105     public void startListening() {
106         int[] updatedIds;
107         ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>();
108 
109         try {
110             if (mPackageName == null) {
111                 mPackageName = mContext.getPackageName();
112             }
113             updatedIds = sService.startListening(mCallbacks, mPackageName, mHostId, updatedViews);
114         }
115         catch (RemoteException e) {
116             throw new RuntimeException("system server dead?", e);
117         }
118 
119         final int N = updatedIds.length;
120         for (int i=0; i<N; i++) {
121             updateAppWidgetView(updatedIds[i], updatedViews.get(i));
122         }
123     }
124 
125     /**
126      * Stop receiving onAppWidgetChanged calls for your AppWidgets.  Call this when your activity is
127      * no longer visible, i.e. from onStop() in your Activity.
128      */
stopListening()129     public void stopListening() {
130         try {
131             sService.stopListening(mHostId);
132         }
133         catch (RemoteException e) {
134             throw new RuntimeException("system server dead?", e);
135         }
136     }
137 
138     /**
139      * Get a appWidgetId for a host in the calling process.
140      *
141      * @return a appWidgetId
142      */
allocateAppWidgetId()143     public int allocateAppWidgetId() {
144         try {
145             if (mPackageName == null) {
146                 mPackageName = mContext.getPackageName();
147             }
148             return sService.allocateAppWidgetId(mPackageName, mHostId);
149         }
150         catch (RemoteException e) {
151             throw new RuntimeException("system server dead?", e);
152         }
153     }
154 
155     /**
156      * Stop listening to changes for this AppWidget.
157      */
deleteAppWidgetId(int appWidgetId)158     public void deleteAppWidgetId(int appWidgetId) {
159         synchronized (mViews) {
160             mViews.remove(appWidgetId);
161             try {
162                 sService.deleteAppWidgetId(appWidgetId);
163             }
164             catch (RemoteException e) {
165                 throw new RuntimeException("system server dead?", e);
166             }
167         }
168     }
169 
170     /**
171      * Remove all records about this host from the AppWidget manager.
172      * <ul>
173      *   <li>Call this when initializing your database, as it might be because of a data wipe.</li>
174      *   <li>Call this to have the AppWidget manager release all resources associated with your
175      *   host.  Any future calls about this host will cause the records to be re-allocated.</li>
176      * </ul>
177      */
deleteHost()178     public void deleteHost() {
179         try {
180             sService.deleteHost(mHostId);
181         }
182         catch (RemoteException e) {
183             throw new RuntimeException("system server dead?", e);
184         }
185     }
186 
187     /**
188      * Remove all records about all hosts for your package.
189      * <ul>
190      *   <li>Call this when initializing your database, as it might be because of a data wipe.</li>
191      *   <li>Call this to have the AppWidget manager release all resources associated with your
192      *   host.  Any future calls about this host will cause the records to be re-allocated.</li>
193      * </ul>
194      */
deleteAllHosts()195     public static void deleteAllHosts() {
196         try {
197             sService.deleteAllHosts();
198         }
199         catch (RemoteException e) {
200             throw new RuntimeException("system server dead?", e);
201         }
202     }
203 
createView(Context context, int appWidgetId, AppWidgetProviderInfo appWidget)204     public final AppWidgetHostView createView(Context context, int appWidgetId,
205             AppWidgetProviderInfo appWidget) {
206         AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget);
207         view.setAppWidget(appWidgetId, appWidget);
208         synchronized (mViews) {
209             mViews.put(appWidgetId, view);
210         }
211         RemoteViews views;
212         try {
213             views = sService.getAppWidgetViews(appWidgetId);
214         } catch (RemoteException e) {
215             throw new RuntimeException("system server dead?", e);
216         }
217         view.updateAppWidget(views);
218         return view;
219     }
220 
221     /**
222      * Called to create the AppWidgetHostView.  Override to return a custom subclass if you
223      * need it.  {@more}
224      */
onCreateView(Context context, int appWidgetId, AppWidgetProviderInfo appWidget)225     protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
226             AppWidgetProviderInfo appWidget) {
227         return new AppWidgetHostView(context);
228     }
229 
230     /**
231      * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk.
232      */
233     @SuppressWarnings({"UnusedDeclaration"})
onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget)234     protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) {
235     }
236 
updateAppWidgetView(int appWidgetId, RemoteViews views)237     void updateAppWidgetView(int appWidgetId, RemoteViews views) {
238         AppWidgetHostView v;
239         synchronized (mViews) {
240             v = mViews.get(appWidgetId);
241         }
242         if (v != null) {
243             v.updateAppWidget(views);
244         }
245     }
246 }
247 
248 
249