Merge "Updating AppWidgetHost to receive a callback when any appWidget has changed. (Bug 6602951)"
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user