Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58c35bbe authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Updating AppWidgetHost to receive a callback when any appWidget has changed. (Bug 6602951)"

parents 3400aa10 7fbd2843
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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();
  }
+19 −1
Original line number Diff line number Diff line
@@ -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) {
+1 −0
Original line number Diff line number Diff line
@@ -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);
}
+48 −8
Original line number Diff line number Diff line
@@ -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;
            }
        }
    }
}