19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2009 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Projectpackage android.appwidget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 197643f7e399a7d9004d77fe72f88e9947414860e4Svetoslavimport java.lang.ref.WeakReference; 20d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohenimport java.util.ArrayList; 21d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohenimport java.util.HashMap; 22d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen 238e1d299da27da534b508b1da51ebe351a689cefaSvetoslavimport android.annotation.NonNull; 248e1d299da27da534b508b1da51ebe351a689cefaSvetoslavimport android.annotation.Nullable; 25976e8bd2017d0263216c62111454438cc0f130e3Svetoslavimport android.app.Activity; 26976e8bd2017d0263216c62111454438cc0f130e3Svetoslavimport android.content.ActivityNotFoundException; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 28976e8bd2017d0263216c62111454438cc0f130e3Svetoslavimport android.content.IntentSender; 293ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohenimport android.os.Binder; 308e1d299da27da534b508b1da51ebe351a689cefaSvetoslavimport android.os.Bundle; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 35f229e4d3eb8f910c181f96416c6798f6f305a395Jim Millerimport android.os.Process; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 38d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohenimport android.util.DisplayMetrics; 39d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohenimport android.util.TypedValue; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.RemoteViews; 41e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Millerimport android.widget.RemoteViews.OnClickHandler; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Projectimport com.android.internal.appwidget.IAppWidgetHost; 44c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Projectimport com.android.internal.appwidget.IAppWidgetService; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 47c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * AppWidgetHost provides the interaction with the AppWidget service for apps, 48c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * like the home screen, that want to embed AppWidgets in their UI. 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 50c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Projectpublic class AppWidgetHost { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int HANDLE_UPDATE = 1; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int HANDLE_PROVIDER_CHANGED = 2; 547fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung static final int HANDLE_PROVIDERS_CHANGED = 3; 557fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung static final int HANDLE_VIEW_DATA_CHANGED = 4; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 57a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy final static Object sServiceLock = new Object(); 58c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project static IAppWidgetService sService; 59d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen private DisplayMetrics mDisplayMetrics; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 617a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung private String mContextOpPackageName; 627643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav private final Handler mHandler; 637643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav private final int mHostId; 647643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav private final Callbacks mCallbacks; 657643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav private final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<>(); 66a75a883fe9ea1790803148f0a561473073e3f264Jim Miller private OnClickHandler mOnClickHandler; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 687643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav static class Callbacks extends IAppWidgetHost.Stub { 697643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav private final WeakReference<Handler> mWeakHandler; 707643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav 717643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav public Callbacks(Handler handler) { 727643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav mWeakHandler = new WeakReference<>(handler); 737643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav } 747643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav 75976e8bd2017d0263216c62111454438cc0f130e3Svetoslav public void updateAppWidget(int appWidgetId, RemoteViews views) { 763ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen if (isLocalBinder() && views != null) { 773ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen views = views.clone(); 783ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen } 797643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav Handler handler = mWeakHandler.get(); 807643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav if (handler == null) { 817643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav return; 827643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav } 837643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav Message msg = handler.obtainMessage(HANDLE_UPDATE, appWidgetId, 0, views); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.sendToTarget(); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 87976e8bd2017d0263216c62111454438cc0f130e3Svetoslav public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) { 883ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen if (isLocalBinder() && info != null) { 893ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen info = info.clone(); 903ff2d867d46067132890a5a6ad68be8a4314d7f6Adam Cohen } 917643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav Handler handler = mWeakHandler.get(); 927643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav if (handler == null) { 937643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav return; 947643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav } 957643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav Message msg = handler.obtainMessage(HANDLE_PROVIDER_CHANGED, 96976e8bd2017d0263216c62111454438cc0f130e3Svetoslav appWidgetId, 0, info); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.sendToTarget(); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 99499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 100976e8bd2017d0263216c62111454438cc0f130e3Svetoslav public void providersChanged() { 1017643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav Handler handler = mWeakHandler.get(); 1027643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav if (handler == null) { 1037643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav return; 1047643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav } 1057643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav handler.obtainMessage(HANDLE_PROVIDERS_CHANGED).sendToTarget(); 1067fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung } 1077fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung 108976e8bd2017d0263216c62111454438cc0f130e3Svetoslav public void viewDataChanged(int appWidgetId, int viewId) { 1097643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav Handler handler = mWeakHandler.get(); 1107643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav if (handler == null) { 1117643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav return; 1127643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav } 1137643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav Message msg = handler.obtainMessage(HANDLE_VIEW_DATA_CHANGED, 114976e8bd2017d0263216c62111454438cc0f130e3Svetoslav appWidgetId, viewId); 115499cb9f516062b654952d282f211bee44c31a3c2Winson Chung msg.sendToTarget(); 116499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 1177643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav 1187643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav private static boolean isLocalBinder() { 1197643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav return Process.myPid() == Binder.getCallingPid(); 1207643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class UpdateHandler extends Handler { 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public UpdateHandler(Looper looper) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(looper); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 127e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case HANDLE_UPDATE: { 131976e8bd2017d0263216c62111454438cc0f130e3Svetoslav updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case HANDLE_PROVIDER_CHANGED: { 135c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1387fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung case HANDLE_PROVIDERS_CHANGED: { 139eeb4ff4d137a2ff2d25340c2b0396f2c3fd5068bWinson Chung onProvidersChanged(); 1407fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung break; 1417fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung } 142499cb9f516062b654952d282f211bee44c31a3c2Winson Chung case HANDLE_VIEW_DATA_CHANGED: { 143976e8bd2017d0263216c62111454438cc0f130e3Svetoslav viewDataChanged(msg.arg1, msg.arg2); 144499cb9f516062b654952d282f211bee44c31a3c2Winson Chung break; 145499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 149e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller 150c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public AppWidgetHost(Context context, int hostId) { 151e6d5545a539068dcfdd62d43ee0ef6789bb76a8eMichael Jurka this(context, hostId, null, context.getMainLooper()); 152e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller } 153e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller 154e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller /** 155e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller * @hide 156e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller */ 157f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller public AppWidgetHost(Context context, int hostId, OnClickHandler handler, Looper looper) { 1587a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung mContextOpPackageName = context.getOpPackageName(); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHostId = hostId; 160e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller mOnClickHandler = handler; 161f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller mHandler = new UpdateHandler(looper); 1627643f7e399a7d9004d77fe72f88e9947414860e4Svetoslav mCallbacks = new Callbacks(mHandler); 163d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen mDisplayMetrics = context.getResources().getDisplayMetrics(); 164f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller bindService(); 165f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller } 166f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller 16794022e8997084be458a1faf46e72efab1d59e973Amith Yamasani 168f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller private static void bindService() { 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (sServiceLock) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sService == null) { 171c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE); 172c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project sService = IAppWidgetService.Stub.asInterface(b); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 178c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Start receiving onAppWidgetChanged calls for your AppWidgets. Call this when your activity 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * becomes visible, i.e. from onStart() in your Activity. 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startListening() { 182a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy int[] updatedIds; 183a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>(); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1857a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung updatedIds = sService.startListening(mCallbacks, mContextOpPackageName, mHostId, 186976e8bd2017d0263216c62111454438cc0f130e3Svetoslav updatedViews); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project catch (RemoteException e) { 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("system server dead?", e); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = updatedIds.length; 193976e8bd2017d0263216c62111454438cc0f130e3Svetoslav for (int i = 0; i < N; i++) { 194976e8bd2017d0263216c62111454438cc0f130e3Svetoslav updateAppWidgetView(updatedIds[i], updatedViews.get(i)); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 199c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Stop receiving onAppWidgetChanged calls for your AppWidgets. Call this when your activity is 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * no longer visible, i.e. from onStop() in your Activity. 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopListening() { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2047a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung sService.stopListening(mContextOpPackageName, mHostId); 205c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani } 206c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani catch (RemoteException e) { 207c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani throw new RuntimeException("system server dead?", e); 208c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani } 209c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani 210a75a883fe9ea1790803148f0a561473073e3f264Jim Miller // This is here because keyguard needs it since it'll be switching users after this call. 211a75a883fe9ea1790803148f0a561473073e3f264Jim Miller // If it turns out other apps need to call this often, we should re-think how this works. 212c566b43d02596cba437e9a2723e9f989297cca72Amith Yamasani clearViews(); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 216c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Get a appWidgetId for a host in the calling process. 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 218c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * @return a appWidgetId 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 220c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public int allocateAppWidgetId() { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2227a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung return sService.allocateAppWidgetId(mContextOpPackageName, mHostId); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project catch (RemoteException e) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("system server dead?", e); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 230976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * Starts an app widget provider configure activity for result on behalf of the caller. 231976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * Use this method if the provider is in another profile as you are not allowed to start 2328e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * an activity in another profile. You can optionally provide a request code that is 2338e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * returned in {@link Activity#onActivityResult(int, int, android.content.Intent)} and 2348e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * an options bundle to be passed to the started activity. 2358e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * <p> 2368e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * Note that the provided app widget has to be bound for this method to work. 2378e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * </p> 238f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller * 239976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * @param activity The activity from which to start the configure one. 2408e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * @param appWidgetId The bound app widget whose provider's config activity to start. 241976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * @param requestCode Optional request code retuned with the result. 2428e1d299da27da534b508b1da51ebe351a689cefaSvetoslav * @param intentFlags Optional intent flags. 243976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * 244976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * @throws android.content.ActivityNotFoundException If the activity is not found. 245976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * 246976e8bd2017d0263216c62111454438cc0f130e3Svetoslav * @see AppWidgetProviderInfo#getProfile() 247f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller */ 2488e1d299da27da534b508b1da51ebe351a689cefaSvetoslav public final void startAppWidgetConfigureActivityForResult(@NonNull Activity activity, 2498e1d299da27da534b508b1da51ebe351a689cefaSvetoslav int appWidgetId, int intentFlags, int requestCode, @Nullable Bundle options) { 250f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller try { 251976e8bd2017d0263216c62111454438cc0f130e3Svetoslav IntentSender intentSender = sService.createAppWidgetConfigIntentSender( 2527a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung mContextOpPackageName, appWidgetId, intentFlags); 253976e8bd2017d0263216c62111454438cc0f130e3Svetoslav if (intentSender != null) { 2548e1d299da27da534b508b1da51ebe351a689cefaSvetoslav activity.startIntentSenderForResult(intentSender, requestCode, null, 0, 0, 0, 2558e1d299da27da534b508b1da51ebe351a689cefaSvetoslav options); 256976e8bd2017d0263216c62111454438cc0f130e3Svetoslav } else { 257976e8bd2017d0263216c62111454438cc0f130e3Svetoslav throw new ActivityNotFoundException(); 258f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller } 259976e8bd2017d0263216c62111454438cc0f130e3Svetoslav } catch (IntentSender.SendIntentException e) { 260976e8bd2017d0263216c62111454438cc0f130e3Svetoslav throw new ActivityNotFoundException(); 261f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller } catch (RemoteException e) { 262f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller throw new RuntimeException("system server dead?", e); 263f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller } 264f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller } 265f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller 26675b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka /** 26775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka * Gets a list of all the appWidgetIds that are bound to the current host 26875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka * 26975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka * @hide 27075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka */ 27175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka public int[] getAppWidgetIds() { 27275b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka try { 27375b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka if (sService == null) { 27475b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka bindService(); 27575b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka } 2767a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung return sService.getAppWidgetIdsForHost(mContextOpPackageName, mHostId); 27775b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka } catch (RemoteException e) { 27875b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka throw new RuntimeException("system server dead?", e); 27975b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka } 28075b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka } 28175b5cfb4a41030333820d072578a288d4ec9899cMichael Jurka 282f229e4d3eb8f910c181f96416c6798f6f305a395Jim Miller /** 283e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller * Stop listening to changes for this AppWidget. 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 285c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public void deleteAppWidgetId(int appWidgetId) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mViews) { 287c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project mViews.remove(appWidgetId); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2897a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung sService.deleteAppWidgetId(mContextOpPackageName, appWidgetId); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project catch (RemoteException e) { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("system server dead?", e); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 298c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Remove all records about this host from the AppWidget manager. 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Call this when initializing your database, as it might be because of a data wipe.</li> 301c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * <li>Call this to have the AppWidget manager release all resources associated with your 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * host. Any future calls about this host will cause the records to be re-allocated.</li> 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void deleteHost() { 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3077a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung sService.deleteHost(mContextOpPackageName, mHostId); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project catch (RemoteException e) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("system server dead?", e); 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove all records about all hosts for your package. 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>Call this when initializing your database, as it might be because of a data wipe.</li> 318c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * <li>Call this to have the AppWidget manager release all resources associated with your 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * host. Any future calls about this host will cause the records to be re-allocated.</li> 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void deleteAllHosts() { 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 324976e8bd2017d0263216c62111454438cc0f130e3Svetoslav sService.deleteAllHosts(); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project catch (RemoteException e) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("system server dead?", e); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 331ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy /** 332ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy * Create the AppWidgetHostView for the given widget. 333ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy * The AppWidgetHost retains a pointer to the newly-created View. 334ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy */ 335c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project public final AppWidgetHostView createView(Context context, int appWidgetId, 336c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project AppWidgetProviderInfo appWidget) { 3377a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget); 338e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller view.setOnClickHandler(mOnClickHandler); 339c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project view.setAppWidget(appWidgetId, appWidget); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mViews) { 341c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project mViews.put(appWidgetId, view); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 343a54755962ca7725d1e2b6cacbbaece6f1cbf5af4Romain Guy RemoteViews views; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3457a96f3c917e0001ee739b65da37b2fadec7d7765Winson Chung views = sService.getAppWidgetViews(mContextOpPackageName, appWidgetId); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException("system server dead?", e); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 349c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project view.updateAppWidget(views); 350e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return view; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 355c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Called to create the AppWidgetHostView. Override to return a custom subclass if you 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * need it. {@more} 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 358c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project protected AppWidgetHostView onCreateView(Context context, int appWidgetId, 359c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project AppWidgetProviderInfo appWidget) { 360e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller return new AppWidgetHostView(context, mOnClickHandler); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 362d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 364c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk. 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 366c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) { 367f140be6c3c21dd0f6d2214929e89d60de31d2c04Joe Onorato AppWidgetHostView v; 368d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen 369d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen // Convert complex to dp -- we are getting the AppWidgetProviderInfo from the 370e667a7add46a6389c64f2105bd33943cfe6a3fa4Jim Miller // AppWidgetService, which doesn't have our context, hence we need to do the 371d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen // conversion here. 372d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen appWidget.minWidth = 373d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen TypedValue.complexToDimensionPixelSize(appWidget.minWidth, mDisplayMetrics); 374d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen appWidget.minHeight = 375d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen TypedValue.complexToDimensionPixelSize(appWidget.minHeight, mDisplayMetrics); 3761bfaf561b7c09388311f1834f17e057739cf587aAdam Cohen appWidget.minResizeWidth = 3771bfaf561b7c09388311f1834f17e057739cf587aAdam Cohen TypedValue.complexToDimensionPixelSize(appWidget.minResizeWidth, mDisplayMetrics); 3781bfaf561b7c09388311f1834f17e057739cf587aAdam Cohen appWidget.minResizeHeight = 3791bfaf561b7c09388311f1834f17e057739cf587aAdam Cohen TypedValue.complexToDimensionPixelSize(appWidget.minResizeHeight, mDisplayMetrics); 380d2e20de64b6de8b6391c63e2f5b02ce7698bf4bfAdam Cohen 381f140be6c3c21dd0f6d2214929e89d60de31d2c04Joe Onorato synchronized (mViews) { 382f140be6c3c21dd0f6d2214929e89d60de31d2c04Joe Onorato v = mViews.get(appWidgetId); 383f140be6c3c21dd0f6d2214929e89d60de31d2c04Joe Onorato } 384f140be6c3c21dd0f6d2214929e89d60de31d2c04Joe Onorato if (v != null) { 385c27bb559805ae5cd06f7ecf575959c60c51a22aaJoe Onorato v.resetAppWidget(appWidget); 386f140be6c3c21dd0f6d2214929e89d60de31d2c04Joe Onorato } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3897fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung /** 3907fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung * Called when the set of available widgets changes (ie. widget containing packages 3917fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung * are added, updated or removed, or widget components are enabled or disabled.) 3927fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung */ 3937fbd28438c2322973c77f31f0721a24fe1c35039Winson Chung protected void onProvidersChanged() { 394a75a883fe9ea1790803148f0a561473073e3f264Jim Miller // Does nothing 395a75a883fe9ea1790803148f0a561473073e3f264Jim Miller } 396a75a883fe9ea1790803148f0a561473073e3f264Jim Miller 397976e8bd2017d0263216c62111454438cc0f130e3Svetoslav void updateAppWidgetView(int appWidgetId, RemoteViews views) { 398c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project AppWidgetHostView v; 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mViews) { 400c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project v = mViews.get(appWidgetId); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (v != null) { 403c27bb559805ae5cd06f7ecf575959c60c51a22aaJoe Onorato v.updateAppWidget(views); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 406499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 407976e8bd2017d0263216c62111454438cc0f130e3Svetoslav void viewDataChanged(int appWidgetId, int viewId) { 408499cb9f516062b654952d282f211bee44c31a3c2Winson Chung AppWidgetHostView v; 409499cb9f516062b654952d282f211bee44c31a3c2Winson Chung synchronized (mViews) { 410499cb9f516062b654952d282f211bee44c31a3c2Winson Chung v = mViews.get(appWidgetId); 411499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 412499cb9f516062b654952d282f211bee44c31a3c2Winson Chung if (v != null) { 4136394c0e52cf641d93f678fd052499aa952e3595dWinson Chung v.viewDataChanged(viewId); 414499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 415499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 416ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy 417ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy /** 418ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy * Clear the list of Views that have been created by this AppWidgetHost. 419ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy */ 420ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy protected void clearViews() { 421ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy mViews.clear(); 422ec84c3a189e4aa70aa6ea8ba712e5a4f260a153bPatrick Dubroy } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 426