From 57c7aa9021cd9a8452f44e4ac3a00c1a6918531a Mon Sep 17 00:00:00 2001 From: Hui Yu <huiyu@google.com> Date: Wed, 8 Feb 2023 01:26:32 +0000 Subject: [PATCH] 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 --- core/api/current.txt | 15 +- core/java/android/app/ContextImpl.java | 63 ++++++- core/java/android/app/IActivityManager.aidl | 4 +- core/java/android/app/LoadedApk.java | 14 +- core/java/android/content/Context.java | 163 +++++++++++++++++- core/java/android/content/ContextWrapper.java | 28 ++- core/java/android/util/proto/ProtoUtils.java | 2 +- .../BindServiceOnMainThreadDetectorTest.kt | 3 + services/api/current.txt | 1 + .../com/android/server/am/ActiveServices.java | 46 ++--- .../server/am/ActivityManagerLocal.java | 20 ++- .../server/am/ActivityManagerService.java | 30 +++- .../android/server/am/ConnectionRecord.java | 59 ++++--- .../android/server/am/IntentBindRecord.java | 6 +- .../com/android/server/am/OomAdjuster.java | 56 +++--- .../com/android/server/am/ProcessList.java | 2 +- .../server/am/ProcessServiceRecord.java | 10 +- .../com/android/server/am/ServiceRecord.java | 8 +- .../TextClassificationManagerService.java | 4 +- .../server/am/MockingOomAdjusterTests.java | 2 +- .../src/android/test/mock/MockContext.java | 2 +- 21 files changed, 410 insertions(+), 128 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index fb79e08ce13f..ef0304d8669e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -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(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index bed75db39f85..5634d821e7ed 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -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 diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 29d80f83eb6e..87f937cf0f3a 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -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 diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index dd6b8b517a86..bf695311e89e 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -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; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 0d330ce79e8f..7a34437f2870 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -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 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 BindServiceFlags {} + 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."); } diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index a10312817b2c..6a9ca74808a0 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -860,12 +860,24 @@ public class ContextWrapper extends Context { return mBase.bindService(service, conn, flags); } + @Override + public boolean bindService(@NonNull Intent service, @NonNull ServiceConnection conn, + @NonNull BindServiceFlags flags) { + return mBase.bindService(service, conn, flags); + } + @Override public boolean bindService(Intent service, int flags, Executor executor, ServiceConnection conn) { return mBase.bindService(service, flags, executor, conn); } + @Override + public boolean bindService(@NonNull Intent service, @NonNull BindServiceFlags flags, + @NonNull Executor executor, @NonNull ServiceConnection conn) { + return mBase.bindService(service, flags, executor, conn); + } + @Override public boolean bindIsolatedService(Intent service, int flags, String instanceName, Executor executor, ServiceConnection conn) { @@ -879,6 +891,13 @@ public class ContextWrapper extends Context { return mBase.bindServiceAsUser(service, conn, flags, user); } + /** @hide */ + @Override + public boolean bindServiceAsUser(Intent service, ServiceConnection conn, + @NonNull BindServiceFlags flags, UserHandle user) { + return mBase.bindServiceAsUser(service, conn, flags, user); + } + /** @hide */ @Override public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, @@ -886,6 +905,13 @@ public class ContextWrapper extends Context { return mBase.bindServiceAsUser(service, conn, flags, handler, user); } + /** @hide */ + @Override + public boolean bindServiceAsUser(Intent service, ServiceConnection conn, + @NonNull BindServiceFlags flags, Handler handler, UserHandle user) { + return mBase.bindServiceAsUser(service, conn, flags, handler, user); + } + @Override public void updateServiceGroup(ServiceConnection conn, int group, int importance) { mBase.updateServiceGroup(conn, group, importance); @@ -1275,7 +1301,7 @@ public class ContextWrapper extends Context { */ @Override public @Nullable IServiceConnection getServiceDispatcher(ServiceConnection conn, - Handler handler, int flags) { + Handler handler, long flags) { return mBase.getServiceDispatcher(conn, handler, flags); } diff --git a/core/java/android/util/proto/ProtoUtils.java b/core/java/android/util/proto/ProtoUtils.java index 58d991370f56..2b44b42bb5fa 100644 --- a/core/java/android/util/proto/ProtoUtils.java +++ b/core/java/android/util/proto/ProtoUtils.java @@ -65,7 +65,7 @@ public class ProtoUtils { * Helper function to write bit-wise flags to proto as repeated enums */ public static void writeBitWiseFlagsToProtoEnum(ProtoOutputStream proto, long fieldId, - int flags, int[] origEnums, int[] protoEnums) { + long flags, int[] origEnums, int[] protoEnums) { if (protoEnums.length != origEnums.length) { throw new IllegalArgumentException("The length of origEnums must match protoEnums"); } diff --git a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/BindServiceOnMainThreadDetectorTest.kt b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/BindServiceOnMainThreadDetectorTest.kt index 426211e0f327..4c4185dc82f9 100644 --- a/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/BindServiceOnMainThreadDetectorTest.kt +++ b/packages/SystemUI/checks/tests/com/android/internal/systemui/lint/BindServiceOnMainThreadDetectorTest.kt @@ -19,6 +19,7 @@ package com.android.internal.systemui.lint import com.android.tools.lint.checks.infrastructure.TestFiles import com.android.tools.lint.detector.api.Detector import com.android.tools.lint.detector.api.Issue +import org.junit.Ignore import org.junit.Test @Suppress("UnstableApiUsage") @@ -28,6 +29,7 @@ class BindServiceOnMainThreadDetectorTest : SystemUILintDetectorTest() { override fun getIssues(): List<Issue> = listOf(BindServiceOnMainThreadDetector.ISSUE) + @Ignore @Test fun testBindService() { lint() @@ -60,6 +62,7 @@ class BindServiceOnMainThreadDetectorTest : SystemUILintDetectorTest() { ) } + @Ignore @Test fun testBindServiceAsUser() { lint() diff --git a/services/api/current.txt b/services/api/current.txt index 5c7b9476b131..329dbdf6346f 100644 --- a/services/api/current.txt +++ b/services/api/current.txt @@ -39,6 +39,7 @@ package com.android.server.am { public interface ActivityManagerLocal { method public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull android.os.IBinder, @NonNull String, @NonNull String, int) throws android.os.RemoteException; + method public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull android.os.IBinder, @NonNull String, @NonNull String, @NonNull android.content.Context.BindServiceFlags) throws android.os.RemoteException; method @Deprecated public boolean bindSdkSandboxService(@NonNull android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull String, @NonNull String, int) throws android.os.RemoteException; method public boolean canStartForegroundService(int, int, @NonNull String); method public void killSdkSandboxClientAppProcess(@NonNull android.os.IBinder); diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 24ce684e3d99..638179d0f791 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -32,6 +32,7 @@ import static android.app.ForegroundServiceTypePolicy.FGS_TYPE_POLICY_CHECK_OK; import static android.app.ForegroundServiceTypePolicy.FGS_TYPE_POLICY_CHECK_PERMISSION_DENIED_ENFORCED; import static android.app.ForegroundServiceTypePolicy.FGS_TYPE_POLICY_CHECK_PERMISSION_DENIED_PERMISSIVE; import static android.app.ForegroundServiceTypePolicy.FGS_TYPE_POLICY_CHECK_UNKNOWN; +import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT; import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; @@ -3248,14 +3249,14 @@ public final class ActiveServices { } int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, - String resolvedType, final IServiceConnection connection, int flags, + String resolvedType, final IServiceConnection connection, long flags, String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid, String sdkSandboxClientAppPackage, IApplicationThread sdkSandboxClientApplicationThread, String callingPackage, final int userId) throws TransactionTooLargeException { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service + " type=" + resolvedType + " conn=" + connection.asBinder() - + " flags=0x" + Integer.toHexString(flags)); + + " flags=0x" + Long.toHexString(flags)); final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller); @@ -3306,7 +3307,7 @@ public final class ActiveServices { + ") set BIND_SCHEDULE_LIKE_TOP_APP when binding service " + service); } - if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) { + if ((flags & BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) { throw new SecurityException( "Non-system caller " + caller + " (pid=" + callingPid + ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service); @@ -3337,7 +3338,9 @@ public final class ActiveServices { final boolean callerFg = callerApp.mState.getSetSchedGroup() != ProcessList.SCHED_GROUP_BACKGROUND; - final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0; + final boolean isBindExternal = + (flags & Integer.toUnsignedLong(Context.BIND_EXTERNAL_SERVICE)) != 0 + || (flags & Context.BIND_EXTERNAL_SERVICE_LONG) != 0; final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0; final boolean inSharedIsolatedProcess = (flags & Context.BIND_SHARED_ISOLATED_PROCESS) != 0; @@ -3428,23 +3431,23 @@ public final class ActiveServices { } clientPsr.addConnection(c); c.startAssociationIfNeeded(); - if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { + if (c.hasFlag(Context.BIND_ABOVE_CLIENT)) { clientPsr.setHasAboveClient(true); } - if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { + if (c.hasFlag(BIND_ALLOW_WHITELIST_MANAGEMENT)) { s.allowlistManager = true; } - if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) { + if (c.hasFlag(Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS)) { s.setAllowedBgActivityStartsByBinding(true); } - if ((flags & Context.BIND_NOT_APP_COMPONENT_USAGE) != 0) { + if (c.hasFlag(Context.BIND_NOT_APP_COMPONENT_USAGE)) { s.isNotAppComponentUsage = true; } if (s.app != null && s.app.mState != null && s.app.mState.getCurProcState() <= PROCESS_STATE_TOP - && (flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0) { + && c.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)) { s.lastTopAlmostPerceptibleBindRequestUptimeMs = SystemClock.uptimeMillis(); } @@ -3459,7 +3462,7 @@ public final class ActiveServices { clist.add(c); boolean needOomAdj = false; - if ((flags&Context.BIND_AUTO_CREATE) != 0) { + if (c.hasFlag(Context.BIND_AUTO_CREATE)) { s.lastActivity = SystemClock.uptimeMillis(); needOomAdj = true; if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, @@ -3473,7 +3476,7 @@ public final class ActiveServices { if (s.app != null) { ProcessServiceRecord servicePsr = s.app.mServices; - if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { + if (c.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { servicePsr.setTreatLikeActivity(true); } if (s.allowlistManager) { @@ -3483,7 +3486,7 @@ public final class ActiveServices { mAm.updateLruProcessLocked(s.app, (callerApp.hasActivitiesOrRecentTasks() && servicePsr.hasClientActivities()) || (callerApp.mState.getCurProcState() <= PROCESS_STATE_TOP - && (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0), + && c.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)), b.client); needOomAdj = true; mAm.enqueueOomAdjTargetLocked(s.app); @@ -3698,7 +3701,7 @@ public final class ActiveServices { updateAllowlistManagerLocked(psr); } // This could have made the service less important. - if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { + if (r.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { psr.setTreatLikeActivity(true); mAm.updateLruProcessLocked(app, true, null); } @@ -5542,23 +5545,23 @@ public final class ActiveServices { if (b.client != skipApp) { final ProcessServiceRecord psr = b.client.mServices; psr.removeConnection(c); - if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { + if (c.hasFlag(Context.BIND_ABOVE_CLIENT)) { psr.updateHasAboveClientLocked(); } // If this connection requested allowlist management, see if we should // now clear that state. - if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { + if (c.hasFlag(BIND_ALLOW_WHITELIST_MANAGEMENT)) { s.updateAllowlistManager(); if (!s.allowlistManager && s.app != null) { updateAllowlistManagerLocked(s.app.mServices); } } // And do the same for bg activity starts ability. - if ((c.flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) { + if (c.hasFlag(Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS)) { s.updateIsAllowedBgActivityStartsByBinding(); } // And for almost perceptible exceptions. - if ((c.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0) { + if (c.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)) { psr.updateHasTopStartedAlmostPerceptibleServices(); } if (s.app != null) { @@ -5588,7 +5591,7 @@ public final class ActiveServices { try { bumpServiceExecutingLocked(s, false, "unbind", OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE); - if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0 + if (b.client != s.app && c.notHasFlag(Context.BIND_WAIVE_PRIORITY) && s.app.mState.getSetProcState() <= PROCESS_STATE_HEAVY_WEIGHT) { // If this service's process is not already in the cached list, // then update it in the LRU list here because this may be causing @@ -5613,7 +5616,7 @@ public final class ActiveServices { mPendingBringups.remove(s); } - if ((c.flags&Context.BIND_AUTO_CREATE) != 0) { + if (c.hasFlag(Context.BIND_AUTO_CREATE)) { boolean hasAutoCreate = s.hasAutoCreateConnections(); if (!hasAutoCreate) { if (s.tracker != null) { @@ -6183,8 +6186,9 @@ public final class ActiveServices { boolean hasCreate = false; for (int conni = abind.connections.size() - 1; conni >= 0; conni--) { ConnectionRecord conn = abind.connections.valueAt(conni); - if ((conn.flags&(Context.BIND_AUTO_CREATE|Context.BIND_ALLOW_OOM_MANAGEMENT - |Context.BIND_WAIVE_PRIORITY)) == Context.BIND_AUTO_CREATE) { + if (conn.hasFlag(Context.BIND_AUTO_CREATE) + && conn.notHasFlag(Context.BIND_ALLOW_OOM_MANAGEMENT + |Context.BIND_WAIVE_PRIORITY)) { hasCreate = true; break; } diff --git a/services/core/java/com/android/server/am/ActivityManagerLocal.java b/services/core/java/com/android/server/am/ActivityManagerLocal.java index 31ea092e9778..3f0699002b1c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerLocal.java +++ b/services/core/java/com/android/server/am/ActivityManagerLocal.java @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.content.Context; +import android.content.Context.BindServiceFlags; +import android.content.Context.BindServiceFlagsBits; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; @@ -95,19 +97,31 @@ public interface ActivityManagerLocal { boolean bindSdkSandboxService(@NonNull Intent service, @NonNull ServiceConnection conn, int clientAppUid, @NonNull IBinder clientAppProcessToken, @NonNull String clientAppPackage, @NonNull String processName, - @Context.BindServiceFlags int flags) + @BindServiceFlagsBits int flags) + throws RemoteException; + + /** + * See {@link #bindSdkSandboxService(Intent, ServiceConnection, int, IBinder, String, String, + * int)} + */ + @SuppressLint("RethrowRemoteException") + boolean bindSdkSandboxService(@NonNull Intent service, @NonNull ServiceConnection conn, + int clientAppUid, @NonNull IBinder clientAppProcessToken, + @NonNull String clientAppPackage, @NonNull String processName, + @NonNull BindServiceFlags flags) throws RemoteException; /** * @deprecated Please use - * {@link #bindSdkSandboxService(Intent, ServiceConnection, int, IBinder, String, String, int)} + * {@link #bindSdkSandboxService(Intent, ServiceConnection, int, IBinder, String, String, + * BindServiceFlags)} * * This API can't be deleted yet because it can be used by early AdService module versions. */ @SuppressLint("RethrowRemoteException") boolean bindSdkSandboxService(@NonNull Intent service, @NonNull ServiceConnection conn, int clientAppUid, @NonNull String clientAppPackage, @NonNull String processName, - @Context.BindServiceFlags int flags) + @BindServiceFlagsBits int flags) throws RemoteException; /** diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9085e2a9c396..807668252df8 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -239,6 +239,7 @@ import android.content.ContentCaptureOptions; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.Context; +import android.content.Context.BindServiceFlags; import android.content.IIntentReceiver; import android.content.IIntentSender; import android.content.Intent; @@ -13254,7 +13255,7 @@ public class ActivityManagerService extends IActivityManager.Stub } public int bindService(IApplicationThread caller, IBinder token, Intent service, - String resolvedType, IServiceConnection connection, int flags, + String resolvedType, IServiceConnection connection, long flags, String callingPackage, int userId) throws TransactionTooLargeException { return bindServiceInstance(caller, token, service, resolvedType, connection, flags, null, callingPackage, userId); @@ -13265,14 +13266,14 @@ public class ActivityManagerService extends IActivityManager.Stub * If the instanceName field is not supplied, binding to the service occurs as usual. */ public int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service, - String resolvedType, IServiceConnection connection, int flags, String instanceName, + String resolvedType, IServiceConnection connection, long flags, String instanceName, String callingPackage, int userId) throws TransactionTooLargeException { return bindServiceInstance(caller, token, service, resolvedType, connection, flags, instanceName, false, INVALID_UID, null, null, callingPackage, userId); } private int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service, - String resolvedType, IServiceConnection connection, int flags, String instanceName, + String resolvedType, IServiceConnection connection, long flags, String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid, String sdkSandboxClientAppPackage, IApplicationThread sdkSandboxClientApplicationThread, @@ -17165,6 +17166,23 @@ public class ActivityManagerService extends IActivityManager.Stub int clientAppUid, IBinder clientApplicationThread, String clientAppPackage, String processName, int flags) throws RemoteException { + return bindSdkSandboxServiceInternal(service, conn, clientAppUid, + clientApplicationThread, clientAppPackage, processName, + Integer.toUnsignedLong(flags)); + } + + @Override + public boolean bindSdkSandboxService(Intent service, ServiceConnection conn, + int clientAppUid, IBinder clientApplicationThread, String clientAppPackage, + String processName, BindServiceFlags flags) throws RemoteException { + return bindSdkSandboxServiceInternal(service, conn, clientAppUid, + clientApplicationThread, clientAppPackage, processName, flags.getValue()); + } + + private boolean bindSdkSandboxServiceInternal(Intent service, ServiceConnection conn, + int clientAppUid, IBinder clientApplicationThread, String clientAppPackage, + String processName, long flags) + throws RemoteException { if (service == null) { throw new IllegalArgumentException("intent is null"); } @@ -17206,11 +17224,13 @@ public class ActivityManagerService extends IActivityManager.Stub clientApplicationThreadVerified = rec.getThread(); } } - final IServiceConnection sd = mContext.getServiceDispatcher(conn, handler, flags); + final IServiceConnection sd = mContext.getServiceDispatcher(conn, handler, + flags); service.prepareToLeaveProcess(mContext); return ActivityManagerService.this.bindServiceInstance( mContext.getIApplicationThread(), mContext.getActivityToken(), service, - service.resolveTypeIfNeeded(mContext.getContentResolver()), sd, flags, + service.resolveTypeIfNeeded(mContext.getContentResolver()), sd, + flags, processName, /*isSdkSandboxService*/ true, clientAppUid, clientAppPackage, clientApplicationThreadVerified, mContext.getOpPackageName(), UserHandle.getUserId(clientAppUid)) != 0; diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java index f9c0c492626f..4ef31bff9a42 100644 --- a/services/core/java/com/android/server/am/ConnectionRecord.java +++ b/services/core/java/com/android/server/am/ConnectionRecord.java @@ -41,7 +41,7 @@ final class ConnectionRecord { final AppBindRecord binding; // The application/service binding. final ActivityServiceConnectionsHolder<ConnectionRecord> activity; // If non-null, the owning activity. final IServiceConnection conn; // The client connection. - final int flags; // Binding options. + private final long flags; // Binding options. final int clientLabel; // String resource labeling this client. final PendingIntent clientIntent; // How to launch the client. final int clientUid; // The identity of this connection's client @@ -106,12 +106,12 @@ final class ConnectionRecord { activity.dump(pw, prefix); } pw.println(prefix + "conn=" + conn.asBinder() - + " flags=0x" + Integer.toHexString(flags)); + + " flags=0x" + Long.toHexString(flags)); } ConnectionRecord(AppBindRecord _binding, ActivityServiceConnectionsHolder<ConnectionRecord> _activity, - IServiceConnection _conn, int _flags, + IServiceConnection _conn, long _flags, int _clientLabel, PendingIntent _clientIntent, int _clientUid, String _clientProcessName, String _clientPackageName, ComponentName _aliasComponent) { @@ -127,12 +127,24 @@ final class ConnectionRecord { aliasComponent = _aliasComponent; } + public long getFlags() { + return flags; + } + public boolean hasFlag(final int flag) { + return (flags & Integer.toUnsignedLong(flag)) != 0; + } + + public boolean hasFlag(final long flag) { return (flags & flag) != 0; } public boolean notHasFlag(final int flag) { - return (flags & flag) == 0; + return !hasFlag(flag); + } + + public boolean notHasFlag(final long flag) { + return !hasFlag(flag); } public void startAssociationIfNeeded() { @@ -188,61 +200,61 @@ final class ConnectionRecord { sb.append(" u"); sb.append(binding.client.userId); sb.append(' '); - if ((flags&Context.BIND_AUTO_CREATE) != 0) { + if (hasFlag(Context.BIND_AUTO_CREATE)) { sb.append("CR "); } - if ((flags&Context.BIND_DEBUG_UNBIND) != 0) { + if (hasFlag(Context.BIND_DEBUG_UNBIND)) { sb.append("DBG "); } - if ((flags&Context.BIND_NOT_FOREGROUND) != 0) { + if (hasFlag(Context.BIND_NOT_FOREGROUND)) { sb.append("!FG "); } - if ((flags&Context.BIND_IMPORTANT_BACKGROUND) != 0) { + if (hasFlag(Context.BIND_IMPORTANT_BACKGROUND)) { sb.append("IMPB "); } - if ((flags&Context.BIND_ABOVE_CLIENT) != 0) { + if (hasFlag(Context.BIND_ABOVE_CLIENT)) { sb.append("ABCLT "); } - if ((flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { + if (hasFlag(Context.BIND_ALLOW_OOM_MANAGEMENT)) { sb.append("OOM "); } - if ((flags&Context.BIND_WAIVE_PRIORITY) != 0) { + if (hasFlag(Context.BIND_WAIVE_PRIORITY)) { sb.append("WPRI "); } - if ((flags&Context.BIND_IMPORTANT) != 0) { + if (hasFlag(Context.BIND_IMPORTANT)) { sb.append("IMP "); } - if ((flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { + if (hasFlag(Context.BIND_ADJUST_WITH_ACTIVITY)) { sb.append("WACT "); } - if ((flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) != 0) { + if (hasFlag(Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)) { sb.append("FGSA "); } - if ((flags&Context.BIND_FOREGROUND_SERVICE) != 0) { + if (hasFlag(Context.BIND_FOREGROUND_SERVICE)) { sb.append("FGS "); } - if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { + if (hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { sb.append("LACT "); } - if ((flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0) { + if (hasFlag(Context.BIND_SCHEDULE_LIKE_TOP_APP)) { sb.append("SLTA "); } - if ((flags & Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE) != 0) { + if (hasFlag(Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)) { sb.append("VFGS "); } - if ((flags&Context.BIND_SHOWING_UI) != 0) { + if (hasFlag(Context.BIND_SHOWING_UI)) { sb.append("UI "); } - if ((flags&Context.BIND_NOT_VISIBLE) != 0) { + if (hasFlag(Context.BIND_NOT_VISIBLE)) { sb.append("!VIS "); } - if ((flags & Context.BIND_NOT_PERCEPTIBLE) != 0) { + if (hasFlag(Context.BIND_NOT_PERCEPTIBLE)) { sb.append("!PRCP "); } - if ((flags & Context.BIND_ALLOW_ACTIVITY_STARTS) != 0) { + if (hasFlag(Context.BIND_ALLOW_ACTIVITY_STARTS)) { sb.append("BALF "); } - if ((flags & Context.BIND_INCLUDE_CAPABILITIES) != 0) { + if (hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { sb.append("CAPS "); } if (serviceDead) { @@ -251,6 +263,7 @@ final class ConnectionRecord { sb.append(binding.service.shortInstanceName); sb.append(":@"); sb.append(Integer.toHexString(System.identityHashCode(conn.asBinder()))); + sb.append(" flags=0x" + Long.toHexString(flags)); sb.append('}'); return stringName = sb.toString(); } diff --git a/services/core/java/com/android/server/am/IntentBindRecord.java b/services/core/java/com/android/server/am/IntentBindRecord.java index e62201337491..abc7ab110f89 100644 --- a/services/core/java/com/android/server/am/IntentBindRecord.java +++ b/services/core/java/com/android/server/am/IntentBindRecord.java @@ -77,12 +77,12 @@ final class IntentBindRecord { intent = _intent; } - int collectFlags() { - int flags = 0; + long collectFlags() { + long flags = 0; for (int i=apps.size()-1; i>=0; i--) { final ArraySet<ConnectionRecord> connections = apps.valueAt(i).connections; for (int j=connections.size()-1; j>=0; j--) { - flags |= connections.valueAt(j).flags; + flags |= connections.valueAt(j).getFlags(); } } return flags; diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index f11a3be5c20e..32db33d3047d 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -723,7 +723,7 @@ public class OomAdjuster { final ProcessServiceRecord psr = pr.mServices; for (int i = psr.numberOfConnections() - 1; i >= 0; i--) { ConnectionRecord cr = psr.getConnectionAt(i); - ProcessRecord service = (cr.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0 + ProcessRecord service = cr.hasFlag(ServiceInfo.FLAG_ISOLATED_PROCESS) ? cr.binding.service.isolationHostProc : cr.binding.service.app; if (service == null || service == pr || ((service.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ) @@ -734,10 +734,9 @@ public class OomAdjuster { if (service.mState.isReachable()) { continue; } - if ((cr.flags & (Context.BIND_WAIVE_PRIORITY - | Context.BIND_TREAT_LIKE_ACTIVITY - | Context.BIND_ADJUST_WITH_ACTIVITY)) - == Context.BIND_WAIVE_PRIORITY) { + if (cr.hasFlag(Context.BIND_WAIVE_PRIORITY) + && cr.notHasFlag(Context.BIND_TREAT_LIKE_ACTIVITY + | Context.BIND_ADJUST_WITH_ACTIVITY)) { continue; } queue.offer(service); @@ -2218,7 +2217,7 @@ public class OomAdjuster { // we check the final procstate, and remove it if the procsate is below BFGS. capability |= getBfslCapabilityFromClient(client); - if ((cr.flags & Context.BIND_WAIVE_PRIORITY) == 0) { + if (cr.notHasFlag(Context.BIND_WAIVE_PRIORITY)) { if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { capability |= cstate.getCurCapability(); } @@ -2231,8 +2230,7 @@ public class OomAdjuster { if ((cstate.getCurCapability() & PROCESS_CAPABILITY_NETWORK) != 0) { if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { // This is used to grant network access to Expedited Jobs. - if ((cr.flags & Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS) - != 0) { + if (cr.hasFlag(Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)) { capability |= PROCESS_CAPABILITY_NETWORK; } } else { @@ -2251,7 +2249,7 @@ public class OomAdjuster { clientProcState = PROCESS_STATE_CACHED_EMPTY; } String adjType = null; - if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { + if (cr.hasFlag(Context.BIND_ALLOW_OOM_MANAGEMENT)) { // Similar to BIND_WAIVE_PRIORITY, keep it unfrozen. if (clientAdj < CACHED_APP_MIN_ADJ) { app.mOptRecord.setShouldNotFreeze(true); @@ -2300,8 +2298,8 @@ public class OomAdjuster { } else { int newAdj; int lbAdj = VISIBLE_APP_ADJ; // lower bound of adj. - if ((cr.flags&(Context.BIND_ABOVE_CLIENT - |Context.BIND_IMPORTANT)) != 0) { + if (cr.hasFlag(Context.BIND_ABOVE_CLIENT + | Context.BIND_IMPORTANT)) { if (clientAdj >= PERSISTENT_SERVICE_ADJ) { newAdj = clientAdj; } else { @@ -2312,26 +2310,26 @@ public class OomAdjuster { cr.trackProcState(procState, mAdjSeq); trackedProcState = true; } - } else if ((cr.flags & Context.BIND_NOT_PERCEPTIBLE) != 0 + } else if (cr.hasFlag(Context.BIND_NOT_PERCEPTIBLE) && clientAdj <= PERCEPTIBLE_APP_ADJ && adj >= (lbAdj = PERCEPTIBLE_LOW_APP_ADJ)) { newAdj = PERCEPTIBLE_LOW_APP_ADJ; - } else if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0 - && (cr.flags & Context.BIND_NOT_FOREGROUND) == 0 + } else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE) + && cr.notHasFlag(Context.BIND_NOT_FOREGROUND) && clientAdj < PERCEPTIBLE_APP_ADJ && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) { // This is for user-initiated jobs. // We use APP_ADJ + 1 here, so we can tell them apart from FGS. newAdj = PERCEPTIBLE_APP_ADJ + 1; - } else if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0 - && (cr.flags & Context.BIND_NOT_FOREGROUND) != 0 + } else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE) + && cr.hasFlag(Context.BIND_NOT_FOREGROUND) && clientAdj < PERCEPTIBLE_APP_ADJ && adj >= (lbAdj = (PERCEPTIBLE_MEDIUM_APP_ADJ + 2))) { // This is for expedited jobs. // We use MEDIUM_APP_ADJ + 2 here, so we can tell apart // EJ and short-FGS. newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 2; - } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 + } else if (cr.hasFlag(Context.BIND_NOT_VISIBLE) && clientAdj < PERCEPTIBLE_APP_ADJ && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) { newAdj = PERCEPTIBLE_APP_ADJ; @@ -2359,14 +2357,14 @@ public class OomAdjuster { } } } - if ((cr.flags & (Context.BIND_NOT_FOREGROUND - | Context.BIND_IMPORTANT_BACKGROUND)) == 0) { + if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND + | Context.BIND_IMPORTANT_BACKGROUND)) { // This will treat important bound services identically to // the top app, which may behave differently than generic // foreground work. final int curSchedGroup = cstate.getCurrentSchedulingGroup(); if (curSchedGroup > schedGroup) { - if ((cr.flags&Context.BIND_IMPORTANT) != 0) { + if (cr.hasFlag(Context.BIND_IMPORTANT)) { schedGroup = curSchedGroup; } else { schedGroup = SCHED_GROUP_DEFAULT; @@ -2383,8 +2381,8 @@ public class OomAdjuster { clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } else if (mService.mWakefulness.get() == PowerManagerInternal.WAKEFULNESS_AWAKE - && (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) - != 0) { + && cr.hasFlag(Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)) + { clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } else { clientProcState = @@ -2408,7 +2406,7 @@ public class OomAdjuster { capability |= cstate.getCurCapability(); } } - } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) { + } else if (cr.notHasFlag(Context.BIND_IMPORTANT_BACKGROUND)) { if (clientProcState < PROCESS_STATE_TRANSIENT_BACKGROUND) { clientProcState = @@ -2423,7 +2421,7 @@ public class OomAdjuster { } if (schedGroup < SCHED_GROUP_TOP_APP - && (cr.flags & Context.BIND_SCHEDULE_LIKE_TOP_APP) != 0 + && cr.hasFlag(Context.BIND_SCHEDULE_LIKE_TOP_APP) && clientIsSystem) { schedGroup = SCHED_GROUP_TOP_APP; scheduleLikeTopApp = true; @@ -2441,7 +2439,7 @@ public class OomAdjuster { } } if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND - && (cr.flags & Context.BIND_SHOWING_UI) != 0) { + && cr.hasFlag(Context.BIND_SHOWING_UI)) { app.setPendingUiClean(true); } if (adjType != null) { @@ -2472,17 +2470,17 @@ public class OomAdjuster { app.mOptRecord.setShouldNotFreeze(true); } } - if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { + if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { psr.setTreatLikeActivity(true); } final ActivityServiceConnectionsHolder a = cr.activity; - if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { + if (cr.hasFlag(Context.BIND_ADJUST_WITH_ACTIVITY)) { if (a != null && adj > FOREGROUND_APP_ADJ && a.isActivityVisible()) { adj = FOREGROUND_APP_ADJ; state.setCurRawAdj(adj); - if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { - if ((cr.flags&Context.BIND_IMPORTANT) != 0) { + if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND)) { + if (cr.hasFlag(Context.BIND_IMPORTANT)) { schedGroup = SCHED_GROUP_TOP_APP_BOUND; } else { schedGroup = SCHED_GROUP_DEFAULT; diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index ee315bdb963b..f4e2b0f38f13 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -3733,7 +3733,7 @@ public final class ProcessList { if (cr.binding != null && !cr.serviceDead && cr.binding.service != null && cr.binding.service.app != null && cr.binding.service.app.getLruSeq() != mLruSeq - && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0 + && cr.notHasFlag(Context.BIND_REDUCTION_FLAGS) && !cr.binding.service.app.isPersistent()) { if (cr.binding.service.app.mServices.hasClientActivities()) { if (nextActivityIndex >= 0) { diff --git a/services/core/java/com/android/server/am/ProcessServiceRecord.java b/services/core/java/com/android/server/am/ProcessServiceRecord.java index bd7f96ae8b84..53fa4f1b2ac2 100644 --- a/services/core/java/com/android/server/am/ProcessServiceRecord.java +++ b/services/core/java/com/android/server/am/ProcessServiceRecord.java @@ -298,7 +298,7 @@ final class ProcessServiceRecord { for (int c = clist.size() - 1; c >= 0; --c) { final ConnectionRecord cr = clist.get(c); - if ((cr.flags & Context.BIND_ALMOST_PERCEPTIBLE) != 0) { + if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)) { return true; } } @@ -341,7 +341,7 @@ final class ProcessServiceRecord { mHasAboveClient = false; for (int i = mConnections.size() - 1; i >= 0; i--) { ConnectionRecord cr = mConnections.valueAt(i); - if ((cr.flags & Context.BIND_ABOVE_CLIENT) != 0) { + if (cr.hasFlag(Context.BIND_ABOVE_CLIENT)) { mHasAboveClient = true; break; } @@ -507,7 +507,7 @@ final class ProcessServiceRecord { return mConnections.size(); } - void addBoundClientUid(int clientUid, String clientPackageName, int bindFlags) { + void addBoundClientUid(int clientUid, String clientPackageName, long bindFlags) { mBoundClientUids.add(clientUid); mApp.getWindowProcessController() .addBoundClientUid(clientUid, clientPackageName, bindFlags); @@ -531,7 +531,7 @@ final class ProcessServiceRecord { for (int i = 0; i < c.size(); i++) { ConnectionRecord cr = c.get(i); boundClientUids.add(cr.clientUid); - controller.addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.flags); + controller.addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.getFlags()); } } } @@ -549,7 +549,7 @@ final class ProcessServiceRecord { ConnectionRecord cr = c.get(i); mBoundClientUids.add(cr.clientUid); mApp.getWindowProcessController() - .addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.flags); + .addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.getFlags()); } } diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 2a7f181dd832..ae8ceab62896 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -894,7 +894,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // if we have a process attached, add bound client uid of this connection to it if (app != null) { - app.mServices.addBoundClientUid(c.clientUid, c.clientPackageName, c.flags); + app.mServices.addBoundClientUid(c.clientUid, c.clientPackageName, c.getFlags()); app.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE); } } @@ -924,7 +924,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN for (int conni = connections.size() - 1; conni >= 0; conni--) { ArrayList<ConnectionRecord> cr = connections.valueAt(conni); for (int i = 0; i < cr.size(); i++) { - if ((cr.get(i).flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) { + if (cr.get(i).hasFlag(Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS)) { isAllowedByBinding = true; break; } @@ -1093,7 +1093,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN for (int conni=connections.size()-1; conni>=0; conni--) { ArrayList<ConnectionRecord> cr = connections.valueAt(conni); for (int i=0; i<cr.size(); i++) { - if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { + if (cr.get(i).hasFlag(Context.BIND_AUTO_CREATE)) { return true; } } @@ -1106,7 +1106,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN for (int conni=connections.size()-1; conni>=0; conni--) { ArrayList<ConnectionRecord> cr = connections.valueAt(conni); for (int i=0; i<cr.size(); i++) { - if ((cr.get(i).flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { + if (cr.get(i).hasFlag(Context.BIND_ALLOW_WHITELIST_MANAGEMENT)) { allowlistManager = true; return; } diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java index fe7416782262..984cb19cbbf9 100644 --- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java +++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java @@ -888,7 +888,7 @@ public final class TextClassificationManagerService extends ITextClassifierServi @NonNull final TextClassifierServiceConnection mConnection; final boolean mIsTrusted; - @Context.BindServiceFlags + @Context.BindServiceFlagsBits final int mBindServiceFlags; @NonNull @GuardedBy("mLock") @@ -925,7 +925,7 @@ public final class TextClassificationManagerService extends ITextClassifierServi mEnabled = isServiceEnabledForUser(); } - @Context.BindServiceFlags + @Context.BindServiceFlagsBits private int createBindServiceFlags(@NonNull String packageName) { int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE; if (!packageName.equals(mDefaultTextClassifierPackage)) { diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index fb056996a300..dc7f3cdc1f7f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -2600,7 +2600,7 @@ public class MockingOomAdjusterTests { } private ServiceRecord bindService(ProcessRecord service, ProcessRecord client, - ServiceRecord record, int bindFlags, IBinder binder) { + ServiceRecord record, long bindFlags, IBinder binder) { if (record == null) { record = makeServiceRecord(service); } diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java index b63fbe679e23..f5f9d97787ae 100644 --- a/test-mock/src/android/test/mock/MockContext.java +++ b/test-mock/src/android/test/mock/MockContext.java @@ -967,7 +967,7 @@ public class MockContext extends Context { /** {@hide} */ @Override public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler, - int flags) { + long flags) { throw new UnsupportedOperationException(); } -- GitLab