summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/appwidget/AppWidgetHost.java20
-rw-r--r--core/java/com/android/internal/appwidget/IAppWidgetHost.aidl1
-rw-r--r--services/java/com/android/server/AppWidgetServiceImpl.java56
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;
+ }
+ }
}
}