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

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

Merge "Prevent multiple RemoteViewAdapters from being set for the same intent."

parents ec7291c9 9b3a2cf2
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -4365,6 +4365,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
     * @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
     */
    public void setRemoteViewsAdapter(Intent intent) {
        // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing
        // service handling the specified intent.
        Intent.FilterComparison fc = new Intent.FilterComparison(intent);
        if (mRemoteAdapter != null && fc.equals(mRemoteAdapter.getRemoteViewsServiceIntent())) {
            return;
        }

        // Otherwise, create a new RemoteViewsAdapter for binding
        mRemoteAdapter = new RemoteViewsAdapter(getContext(), intent, this);
    }

+9 −0
Original line number Diff line number Diff line
@@ -779,6 +779,15 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter>
     */
    @android.view.RemotableViewMethod
    public void setRemoteViewsAdapter(Intent intent) {
        // Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing
        // service handling the specified intent.
        Intent.FilterComparison fc = new Intent.FilterComparison(intent);
        if (mRemoteViewsAdapter != null &&
                fc.equals(mRemoteViewsAdapter.getRemoteViewsServiceIntent())) {
            return;
        }

        // Otherwise, create a new RemoteViewsAdapter for binding
        mRemoteViewsAdapter = new RemoteViewsAdapter(getContext(), intent, this);
    }

+7 −0
Original line number Diff line number Diff line
@@ -669,6 +669,9 @@ public class RemoteViewsAdapter extends BaseAdapter {
    public RemoteViewsAdapter(Context context, Intent intent, RemoteAdapterConnectionCallback callback) {
        mContext = context;
        mIntent = intent;
        if (mIntent == null) {
            throw new IllegalArgumentException("Non-null Intent must be specified.");
        }

        // initialize the worker thread
        mWorkerThread = new HandlerThread("RemoteViewsCache-loader");
@@ -689,6 +692,10 @@ public class RemoteViewsAdapter extends BaseAdapter {
        unbindService();
    }

    public Intent getRemoteViewsServiceIntent() {
        return mIntent;
    }

    public int getCount() {
        requestBindService();
        return mViewCache.getCount();
+16 −11
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ public abstract class RemoteViewsService extends Service {
    private static final String LOG_TAG = "RemoteViewsService";

    // multimap implementation for reference counting
    private HashMap<Intent, Pair<RemoteViewsFactory, Integer>> mRemoteViewFactories;
    private HashMap<Intent.FilterComparison, Pair<RemoteViewsFactory, Integer>> mRemoteViewFactories;
    private final Object mLock = new Object();

    /**
@@ -108,26 +108,28 @@ public abstract class RemoteViewsService extends Service {
    }

    public RemoteViewsService() {
        mRemoteViewFactories = new HashMap<Intent, Pair<RemoteViewsFactory, Integer>>();
        mRemoteViewFactories =
                new HashMap<Intent.FilterComparison, Pair<RemoteViewsFactory, Integer>>();
    }

    @Override
    public IBinder onBind(Intent intent) {
        synchronized (mLock) {
            // increment the reference count to the particular factory associated with this intent
            Intent.FilterComparison fc = new Intent.FilterComparison(intent);
            Pair<RemoteViewsFactory, Integer> factoryRef = null;
            RemoteViewsFactory factory = null;
            if (!mRemoteViewFactories.containsKey(intent)) {
            if (!mRemoteViewFactories.containsKey(fc)) {
                factory = onGetViewFactory(intent);
                factoryRef = new Pair<RemoteViewsFactory, Integer>(factory, 1);
                mRemoteViewFactories.put(intent, factoryRef);
                mRemoteViewFactories.put(fc, factoryRef);
                factory.onCreate();
            } else {
                Pair<RemoteViewsFactory, Integer> oldFactoryRef = mRemoteViewFactories.get(intent);
                Pair<RemoteViewsFactory, Integer> oldFactoryRef = mRemoteViewFactories.get(fc);
                factory = oldFactoryRef.first;
                int newRefCount = oldFactoryRef.second.intValue() + 1;
                factoryRef = new Pair<RemoteViewsFactory, Integer>(oldFactoryRef.first, newRefCount);
                mRemoteViewFactories.put(intent, factoryRef);
                mRemoteViewFactories.put(fc, factoryRef);
            }
            return new RemoteViewsFactoryAdapter(factory);
        }
@@ -136,16 +138,19 @@ public abstract class RemoteViewsService extends Service {
    @Override
    public boolean onUnbind(Intent intent) {
        synchronized (mLock) {
            if (mRemoteViewFactories.containsKey(intent)) {
            Intent.FilterComparison fc = new Intent.FilterComparison(intent);
            if (mRemoteViewFactories.containsKey(fc)) {
                // this alleviates the user's responsibility of having to clear all factories
                Pair<RemoteViewsFactory, Integer> oldFactoryRef = mRemoteViewFactories.get(intent);
                Pair<RemoteViewsFactory, Integer> oldFactoryRef =
                        mRemoteViewFactories.get(fc);
                int newRefCount = oldFactoryRef.second.intValue() - 1;
                if (newRefCount <= 0) {
                    oldFactoryRef.first.onDestroy();
                    mRemoteViewFactories.remove(intent);
                    mRemoteViewFactories.remove(fc);
                } else {
                    Pair<RemoteViewsFactory, Integer> factoryRef = new Pair<RemoteViewsFactory, Integer>(oldFactoryRef.first, newRefCount);
                    mRemoteViewFactories.put(intent, factoryRef);
                    Pair<RemoteViewsFactory, Integer> factoryRef =
                            new Pair<RemoteViewsFactory, Integer>(oldFactoryRef.first, newRefCount);
                    mRemoteViewFactories.put(fc, factoryRef);
                }
            }
        }