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

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

Merge "Add Context.bindService with executor parameter"

parents 63e82d75 58a57667
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -9655,8 +9655,9 @@ package android.content {
  public abstract class Context {
    ctor public Context();
    method public boolean bindIsolatedService(@RequiresPermission @NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String);
    method public boolean bindIsolatedService(@RequiresPermission @NonNull android.content.Intent, int, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
    method public abstract boolean bindService(@RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, int);
    method public boolean bindService(@RequiresPermission @NonNull android.content.Intent, int, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
    method @CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)") public abstract int checkCallingOrSelfPermission(@NonNull String);
    method @CheckResult(suggest="#enforceCallingOrSelfUriPermission(Uri,int,String)") public abstract int checkCallingOrSelfUriPermission(android.net.Uri, int);
    method @CheckResult(suggest="#enforceCallingPermission(String,String)") public abstract int checkCallingPermission(@NonNull String);
+34 −15
Original line number Diff line number Diff line
@@ -145,8 +145,15 @@ class ReceiverRestrictedContext extends ContextWrapper {
    }

    @Override
    public boolean bindIsolatedService(Intent service, ServiceConnection conn, int flags,
            String instanceName) {
    public boolean bindService(
          Intent service, int flags, Executor executor, ServiceConnection conn) {
        throw new ReceiverCallNotAllowedException(
            "BroadcastReceiver components are not allowed to bind to services");
    }

    @Override
    public boolean bindIsolatedService(Intent service, int flags, String instanceName,
            Executor executor, ServiceConnection conn) {
        throw new ReceiverCallNotAllowedException(
            "BroadcastReceiver components are not allowed to bind to services");
    }
@@ -1639,28 +1646,34 @@ class ContextImpl extends Context {
    }

    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
                getUser());
    }

    @Override
    public boolean bindService(
            Intent service, int flags, Executor executor, ServiceConnection conn) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), getUser());
        return bindServiceCommon(service, conn, flags, null, null, executor, getUser());
    }

    @Override
    public boolean bindIsolatedService(Intent service, ServiceConnection conn,
            int flags, String instanceName) {
    public boolean bindIsolatedService(Intent service, int flags, String instanceName,
            Executor executor, ServiceConnection conn) {
        warnIfCallingFromSystemProcess();
        if (instanceName == null) {
            throw new NullPointerException("null instanceName");
        }
        return bindServiceCommon(service, conn, flags, instanceName, mMainThread.getHandler(),
                getUser());
        return bindServiceCommon(service, conn, flags, instanceName, null, executor, getUser());
    }

    /** @hide */
    @Override
    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
            UserHandle user) {
        return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), user);
        return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null, user);
    }

    /** @hide */
@@ -1670,7 +1683,7 @@ class ContextImpl extends Context {
        if (handler == null) {
            throw new IllegalArgumentException("handler must not be null.");
        }
        return bindServiceCommon(service, conn, flags, null, handler, user);
        return bindServiceCommon(service, conn, flags, null, handler, null, user);
    }

    /** @hide */
