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

Commit 57c7aa90 authored by Hui Yu's avatar Hui Yu
Browse files

Extend bindService flags from 32 bits to 64 bits.

bindService flags used to a be a 32 bits integer type, we are running
out of 32 bits flags. Now use an object BindServiceFlags which is a 64
bits long type (can be changed to other data structure/type in the
future) for the bindService flags.

Bug: 191785864
Test: atest cts/tests/app/src/android/app/cts/ServiceTest.java#testBindServiceFlags
atest cts/tests/app/src/android/app/cts/ServiceTest.java
atest cts/tests/app/src/android/app/cts/ActivityManagerProcessStateTest.java
atest cts/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java
Change-Id: Ib120869c5d90ff37f551d760205a7b65f8b56020

Change-Id: Ib5bec28b7c9aa55874f46210fdbe24596bab40d6
parent 1a936d17
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -7783,7 +7783,8 @@ package android.app.admin {
    method public void addPersistentPreferredActivity(@NonNull android.content.ComponentName, android.content.IntentFilter, @NonNull android.content.ComponentName);
    method public void addUserRestriction(@NonNull android.content.ComponentName, String);
    method public void addUserRestrictionGlobally(@NonNull String);
    method public boolean bindDeviceAdminServiceAsUser(@NonNull android.content.ComponentName, android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull android.os.UserHandle);
    method public boolean bindDeviceAdminServiceAsUser(@NonNull android.content.ComponentName, @NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull android.os.UserHandle);
    method public boolean bindDeviceAdminServiceAsUser(@NonNull android.content.ComponentName, @NonNull android.content.Intent, @NonNull android.content.ServiceConnection, @NonNull android.content.Context.BindServiceFlags, @NonNull android.os.UserHandle);
    method public boolean canAdminGrantSensorsPermissions();
    method public boolean canUsbDataSignalingBeDisabled();
    method public void clearApplicationUserData(@NonNull android.content.ComponentName, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.app.admin.DevicePolicyManager.OnClearApplicationUserDataListener);
@@ -10211,9 +10212,13 @@ package android.content {
  public abstract class Context {
    ctor public Context();
    method public boolean bindIsolatedService(@NonNull @RequiresPermission 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 bindIsolatedService(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.Context.BindServiceFlags, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
    method public abstract boolean bindService(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, int);
    method public boolean bindService(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, @NonNull android.content.Context.BindServiceFlags);
    method public boolean bindService(@NonNull @RequiresPermission android.content.Intent, int, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
    method public boolean bindService(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.Context.BindServiceFlags, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
    method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL", android.Manifest.permission.INTERACT_ACROSS_PROFILES}, conditional=true) public boolean bindServiceAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull android.os.UserHandle);
    method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", "android.permission.INTERACT_ACROSS_USERS_FULL", android.Manifest.permission.INTERACT_ACROSS_PROFILES}, conditional=true) public boolean bindServiceAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, @NonNull android.content.Context.BindServiceFlags, @NonNull android.os.UserHandle);
    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 @NonNull public int[] checkCallingOrSelfUriPermissions(@NonNull java.util.List<android.net.Uri>, int);
@@ -10374,6 +10379,7 @@ package android.content {
    field public static final int BIND_AUTO_CREATE = 1; // 0x1
    field public static final int BIND_DEBUG_UNBIND = 2; // 0x2
    field public static final int BIND_EXTERNAL_SERVICE = -2147483648; // 0x80000000
    field public static final long BIND_EXTERNAL_SERVICE_LONG = -9223372036854775808L; // 0x8000000000000000L
    field public static final int BIND_IMPORTANT = 64; // 0x40
    field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000
    field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
@@ -10478,6 +10484,11 @@ package android.content {
    field @UiContext public static final String WINDOW_SERVICE = "window";
  }
  public static final class Context.BindServiceFlags {
    method public long getValue();
    method @NonNull public static android.content.Context.BindServiceFlags of(long);
  }
  public final class ContextParams {
    method @Nullable public String getAttributionTag();
    method @Nullable public android.content.AttributionSource getNextAttributionSource();
+55 −8
Original line number Diff line number Diff line
@@ -1983,14 +1983,30 @@ class ContextImpl extends Context {
    @Override
    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
                getUser());
        return bindServiceCommon(service, conn, Integer.toUnsignedLong(flags), null,
                mMainThread.getHandler(), null, getUser());
    }

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

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

    @Override
    public boolean bindService(Intent service, @NonNull BindServiceFlags flags, Executor executor,
            ServiceConnection conn) {
        return bindServiceCommon(service, conn, flags.getValue(), null, null, executor,
                getUser());
    }

    @Override
@@ -2000,13 +2016,33 @@ class ContextImpl extends Context {
        if (instanceName == null) {
            throw new NullPointerException("null instanceName");
        }
        return bindServiceCommon(service, conn, flags, instanceName, null, executor, getUser());
        return bindServiceCommon(service, conn, Integer.toUnsignedLong(flags), instanceName, null, executor,
                getUser());
    }

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

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

    @Override
    public boolean bindServiceAsUser(Intent service, ServiceConnection conn,
            @NonNull BindServiceFlags flags, UserHandle user) {
        return bindServiceCommon(service, conn, flags.getValue(), null,
                mMainThread.getHandler(), null, user);
    }

    /** @hide */
@@ -2016,13 +2052,24 @@ class ContextImpl extends Context {
        if (handler == null) {
            throw new IllegalArgumentException("handler must not be null.");
        }
        return bindServiceCommon(service, conn, flags, null, handler, null, user);
        return bindServiceCommon(service, conn, Integer.toUnsignedLong(flags), null, handler,
                null, user);
    }

    @Override
    public boolean bindServiceAsUser(Intent service, ServiceConnection conn,
            @NonNull BindServiceFlags flags, Handler handler, UserHandle user) {
        if (handler == null) {
            throw new IllegalArgumentException("handler must not be null.");
        }
        return bindServiceCommon(service, conn, flags.getValue(), null, handler,
                null, user);
    }

    /** @hide */
    @Override
    public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
            int flags) {
            long flags) {
        return mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    }

@@ -2045,7 +2092,7 @@ class ContextImpl extends Context {
        return mMainThread.getHandler();
    }

    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
    private boolean bindServiceCommon(Intent service, ServiceConnection conn, long flags,
            String instanceName, Handler handler, Executor executor, UserHandle user) {
        // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser and
        // ActivityManagerLocal.bindSdkSandboxService
+2 −2
Original line number Diff line number Diff line
@@ -172,10 +172,10 @@ interface IActivityManager {
    // Currently keeping old bindService because it is on the greylist
    @UnsupportedAppUsage
    int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
            in String resolvedType, in IServiceConnection connection, int flags,
            in String resolvedType, in IServiceConnection connection, long flags,
            in String callingPackage, int userId);
    int bindServiceInstance(in IApplicationThread caller, in IBinder token, in Intent service,
            in String resolvedType, in IServiceConnection connection, int flags,
            in String resolvedType, in IServiceConnection connection, long flags,
            in String instanceName, in String callingPackage, int userId);
    void updateServiceGroup(in IServiceConnection connection, int group, int importance);
    @UnsupportedAppUsage
+7 −7
Original line number Diff line number Diff line
@@ -1898,17 +1898,17 @@ public final class LoadedApk {

    @UnsupportedAppUsage
    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
            Context context, Handler handler, long flags) {
        return getServiceDispatcherCommon(c, context, handler, null, flags);
    }

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

    private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
            Context context, Handler handler, Executor executor, int flags) {
            Context context, Handler handler, Executor executor, long flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
@@ -2008,7 +2008,7 @@ public final class LoadedApk {
        private final Handler mActivityThread;
        private final Executor mActivityExecutor;
        private final ServiceConnectionLeaked mLocation;
        private final int mFlags;
        private final long mFlags;

        private RuntimeException mUnbindLocation;

@@ -2041,7 +2041,7 @@ public final class LoadedApk {

        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
        ServiceDispatcher(ServiceConnection conn,
                Context context, Handler activityThread, int flags) {
                Context context, Handler activityThread, long flags) {
            mIServiceConnection = new InnerConnection(this);
            mConnection = conn;
            mContext = context;
@@ -2053,7 +2053,7 @@ public final class LoadedApk {
        }

        ServiceDispatcher(ServiceConnection conn,
                Context context, Executor activityExecutor, int flags) {
                Context context, Executor activityExecutor, long flags) {
            mIServiceConnection = new InnerConnection(this);
            mConnection = conn;
            mContext = context;
@@ -2109,7 +2109,7 @@ public final class LoadedApk {
            return mIServiceConnection;
        }

        int getFlags() {
        long getFlags() {
            return mFlags;
        }

+154 −9
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.ColorRes;
import android.annotation.DisplayContext;
import android.annotation.DrawableRes;
import android.annotation.IntDef;
import android.annotation.LongDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.PermissionMethod;
@@ -267,7 +268,10 @@ public abstract class Context {
     */
    public static final int MODE_NO_LOCALIZED_COLLATORS = 0x0010;

    /** @hide */
    /**
     * Flags used for bindService(int) APIs. Note, we now have long BIND_* flags.
     * @hide
     */
    @IntDef(flag = true, prefix = { "BIND_" }, value = {
            BIND_AUTO_CREATE,
            BIND_DEBUG_UNBIND,
@@ -280,10 +284,74 @@ public abstract class Context {
            BIND_NOT_PERCEPTIBLE,
            BIND_ALLOW_ACTIVITY_STARTS,
            BIND_INCLUDE_CAPABILITIES,
            BIND_SHARED_ISOLATED_PROCESS
            BIND_SHARED_ISOLATED_PROCESS,
            BIND_EXTERNAL_SERVICE
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BindServiceFlags {}
    public @interface BindServiceFlagsBits {}

    /**
     * Long version of BIND_* flags used for bindService(BindServiceFlags) APIs.
     * @hide
     */
    @LongDef(flag = true, prefix = { "BIND_" }, value = {
            BIND_AUTO_CREATE,
            BIND_DEBUG_UNBIND,
            BIND_NOT_FOREGROUND,
            BIND_ABOVE_CLIENT,
            BIND_ALLOW_OOM_MANAGEMENT,
            BIND_WAIVE_PRIORITY,
            BIND_IMPORTANT,
            BIND_ADJUST_WITH_ACTIVITY,
            BIND_NOT_PERCEPTIBLE,
            BIND_ALLOW_ACTIVITY_STARTS,
            BIND_INCLUDE_CAPABILITIES,
            BIND_SHARED_ISOLATED_PROCESS,
            // Intentionally not included, because it'd cause sign-extension.
            // This would allow Android Studio to show a warning, if someone tries to use
            // BIND_EXTERNAL_SERVICE BindServiceFlags.
            BIND_EXTERNAL_SERVICE_LONG
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BindServiceFlagsLongBits {}

    /**
     * Specific flags used for bindService() call, which encapsulates a 64 bits long integer.
     * Call {@link BindServiceFlags#of(long)} to obtain an
     * object of {@code BindServiceFlags}.
     */
    public final static class BindServiceFlags {
        private final long mValue;

        private BindServiceFlags(@BindServiceFlagsLongBits long value) {
            mValue = value;
        }

        /**
         * @return Return flags in 64 bits long integer.
         */
        public long getValue() {
            return mValue;
        }

        /**
         * Build {@link BindServiceFlags} from BIND_* FLAGS.
         *
         * Note, {@link #BIND_EXTERNAL_SERVICE} is not supported in this method, because
         * it has the highest integer bit set and cause wrong flags to be set. Use
         * {@link #BIND_EXTERNAL_SERVICE_LONG} instead.
         */
        @NonNull
        public static BindServiceFlags of(@BindServiceFlagsLongBits long value) {
            if ((value & Integer.toUnsignedLong(BIND_EXTERNAL_SERVICE)) != 0){
                throw new IllegalArgumentException(
                        "BIND_EXTERNAL_SERVICE is deprecated. Use BIND_EXTERNAL_SERVICE_LONG"
                                + " instead");
            }

            return new BindServiceFlags(value);
        }
    }

    /**
     * Flag for {@link #bindService}: automatically create the service as long
@@ -595,9 +663,20 @@ public abstract class Context {
     * The purpose of this flag is to allow applications to provide services that are attributed
     * to the app using the service, rather than the application providing the service.
     * </p>
     *
     * <em>This flag is NOT compatible with {@link BindServiceFlags}. If you need to use
     * {@link BindServiceFlags}, you must use {@link #BIND_EXTERNAL_SERVICE_LONG} instead.
     */
    public static final int BIND_EXTERNAL_SERVICE = 0x80000000;


    /**
     * Works in the same way as {@link #BIND_EXTERNAL_SERVICE}, but it's defined as a (@code long)
     * value that is compatible to {@link BindServiceFlags}.
     */
    public static final long BIND_EXTERNAL_SERVICE_LONG = 0x8000_0000_0000_0000L;


    /**
     * These bind flags reduce the strength of the binding such that we shouldn't
     * consider it as pulling the process up to the level of the one that is bound to it.
@@ -3648,6 +3727,9 @@ public abstract class Context {
     * {@link #registerReceiver}, since the lifetime of this BroadcastReceiver
     * is tied to another object (the one that registered it).</p>
     *
     * <p>This method only accepts a int type flag, to pass in a long type flag, call
     * {@link #bindService(Intent, ServiceConnection, BindServiceFlags)} instead.</p>
     *
     * @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.
@@ -3681,14 +3763,26 @@ public abstract class Context {
     * @see #unbindService
     * @see #startService
     */
    public abstract boolean bindService(@RequiresPermission Intent service,
            @NonNull ServiceConnection conn, @BindServiceFlags int flags);
    public abstract boolean bindService(@RequiresPermission @NonNull Intent service,
            @NonNull ServiceConnection conn, int flags);

    /**
     * See {@link #bindService(Intent, ServiceConnection, int)}
     * Call {@link BindServiceFlags#of(long)} to obtain a BindServiceFlags object.
     */
    public boolean bindService(@RequiresPermission @NonNull Intent service,
            @NonNull ServiceConnection conn, @NonNull BindServiceFlags flags) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Same as {@link #bindService(Intent, ServiceConnection, int)
     * bindService(Intent, ServiceConnection, int)} with executor to control ServiceConnection
     * callbacks.
     *
     * <p>This method only accepts a 32 bits flag, to pass in a 64 bits flag, call
     * {@link #bindService(Intent, BindServiceFlags, Executor, ServiceConnection)} instead.</p>
     *
     * @param executor Callbacks on ServiceConnection will be called on executor. Must use same
     *      instance for the same instance of ServiceConnection.
     *
@@ -3697,7 +3791,17 @@ public abstract class Context {
     *      bindService(Intent, ServiceConnection, int)}.
     */
    public boolean bindService(@RequiresPermission @NonNull Intent service,
            @BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor,
            @BindServiceFlagsBits int flags, @NonNull @CallbackExecutor Executor executor,
            @NonNull ServiceConnection conn) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * See {@link #bindService(Intent, int, Executor, ServiceConnection)}
     * Call {@link BindServiceFlags#of(long)} to obtain a BindServiceFlags object.
     */
    public boolean bindService(@RequiresPermission @NonNull Intent service,
            @NonNull BindServiceFlags flags, @NonNull @CallbackExecutor Executor executor,
            @NonNull ServiceConnection conn) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }
@@ -3735,7 +3839,17 @@ public abstract class Context {
     * @see android.R.attr#isolatedProcess
     */
    public boolean bindIsolatedService(@RequiresPermission @NonNull Intent service,
            @BindServiceFlags int flags, @NonNull String instanceName,
            int flags, @NonNull String instanceName,
            @NonNull @CallbackExecutor Executor executor, @NonNull ServiceConnection conn) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * See {@link #bindIsolatedService(Intent, int, String, Executor,ServiceConnection)}
     * Call {@link BindServiceFlags#of(long)} to obtain a BindServiceFlags object.
     */
    public boolean bindIsolatedService(@RequiresPermission @NonNull Intent service,
            @NonNull BindServiceFlags flags, @NonNull String instanceName,
            @NonNull @CallbackExecutor Executor executor, @NonNull ServiceConnection conn) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }
@@ -3785,10 +3899,25 @@ public abstract class Context {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * See {@link #bindServiceAsUser(Intent, ServiceConnection, int, UserHandle)}
     * Call {@link BindServiceFlags#of(long)} to obtain a BindServiceFlags object.
     */
    @SuppressWarnings("unused")
    @RequiresPermission(anyOf = {
            android.Manifest.permission.INTERACT_ACROSS_USERS,
            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
            android.Manifest.permission.INTERACT_ACROSS_PROFILES
    }, conditional = true)
    public boolean bindServiceAsUser(
            @NonNull @RequiresPermission Intent service, @NonNull ServiceConnection conn,
            @NonNull BindServiceFlags flags, @NonNull UserHandle user) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * Same as {@link #bindServiceAsUser(Intent, ServiceConnection, int, UserHandle)}, but with an
     * explicit non-null Handler to run the ServiceConnection callbacks on.
     *
     * @hide
     */
    @RequiresPermission(anyOf = {
@@ -3802,6 +3931,22 @@ public abstract class Context {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * See {@link #bindServiceAsUser(Intent, ServiceConnection, int, Handler, UserHandle)}
     * Call {@link BindServiceFlags#of(long)} to obtain a BindServiceFlags object.
     * @hide
     */
    @RequiresPermission(anyOf = {
            android.Manifest.permission.INTERACT_ACROSS_USERS,
            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
            android.Manifest.permission.INTERACT_ACROSS_PROFILES
    }, conditional = true)
    @UnsupportedAppUsage(trackingBug = 136728678)
    public boolean bindServiceAsUser(@NonNull Intent service, @NonNull ServiceConnection conn,
            @NonNull BindServiceFlags flags, @NonNull Handler handler, @NonNull UserHandle user) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * For a service previously bound with {@link #bindService} or a related method, change
     * how the system manages that service's process in relation to other processes.  This
@@ -7566,7 +7711,7 @@ public abstract class Context {
     */
    @Nullable
    public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
            int flags) {
            long flags) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

Loading