summaryrefslogtreecommitdiffstats
path: root/core/java/android/appwidget/AppWidgetHost.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/appwidget/AppWidgetHost.java')
-rw-r--r--core/java/android/appwidget/AppWidgetHost.java248
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);
+ }
+ }
+}
+
+