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

Commit f532a9e4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "The launcher to always listen to app widget" into tm-qpr-dev

parents f9b4040b bf3dde7e
Loading
Loading
Loading
Loading
+88 −36
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ public class AppWidgetHost {
    private final Handler mHandler;
    private final int mHostId;
    private final Callbacks mCallbacks;
    private final SparseArray<AppWidgetHostView> mViews = new SparseArray<>();
    private final SparseArray<AppWidgetHostListener> mListeners = new SparseArray<>();
    private InteractionHandler mInteractionHandler;

    static class Callbacks extends IAppWidgetHost.Stub {
@@ -171,6 +171,15 @@ public class AppWidgetHost {
        this(context, hostId, null, context.getMainLooper());
    }

    @Nullable
    private AppWidgetHostListener getListener(final int appWidgetId) {
        AppWidgetHostListener tempListener = null;
        synchronized (mListeners) {
            tempListener = mListeners.get(appWidgetId);
        }
        return tempListener;
    }

    /**
     * @hide
     */
@@ -210,11 +219,11 @@ public class AppWidgetHost {
            return;
        }
        final int[] idsToUpdate;
        synchronized (mViews) {
            int N = mViews.size();
            idsToUpdate = new int[N];
            for (int i = 0; i < N; i++) {
                idsToUpdate[i] = mViews.keyAt(i);
        synchronized (mListeners) {
            int n = mListeners.size();
            idsToUpdate = new int[n];
            for (int i = 0; i < n; i++) {
                idsToUpdate[i] = mListeners.keyAt(i);
            }
        }
        List<PendingHostUpdate> updates;
@@ -349,16 +358,13 @@ public class AppWidgetHost {
        if (sService == null) {
            return;
        }
        synchronized (mViews) {
            mViews.remove(appWidgetId);
        removeListener(appWidgetId);
        try {
            sService.deleteAppWidgetId(mContextOpPackageName, appWidgetId);
            }
            catch (RemoteException e) {
        } catch (RemoteException e) {
            throw new RuntimeException("system server dead?", e);
        }
    }
    }

    /**
     * Remove all records about this host from the AppWidget manager.
@@ -412,9 +418,7 @@ public class AppWidgetHost {
        AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget);
        view.setInteractionHandler(mInteractionHandler);
        view.setAppWidget(appWidgetId, appWidget);
        synchronized (mViews) {
            mViews.put(appWidgetId, view);
        }
        addListener(appWidgetId, view);
        RemoteViews views;
        try {
            views = sService.getAppWidgetViews(mContextOpPackageName, appWidgetId);
@@ -439,24 +443,52 @@ public class AppWidgetHost {
     * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk.
     */
    protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) {
        AppWidgetHostView v;
        AppWidgetHostListener v = getListener(appWidgetId);

        // Convert complex to dp -- we are getting the AppWidgetProviderInfo from the
        // AppWidgetService, which doesn't have our context, hence we need to do the
        // conversion here.
        appWidget.updateDimensions(mDisplayMetrics);
        synchronized (mViews) {
            v = mViews.get(appWidgetId);
        }
        if (v != null) {
            v.resetAppWidget(appWidget);
            v.onUpdateProviderInfo(appWidget);
        }
    }

    void dispatchOnAppWidgetRemoved(int appWidgetId) {
        synchronized (mViews) {
            mViews.remove(appWidgetId);
    /**
     * This interface specifies the actions to be performed on the app widget based on the calls
     * from the service
     *
     * @hide
     */
    public interface AppWidgetHostListener {

        /**
         * This function is called when the service want to reset the app widget provider info
         * @param appWidget The new app widget provider info
         *
         * @hide
         */
        void onUpdateProviderInfo(@Nullable AppWidgetProviderInfo appWidget);

        /**
         * This function is called when the RemoteViews of the app widget is updated
         * @param views The new RemoteViews to be set for the app widget
         *
         * @hide
         */
        void updateAppWidget(@Nullable RemoteViews views);

        /**
         * This function is called when the view ID is changed for the app widget
         * @param viewId The new view ID to be be set for the widget
         *
         * @hide
         */
        void onViewDataChanged(int viewId);
    }

    void dispatchOnAppWidgetRemoved(int appWidgetId) {
        removeListener(appWidgetId);
        onAppWidgetRemoved(appWidgetId);
    }

@@ -476,23 +508,43 @@ public class AppWidgetHost {
        // Does nothing
    }

    void updateAppWidgetView(int appWidgetId, RemoteViews views) {
        AppWidgetHostView v;
        synchronized (mViews) {
            v = mViews.get(appWidgetId);
    /**
     * Create an AppWidgetHostListener for the given widget.
     * The AppWidgetHost retains a pointer to the newly-created listener.
     * @param appWidgetId The ID of the app widget for which to add the listener
     * @param listener The listener interface that deals with actions towards the widget view
     *
     * @hide
     */
    public void addListener(int appWidgetId, @NonNull AppWidgetHostListener listener) {
        synchronized (mListeners) {
            mListeners.put(appWidgetId, listener);
        }
    }

    /**
     * Delete the listener for the given widget
     * @param appWidgetId The ID of the app widget for which the listener is to be deleted

     * @hide
     */
    public void removeListener(int appWidgetId) {
        synchronized (mListeners) {
            mListeners.remove(appWidgetId);
        }
    }

    void updateAppWidgetView(int appWidgetId, RemoteViews views) {
        AppWidgetHostListener v = getListener(appWidgetId);
        if (v != null) {
            v.updateAppWidget(views);
        }
    }

    void viewDataChanged(int appWidgetId, int viewId) {
        AppWidgetHostView v;
        synchronized (mViews) {
            v = mViews.get(appWidgetId);
        }
        AppWidgetHostListener v = getListener(appWidgetId);
        if (v != null) {
            v.viewDataChanged(viewId);
            v.onViewDataChanged(viewId);
        }
    }

@@ -500,8 +552,8 @@ public class AppWidgetHost {
     * Clear the list of Views that have been created by this AppWidgetHost.
     */
    protected void clearViews() {
        synchronized (mViews) {
            mViews.clear();
        synchronized (mListeners) {
            mListeners.clear();
        }
    }
}
+10 −3
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ import java.util.concurrent.Executor;
 * between updates, and will try recycling old views for each incoming
 * {@link RemoteViews}.
 */
public class AppWidgetHostView extends FrameLayout {
public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppWidgetHostListener {

    static final String TAG = "AppWidgetHostView";
    private static final String KEY_JAILED_ARRAY = "jail";
@@ -492,8 +492,11 @@ public class AppWidgetHostView extends FrameLayout {
    /**
     * Update the AppWidgetProviderInfo for this view, and reset it to the
     * initial layout.
     *
     * @hide
     */
    void resetAppWidget(AppWidgetProviderInfo info) {
    @Override
    public void onUpdateProviderInfo(@Nullable AppWidgetProviderInfo info) {
        setAppWidget(mAppWidgetId, info);
        mViewMode = VIEW_MODE_NOINIT;
        updateAppWidget(null);
@@ -503,6 +506,7 @@ public class AppWidgetHostView extends FrameLayout {
     * Process a set of {@link RemoteViews} coming in as an update from the
     * AppWidget provider. Will animate into these new views as needed
     */
    @Override
    public void updateAppWidget(RemoteViews remoteViews) {
        mLastInflatedRemoteViews = remoteViews;
        applyRemoteViews(remoteViews, true);
@@ -693,8 +697,11 @@ public class AppWidgetHostView extends FrameLayout {
    /**
     * Process data-changed notifications for the specified view in the specified
     * set of {@link RemoteViews} views.
     *
     * @hide
     */
    void viewDataChanged(int viewId) {
    @Override
    public void onViewDataChanged(int viewId) {
        View v = findViewById(viewId);
        if ((v != null) && (v instanceof AdapterView<?>)) {
            AdapterView<?> adapterView = (AdapterView<?>) v;