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

Commit 27b4d94a authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Implement naming of isolated service bindings.

This allows clients to run multiple instances of the same
manifest service declaration.  It only works for isolated
services, to avoid too much abuse temptation.  This is part
of the "Chrome site isolation" work, to allow chrome to have
many more render processes running and help it manage them.

Bug: 111434506
Test: atest CtsAppTestCases:ServiceTest
Change-Id: I22e65758678a07075ed32ed6463082ddf846d3a4
parent 59805434
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -9475,6 +9475,7 @@ package android.content {
  public abstract class Context {
    ctor public Context();
    method public abstract boolean bindIsolatedService(android.content.Intent, android.content.ServiceConnection, int, java.lang.String);
    method public abstract boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
    method public abstract int checkCallingOrSelfPermission(java.lang.String);
    method public abstract int checkCallingOrSelfUriPermission(android.net.Uri, int);
@@ -9686,6 +9687,7 @@ package android.content {
  public class ContextWrapper extends android.content.Context {
    ctor public ContextWrapper(android.content.Context);
    method protected void attachBaseContext(android.content.Context);
    method public boolean bindIsolatedService(android.content.Intent, android.content.ServiceConnection, int, java.lang.String);
    method public boolean bindService(android.content.Intent, android.content.ServiceConnection, int);
    method public int checkCallingOrSelfPermission(java.lang.String);
    method public int checkCallingOrSelfUriPermission(android.net.Uri, int);
+25 −6
Original line number Diff line number Diff line
@@ -140,6 +140,13 @@ class ReceiverRestrictedContext extends ContextWrapper {
        throw new ReceiverCallNotAllowedException(
                "BroadcastReceiver components are not allowed to bind to services");
    }

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

/**
@@ -1630,14 +1637,25 @@ class ContextImpl extends Context {
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
        return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), getUser());
    }

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

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

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

    /** @hide */
@@ -1669,7 +1687,8 @@ class ContextImpl extends Context {
        return mMainThread.getHandler();
    }

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            String instanceName, Handler
            handler, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
        IServiceConnection sd;
@@ -1690,10 +1709,10 @@ class ContextImpl extends Context {
                flags |= BIND_WAIVE_PRIORITY;
            }
            service.prepareToLeaveProcess(this);
            int res = ActivityManager.getService().bindService(
            int res = ActivityManager.getService().bindIsolatedService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
                sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
            if (res < 0) {
                throw new SecurityException(
                        "Not allowed to bind to service " + service);
+4 −0
Original line number Diff line number Diff line
@@ -133,9 +133,13 @@ interface IActivityManager {
            in String resolvedType, boolean requireForeground, in String callingPackage, int userId);
    int stopService(in IApplicationThread caller, in Intent service,
            in String resolvedType, int userId);
    // Currently keeping old bindService because it is on the greylist
    int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
            in String resolvedType, in IServiceConnection connection, int flags,
            in String callingPackage, int userId);
    int bindIsolatedService(in IApplicationThread caller, in IBinder token, in Intent service,
            in String resolvedType, in IServiceConnection connection, int flags,
            in String instanceName, in String callingPackage, int userId);
    boolean unbindService(in IServiceConnection connection);
    void publishService(in IBinder token, in Intent intent, in IBinder service);
    void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent);
+31 −3
Original line number Diff line number Diff line
@@ -2906,8 +2906,9 @@ public abstract class Context {
     * @param flags Operation options for the binding.  May be 0,
     *          {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND},
     *          {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
     *          {@link #BIND_ALLOW_OOM_MANAGEMENT}, or
     *          {@link #BIND_WAIVE_PRIORITY}.
     *          {@link #BIND_ALLOW_OOM_MANAGEMENT}, {@link #BIND_WAIVE_PRIORITY}.
     *          {@link #BIND_IMPORTANT}, or
     *          {@link #BIND_ADJUST_WITH_ACTIVITY}.
     * @return {@code true} if the system is in the process of bringing up a
     *         service that your client has permission to bind to; {@code false}
     *         if the system couldn't find the service or if your client doesn't
@@ -2923,10 +2924,37 @@ public abstract class Context {
     * @see #BIND_AUTO_CREATE
     * @see #BIND_DEBUG_UNBIND
     * @see #BIND_NOT_FOREGROUND
     * @see #BIND_ABOVE_CLIENT
     * @see #BIND_ALLOW_OOM_MANAGEMENT
     * @see #BIND_WAIVE_PRIORITY
     * @see #BIND_IMPORTANT
     * @see #BIND_ADJUST_WITH_ACTIVITY
     */
    public abstract boolean bindService(@RequiresPermission Intent service,
            @NonNull ServiceConnection conn, @BindServiceFlags int flags);

    /**
     * Variation of {@link #bindService} that, in the specific case of isolated
     * services, allows the caller to generate multiple instances of a service
     * from a single component declaration.
     *
     * @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}.
     *
     * @throws SecurityException If the caller does not have permission to access the service
     *
     * @see #bindService
     */
    public abstract boolean bindIsolatedService(@RequiresPermission Intent service,
            @NonNull ServiceConnection conn, @BindServiceFlags int flags,
            @NonNull String instanceName);

    /**
     * Same as {@link #bindService(Intent, ServiceConnection, int)}, but with an explicit userHandle
     * argument for use by system server and other multi-user aware code.
@@ -2941,7 +2969,7 @@ public abstract class Context {
    }

    /**
     * Same as {@link #bindService(Intent, ServiceConnection, int, UserHandle)}, but with an
     * Same as {@link #bindServiceAsUser(Intent, ServiceConnection, int, UserHandle)}, but with an
     * explicit non-null Handler to run the ServiceConnection callbacks on.
     *
     * @hide
+6 −0
Original line number Diff line number Diff line
@@ -705,6 +705,12 @@ public class ContextWrapper extends Context {
        return mBase.bindService(service, conn, flags);
    }

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

    /** @hide */
    @Override
    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
Loading