diff options
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/appwidget/AppWidgetHost.java | 20 | ||||
| -rw-r--r-- | core/java/com/android/internal/appwidget/IAppWidgetHost.aidl | 1 | ||||
| -rw-r--r-- | services/java/com/android/server/AppWidgetServiceImpl.java | 56 |
4 files changed, 69 insertions, 9 deletions
diff --git a/api/current.txt b/api/current.txt index 4bcd982..6b46baa 100644 --- a/api/current.txt +++ b/api/current.txt @@ -4336,6 +4336,7 @@ package android.appwidget { method public void deleteHost(); method protected android.appwidget.AppWidgetHostView onCreateView(android.content.Context, int, android.appwidget.AppWidgetProviderInfo); method protected void onProviderChanged(int, android.appwidget.AppWidgetProviderInfo); + method protected void onProvidersChanged(); method public void startListening(); method public void stopListening(); } diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 08bc0ac..2c19c0c 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -41,7 +41,8 @@ public class AppWidgetHost { static final int HANDLE_UPDATE = 1; static final int HANDLE_PROVIDER_CHANGED = 2; - static final int HANDLE_VIEW_DATA_CHANGED = 3; + static final int HANDLE_PROVIDERS_CHANGED = 3; + static final int HANDLE_VIEW_DATA_CHANGED = 4; final static Object sServiceLock = new Object(); static IAppWidgetService sService; @@ -65,6 +66,11 @@ public class AppWidgetHost { msg.sendToTarget(); } + public void providersChanged() { + Message msg = mHandler.obtainMessage(HANDLE_PROVIDERS_CHANGED); + msg.sendToTarget(); + } + public void viewDataChanged(int appWidgetId, int viewId) { Message msg = mHandler.obtainMessage(HANDLE_VIEW_DATA_CHANGED); msg.arg1 = appWidgetId; @@ -88,6 +94,10 @@ public class AppWidgetHost { onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj); break; } + case HANDLE_PROVIDERS_CHANGED: { + onProvidersChanged(); + break; + } case HANDLE_VIEW_DATA_CHANGED: { viewDataChanged(msg.arg1, msg.arg2); break; @@ -274,6 +284,14 @@ public class AppWidgetHost { } } + /** + * Called when the set of available widgets changes (ie. widget containing packages + * are added, updated or removed, or widget components are enabled or disabled.) + */ + protected void onProvidersChanged() { + // Do nothing + } + void updateAppWidgetView(int appWidgetId, RemoteViews views) { AppWidgetHostView v; synchronized (mViews) { diff --git a/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl index 216d985..78b4466 100644 --- a/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl +++ b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl @@ -24,6 +24,7 @@ import android.widget.RemoteViews; oneway interface IAppWidgetHost { void updateAppWidget(int appWidgetId, in RemoteViews views); void providerChanged(int appWidgetId, in AppWidgetProviderInfo info); + void providersChanged(); void viewDataChanged(int appWidgetId, int viewId); } diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index df2e1aa..7bc6a88 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -223,6 +223,7 @@ class AppWidgetServiceImpl { final String action = intent.getAction(); boolean added = false; boolean changed = false; + boolean providersModified = false; String pkgList[] = null; if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); @@ -254,12 +255,12 @@ class AppWidgetServiceImpl { || (extras != null && extras.getBoolean(Intent.EXTRA_REPLACING, false))) { for (String pkgName : pkgList) { // The package was just upgraded - updateProvidersForPackageLocked(pkgName); + providersModified |= updateProvidersForPackageLocked(pkgName); } } else { // The package was just added for (String pkgName : pkgList) { - addProvidersForPackageLocked(pkgName); + providersModified |= addProvidersForPackageLocked(pkgName); } } saveStateLocked(); @@ -272,12 +273,20 @@ class AppWidgetServiceImpl { synchronized (mAppWidgetIds) { ensureStateLoadedLocked(); for (String pkgName : pkgList) { - removeProvidersForPackageLocked(pkgName); + providersModified |= removeProvidersForPackageLocked(pkgName); saveStateLocked(); } } } } + + if (providersModified) { + // If the set of providers has been modified, notify each active AppWidgetHost + synchronized (mAppWidgetIds) { + ensureStateLoadedLocked(); + notifyHostsForProvidersChangedLocked(); + } + } } private void dumpProvider(Provider p, int index, PrintWriter pw) { @@ -1637,7 +1646,8 @@ class AppWidgetServiceImpl { getSettingsFile(mUserId).delete(); } - void addProvidersForPackageLocked(String pkgName) { + boolean addProvidersForPackageLocked(String pkgName) { + boolean providersAdded = false; Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setPackage(pkgName); List<ResolveInfo> broadcastReceivers; @@ -1647,7 +1657,7 @@ class AppWidgetServiceImpl { PackageManager.GET_META_DATA, mUserId); } catch (RemoteException re) { // Shouldn't happen, local call - return; + return false; } final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size(); for (int i = 0; i < N; i++) { @@ -1658,11 +1668,15 @@ class AppWidgetServiceImpl { } if (pkgName.equals(ai.packageName)) { addProviderLocked(ri); + providersAdded = true; } } + + return providersAdded; } - void updateProvidersForPackageLocked(String pkgName) { + boolean updateProvidersForPackageLocked(String pkgName) { + boolean providersUpdated = false; HashSet<String> keep = new HashSet<String>(); Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setPackage(pkgName); @@ -1673,7 +1687,7 @@ class AppWidgetServiceImpl { PackageManager.GET_META_DATA, mUserId); } catch (RemoteException re) { // Shouldn't happen, local call - return; + return false; } // add the missing ones and collect which ones to keep @@ -1690,6 +1704,7 @@ class AppWidgetServiceImpl { if (p == null) { if (addProviderLocked(ri)) { keep.add(ai.name); + providersUpdated = true; } } else { Provider parsed = parseProviderInfoXml(component, ri); @@ -1724,6 +1739,7 @@ class AppWidgetServiceImpl { } // Now that we've told the host, push out an update. sendUpdateIntentLocked(p, appWidgetIds); + providersUpdated = true; } } } @@ -1737,16 +1753,21 @@ class AppWidgetServiceImpl { if (pkgName.equals(p.info.provider.getPackageName()) && !keep.contains(p.info.provider.getClassName())) { removeProviderLocked(i, p); + providersUpdated = true; } } + + return providersUpdated; } - void removeProvidersForPackageLocked(String pkgName) { + boolean removeProvidersForPackageLocked(String pkgName) { + boolean providersRemoved = false; int N = mInstalledProviders.size(); for (int i = N - 1; i >= 0; i--) { Provider p = mInstalledProviders.get(i); if (pkgName.equals(p.info.provider.getPackageName())) { removeProviderLocked(i, p); + providersRemoved = true; } } @@ -1761,5 +1782,24 @@ class AppWidgetServiceImpl { deleteHostLocked(host); } } + + return providersRemoved; + } + + void notifyHostsForProvidersChangedLocked() { + final int N = mHosts.size(); + for (int i = N - 1; i >= 0; i--) { + Host host = mHosts.get(i); + try { + if (host.callbacks != null) { + host.callbacks.providersChanged(); + } + } catch (RemoteException ex) { + // It failed; remove the callback. No need to prune because + // we know that this host is still referenced by this + // instance. + host.callbacks = null; + } + } } } |
