diff options
Diffstat (limited to 'core/java/android/appwidget/AppWidgetHost.java')
-rw-r--r-- | core/java/android/appwidget/AppWidgetHost.java | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java new file mode 100644 index 0000000..10c2b02 --- /dev/null +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -0,0 +1,248 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.appwidget; + +import android.content.Context; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.widget.RemoteViews; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import com.android.internal.appwidget.IAppWidgetHost; +import com.android.internal.appwidget.IAppWidgetService; + +/** + * AppWidgetHost provides the interaction with the AppWidget service for apps, + * like the home screen, that want to embed AppWidgets in their UI. + */ +public class AppWidgetHost { + + static final int HANDLE_UPDATE = 1; + static final int HANDLE_PROVIDER_CHANGED = 2; + + static Object sServiceLock = new Object(); + static IAppWidgetService sService; + + Context mContext; + String mPackageName; + + class Callbacks extends IAppWidgetHost.Stub { + public void updateAppWidget(int appWidgetId, RemoteViews views) { + Message msg = mHandler.obtainMessage(HANDLE_UPDATE); + msg.arg1 = appWidgetId; + msg.obj = views; + msg.sendToTarget(); + } + + public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) { + Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED); + msg.arg1 = appWidgetId; + msg.obj = info; + msg.sendToTarget(); + } + } + + class UpdateHandler extends Handler { + public UpdateHandler(Looper looper) { + super(looper); + } + + public void handleMessage(Message msg) { + switch (msg.what) { + case HANDLE_UPDATE: { + updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj); + break; + } + case HANDLE_PROVIDER_CHANGED: { + onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj); + break; + } + } + } + } + + Handler mHandler; + + int mHostId; + Callbacks mCallbacks = new Callbacks(); + HashMap<Integer,AppWidgetHostView> mViews = new HashMap(); + + public AppWidgetHost(Context context, int hostId) { + mContext = context; + mHostId = hostId; + mHandler = new UpdateHandler(context.getMainLooper()); + synchronized (sServiceLock) { + if (sService == null) { + IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE); + sService = IAppWidgetService.Stub.asInterface(b); + } + } + } + + /** + * Start receiving onAppWidgetChanged calls for your AppWidgets. Call this when your activity + * becomes visible, i.e. from onStart() in your Activity. + */ + public void startListening() { + int[] updatedIds = null; + ArrayList<RemoteViews> updatedViews = new ArrayList(); + + try { + if (mPackageName == null) { + mPackageName = mContext.getPackageName(); + } + updatedIds = sService.startListening(mCallbacks, mPackageName, mHostId, updatedViews); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + + final int N = updatedIds.length; + for (int i=0; i<N; i++) { + updateAppWidgetView(updatedIds[i], updatedViews.get(i)); + } + } + + /** + * Stop receiving onAppWidgetChanged calls for your AppWidgets. Call this when your activity is + * no longer visible, i.e. from onStop() in your Activity. + */ + public void stopListening() { + try { + sService.stopListening(mHostId); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + /** + * Get a appWidgetId for a host in the calling process. + * + * @return a appWidgetId + */ + public int allocateAppWidgetId() { + try { + if (mPackageName == null) { + mPackageName = mContext.getPackageName(); + } + return sService.allocateAppWidgetId(mPackageName, mHostId); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + /** + * Stop listening to changes for this AppWidget. + */ + public void deleteAppWidgetId(int appWidgetId) { + synchronized (mViews) { + mViews.remove(appWidgetId); + try { + sService.deleteAppWidgetId(appWidgetId); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + } + + /** + * Remove all records about this host from the AppWidget manager. + * <ul> + * <li>Call this when initializing your database, as it might be because of a data wipe.</li> + * <li>Call this to have the AppWidget manager release all resources associated with your + * host. Any future calls about this host will cause the records to be re-allocated.</li> + * </ul> + */ + public void deleteHost() { + try { + sService.deleteHost(mHostId); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + /** + * Remove all records about all hosts for your package. + * <ul> + * <li>Call this when initializing your database, as it might be because of a data wipe.</li> + * <li>Call this to have the AppWidget manager release all resources associated with your + * host. Any future calls about this host will cause the records to be re-allocated.</li> + * </ul> + */ + public static void deleteAllHosts() { + try { + sService.deleteAllHosts(); + } + catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + } + + public final AppWidgetHostView createView(Context context, int appWidgetId, + AppWidgetProviderInfo appWidget) { + AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget); + view.setAppWidget(appWidgetId, appWidget); + synchronized (mViews) { + mViews.put(appWidgetId, view); + } + RemoteViews views = null; + try { + views = sService.getAppWidgetViews(appWidgetId); + } catch (RemoteException e) { + throw new RuntimeException("system server dead?", e); + } + view.updateAppWidget(views); + return view; + } + + /** + * Called to create the AppWidgetHostView. Override to return a custom subclass if you + * need it. {@more} + */ + protected AppWidgetHostView onCreateView(Context context, int appWidgetId, + AppWidgetProviderInfo appWidget) { + return new AppWidgetHostView(context); + } + + /** + * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk. + */ + protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) { + } + + void updateAppWidgetView(int appWidgetId, RemoteViews views) { + AppWidgetHostView v; + synchronized (mViews) { + v = mViews.get(appWidgetId); + } + if (v != null) { + v.updateAppWidget(views); + } + } +} + + |