@@ -1693,15 +1706,21 @@ class ContextImpl extends Context {
    }

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            String instanceName, Handler
            handler, UserHandle user) {
            String instanceName, Handler handler, Executor executor, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
        IServiceConnection sd;
        if (conn == null) {
            throw new IllegalArgumentException("connection is null");
        }
        if (handler != null && executor != null) {
            throw new IllegalArgumentException("Handler and Executor both supplied");
        }
        if (mPackageInfo != null) {
            if (executor != null) {
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
            } else {
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
            }
        } else {
            throw new RuntimeException("Not supported in system context");
        }
+44 −5
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;

final class IntentReceiverLeaked extends AndroidRuntimeException {
    @UnsupportedAppUsage
@@ -1651,6 +1652,16 @@ public final class LoadedApk {
    @UnsupportedAppUsage
    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        return getServiceDispatcherCommon(c, context, handler, null, flags);
    }

    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Executor executor, int flags) {
        return getServiceDispatcherCommon(c, context, null, executor, flags);
    }

    private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
            Context context, Handler handler, Executor executor, int flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
@@ -1659,7 +1670,11 @@ public final class LoadedApk {
                sd = map.get(c);
            }
            if (sd == null) {
                if (executor != null) {
                    sd = new ServiceDispatcher(c, context, executor, flags);
                } else {
                    sd = new ServiceDispatcher(c, context, handler, flags);
                }
                if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
                if (map == null) {
                    map = new ArrayMap<>();
@@ -1667,7 +1682,7 @@ public final class LoadedApk {
                }
                map.put(c, sd);
            } else {
                sd.validate(context, handler);
                sd.validate(context, handler, executor);
            }
            return sd.getIServiceConnection();
        }
@@ -1744,6 +1759,7 @@ public final class LoadedApk {
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        private final Context mContext;
        private final Handler mActivityThread;
        private final Executor mActivityExecutor;
        private final ServiceConnectionLeaked mLocation;
        private final int mFlags;

@@ -1783,12 +1799,25 @@ public final class LoadedApk {
            mConnection = conn;
            mContext = context;
            mActivityThread = activityThread;
            mActivityExecutor = null;
            mLocation = new ServiceConnectionLeaked(null);
            mLocation.fillInStackTrace();
            mFlags = flags;
        }

        void validate(Context context, Handler activityThread) {
        ServiceDispatcher(ServiceConnection conn,
                Context context, Executor activityExecutor, int flags) {
            mIServiceConnection = new InnerConnection(this);
            mConnection = conn;
            mContext = context;
            mActivityThread = null;
            mActivityExecutor = activityExecutor;
            mLocation = new ServiceConnectionLeaked(null);
            mLocation.fillInStackTrace();
            mFlags = flags;
        }

        void validate(Context context, Handler activityThread, Executor activityExecutor) {
            if (mContext != context) {
                throw new RuntimeException(
                    "ServiceConnection " + mConnection +
@@ -1801,6 +1830,12 @@ public final class LoadedApk {
                    " registered with differing handler (was " +
                    mActivityThread + " now " + activityThread + ")");
            }
            if (mActivityExecutor != activityExecutor) {
                throw new RuntimeException(
                    "ServiceConnection " + mConnection +
                    " registered with differing executor (was " +
                    mActivityExecutor + " now " + activityExecutor + ")");
            }
        }

        void doForget() {
@@ -1840,7 +1875,9 @@ public final class LoadedApk {
        }

        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityThread != null) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
            } else if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
@@ -1848,7 +1885,9 @@ public final class LoadedApk {
        }

        public void death(ComponentName name, IBinder service) {
            if (mActivityThread != null) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 1, false));
            } else if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 1, false));
            } else {
                doDeath(name, service);
+19 −4
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.content;

import android.annotation.AttrRes;
import android.annotation.CallbackExecutor;
import android.annotation.CheckResult;
import android.annotation.ColorInt;
import android.annotation.ColorRes;
@@ -2966,6 +2967,18 @@ public abstract class Context {
    public abstract boolean bindService(@RequiresPermission Intent service,
            @NonNull ServiceConnection conn, @BindServiceFlags int flags);

    /**
     * Same as {@link #bindService(Intent, ServiceConnection, int)} with executor to control
     * ServiceConnection callbacks.
     * @param executor Callbacks on ServiceConnection will be called on executor. Must use same
     *      instance for the same instance of ServiceConnection.
     */
    public boolean bindService(@RequiresPermission @NonNull Intent service,
            @BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor,
            @NonNull ServiceConnection conn) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Variation of {@link #bindService} that, in the specific case of isolated
     * services, allows the caller to generate multiple instances of a service
@@ -2973,20 +2986,22 @@ public abstract class Context {
     *
     * @param service Identifies the service to connect to.  The Intent must
     *      specify an explicit component name.
     * @param conn Receives information as the service is started and stopped.
     *      This must be a valid ServiceConnection object; it must not be null.
     * @param flags Operation options for the binding as per {@link #bindService}.
     * @param instanceName Unique identifier for the service instance.  Each unique
     *      name here will result in a different service instance being created.
     * @return Returns success of binding as per {@link #bindService}.
     * @param executor Callbacks on ServiceConnection will be called on executor.
     *      Must use same instance for the same instance of ServiceConnection.
     * @param conn Receives information as the service is started and stopped.
     *      This must be a valid ServiceConnection object; it must not be null.
     *
     * @throws SecurityException If the caller does not have permission to access the service
     *
     * @see #bindService
     */
    public boolean bindIsolatedService(@RequiresPermission @NonNull Intent service,
            @NonNull ServiceConnection conn, @BindServiceFlags int flags,
            @NonNull String instanceName) {
            @BindServiceFlags int flags, @NonNull String instanceName,
            @NonNull @CallbackExecutor Executor executor, @NonNull ServiceConnection conn) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

+9 −3
Original line number Diff line number Diff line
@@ -706,9 +706,15 @@ public class ContextWrapper extends Context {
    }

    @Override
    public boolean bindIsolatedService(Intent service, ServiceConnection conn,
            int flags, String instanceName) {
        return mBase.bindIsolatedService(service, conn, flags, instanceName);
    public boolean bindService(Intent service, int flags, Executor executor,
            ServiceConnection conn) {
        return mBase.bindService(service, flags, executor, conn);
    }

    @Override
    public boolean bindIsolatedService(Intent service, int flags, String instanceName,
            Executor executor, ServiceConnection conn) {
        return mBase.bindIsolatedService(service, flags, instanceName, executor, conn);
    }

    /** @hide */
Loading