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

Commit 9fce85c0 authored by Oluwarotimi Adesina's avatar Oluwarotimi Adesina Committed by Android (Google) Code Review
Browse files

Merge "Support package private shared isolated processes." into main

parents 23068406 e3ed5b28
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ aconfig_srcjars = [
    ":android.chre.flags-aconfig-java{.generated_srcjars}",
    ":android.speech.flags-aconfig-java{.generated_srcjars}",
    ":power_flags_lib{.generated_srcjars}",
    ":android.content.flags-aconfig-java{.generated_srcjars}",
]

filegroup {
@@ -940,3 +941,16 @@ java_aconfig_library {
    aconfig_declarations: "power_flags",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

// Content
aconfig_declarations {
    name: "android.content.flags-aconfig",
    package: "android.content.flags",
    srcs: ["core/java/android/content/flags/flags.aconfig"],
}

java_aconfig_library {
    name: "android.content.flags-aconfig-java",
    aconfig_declarations: "android.content.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+1 −0
Original line number Diff line number Diff line
@@ -10545,6 +10545,7 @@ package android.content {
    field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000
    field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
    field public static final int BIND_NOT_PERCEPTIBLE = 256; // 0x100
    field @FlaggedApi("android.content.flags.enable_bind_package_isolated_process") public static final int BIND_PACKAGE_ISOLATED_PROCESS = 16384; // 0x4000
    field public static final int BIND_SHARED_ISOLATED_PROCESS = 8192; // 0x2000
    field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
    field public static final String BIOMETRIC_SERVICE = "biometric";
+24 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.content;

import static android.content.flags.Flags.FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS;

import android.annotation.AttrRes;
import android.annotation.CallbackExecutor;
import android.annotation.CheckResult;
@@ -296,6 +298,7 @@ public abstract class Context {
            BIND_ALLOW_ACTIVITY_STARTS,
            BIND_INCLUDE_CAPABILITIES,
            BIND_SHARED_ISOLATED_PROCESS,
            BIND_PACKAGE_ISOLATED_PROCESS,
            BIND_EXTERNAL_SERVICE
    })
    @Retention(RetentionPolicy.SOURCE)
@@ -318,6 +321,7 @@ public abstract class Context {
            BIND_ALLOW_ACTIVITY_STARTS,
            BIND_INCLUDE_CAPABILITIES,
            BIND_SHARED_ISOLATED_PROCESS,
            BIND_PACKAGE_ISOLATED_PROCESS,
            // Intentionally not include BIND_EXTERNAL_SERVICE, because it'd cause sign-extension.
            // This would allow Android Studio to show a warning, if someone tries to use
            // BIND_EXTERNAL_SERVICE BindServiceFlags.
@@ -511,6 +515,26 @@ public abstract class Context {
     */
    public static final int BIND_SHARED_ISOLATED_PROCESS = 0x00002000;

    /**
     * Flag for {@link #bindIsolatedService}: Bind the service into a shared isolated process,
     * but only with other isolated services from the same package that declare the same process
     * name.
     *
     * <p>Specifying this flag allows multiple isolated services defined in the same package to be
     * running in a single shared isolated process. This shared isolated process must be specified
     * since this flag will not work with the default application process.
     *
     * <p>This flag is different from {@link #BIND_SHARED_ISOLATED_PROCESS} since it only
     * allows binding services from the same package in the same shared isolated process. This also
     * means the shared package isolated process is global, and not scoped to each potential
     * calling app.
     *
     * <p>The shared isolated process instance is identified by the "android:process" attribute
     * defined by the service. This flag cannot be used without this attribute set.
     */
    @FlaggedApi(FLAG_ENABLE_BIND_PACKAGE_ISOLATED_PROCESS)
    public static final int BIND_PACKAGE_ISOLATED_PROCESS = 1 << 14;

    /***********    Public flags above this line ***********/
    /***********    Hidden flags below this line ***********/

+8 −0
Original line number Diff line number Diff line
package: "android.content.flags"

flag {
    name: "enable_bind_package_isolated_process"
    namespace: "machine_learning"
    description: "This flag enables the newly added flag for binding package-private isolated processes."
    bug: "312706530"
}
 No newline at end of file
+57 −27
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY;
import static android.content.flags.Flags.enableBindPackageIsolatedProcess;


import static com.android.internal.messages.nano.SystemMessageProto.SystemMessage.NOTE_FOREGROUND_SERVICE_BG_LAUNCH;
import static com.android.internal.util.FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__FGS_START_API__FGSSTARTAPI_DELEGATE;
@@ -791,13 +793,15 @@ public final class ActiveServices {

    static String getProcessNameForService(ServiceInfo sInfo, ComponentName name,
            String callingPackage, String instanceName, boolean isSdkSandbox,
            boolean inSharedIsolatedProcess) {
            boolean inSharedIsolatedProcess, boolean inPrivateSharedIsolatedProcess) {
        if (isSdkSandbox) {
            // For SDK sandbox, the process name is passed in as the instanceName
            return instanceName;
        }
        if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
            // For regular processes, just the name in sInfo
        if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0
                || (inPrivateSharedIsolatedProcess && !isDefaultProcessService(sInfo))) {
            // For regular processes, or private package-shared isolated processes, just the name
            // in sInfo
            return sInfo.processName;
        }
        // Isolated processes remain.
@@ -809,6 +813,10 @@ public final class ActiveServices {
        }
    }

    private static boolean isDefaultProcessService(ServiceInfo serviceInfo) {
        return serviceInfo.applicationInfo.processName.equals(serviceInfo.processName);
    }

    private static void traceInstant(@NonNull String message, @NonNull ServiceRecord service) {
        if (!Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
            return;
@@ -864,7 +872,7 @@ public final class ActiveServices {

        ServiceLookupResult res = retrieveServiceLocked(service, instanceName, isSdkSandboxService,
                sdkSandboxClientAppUid, sdkSandboxClientAppPackage, resolvedType, callingPackage,
                callingPid, callingUid, userId, true, callerFg, false, false, null, false);
                callingPid, callingUid, userId, true, callerFg, false, false, null, false, false);
        if (res == null) {
            return null;
        }
@@ -1550,7 +1558,7 @@ public final class ActiveServices {
        ServiceLookupResult r = retrieveServiceLocked(service, instanceName, isSdkSandboxService,
                sdkSandboxClientAppUid, sdkSandboxClientAppPackage, resolvedType, null,
                Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false, false,
                null, false);
                null, false, false);
        if (r != null) {
            if (r.record != null) {
                final long origId = Binder.clearCallingIdentity();
@@ -1642,7 +1650,7 @@ public final class ActiveServices {
    IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
        ServiceLookupResult r = retrieveServiceLocked(service, null, resolvedType, callingPackage,
                Binder.getCallingPid(), Binder.getCallingUid(),
                UserHandle.getCallingUserId(), false, false, false, false, false);
                UserHandle.getCallingUserId(), false, false, false, false, false, false);

        IBinder ret = null;
        if (r != null) {
@@ -3714,6 +3722,9 @@ public final class ActiveServices {
                || (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;
        final boolean inPrivateSharedIsolatedProcess =
                ((flags & Context.BIND_PACKAGE_ISOLATED_PROCESS) != 0)
                        && enableBindPackageIsolatedProcess();
        final boolean matchQuarantined =
                (flags & Context.BIND_MATCH_QUARANTINED_COMPONENTS) != 0;

@@ -3725,7 +3736,7 @@ public final class ActiveServices {
                isSdkSandboxService, sdkSandboxClientAppUid, sdkSandboxClientAppPackage,
                resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg,
                isBindExternal, allowInstant, null /* fgsDelegateOptions */,
                inSharedIsolatedProcess, matchQuarantined);
                inSharedIsolatedProcess, inPrivateSharedIsolatedProcess, matchQuarantined);
        if (res == null) {
            return 0;
        }
@@ -4204,14 +4215,14 @@ public final class ActiveServices {
    }

    private ServiceLookupResult retrieveServiceLocked(Intent service,
            String instanceName, String resolvedType, String callingPackage,
            int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant, boolean inSharedIsolatedProcess) {
            String instanceName, String resolvedType, String callingPackage, int callingPid,
            int callingUid, int userId, boolean createIfNeeded, boolean callingFromFg,
            boolean isBindExternal, boolean allowInstant, boolean inSharedIsolatedProcess,
            boolean inPrivateSharedIsolatedProcess) {
        return retrieveServiceLocked(service, instanceName, false, INVALID_UID, null, resolvedType,
                callingPackage, callingPid, callingUid, userId, createIfNeeded, callingFromFg,
                isBindExternal, allowInstant, null /* fgsDelegateOptions */,
                inSharedIsolatedProcess);
                inSharedIsolatedProcess, inPrivateSharedIsolatedProcess);
    }

    // TODO(b/265746493): Special case for HotwordDetectionService,
@@ -4233,21 +4244,22 @@ public final class ActiveServices {
            String callingPackage, int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant, ForegroundServiceDelegationOptions fgsDelegateOptions,
            boolean inSharedIsolatedProcess) {
            boolean inSharedIsolatedProcess, boolean inPrivateSharedIsolatedProcess) {
        return retrieveServiceLocked(service, instanceName, isSdkSandboxService,
                sdkSandboxClientAppUid, sdkSandboxClientAppPackage, resolvedType, callingPackage,
                callingPid, callingUid, userId, createIfNeeded, callingFromFg, isBindExternal,
                allowInstant, fgsDelegateOptions, inSharedIsolatedProcess,
                false /* matchQuarantined */);
                inPrivateSharedIsolatedProcess, false /* matchQuarantined */);
    }

    private ServiceLookupResult retrieveServiceLocked(Intent service,
            String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
            String sdkSandboxClientAppPackage, String resolvedType,
    private ServiceLookupResult retrieveServiceLocked(
            Intent service, String instanceName, boolean isSdkSandboxService,
            int sdkSandboxClientAppUid, String sdkSandboxClientAppPackage, String resolvedType,
            String callingPackage, int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant, ForegroundServiceDelegationOptions fgsDelegateOptions,
            boolean inSharedIsolatedProcess, boolean matchQuarantined) {
            boolean inSharedIsolatedProcess, boolean inPrivateSharedIsolatedProcess,
            boolean matchQuarantined) {
        if (isSdkSandboxService && instanceName == null) {
            throw new IllegalArgumentException("No instanceName provided for sdk sandbox process");
        }
@@ -4344,7 +4356,8 @@ public final class ActiveServices {
                final ServiceRestarter res = new ServiceRestarter();
                final String processName = getProcessNameForService(sInfo, cn, callingPackage,
                        null /* instanceName */, false /* isSdkSandbox */,
                        false /* inSharedIsolatedProcess */);
                        false /* inSharedIsolatedProcess */,
                        false /*inPrivateSharedIsolatedProcess*/);
                r = new ServiceRecord(mAm, cn /* name */, cn /* instanceName */,
                        sInfo.applicationInfo.packageName, sInfo.applicationInfo.uid, filter, sInfo,
                        callingFromFg, res, processName,
@@ -4415,6 +4428,10 @@ public final class ActiveServices {
                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
                                    + className + " is not exported");
                        }
                        if (inPrivateSharedIsolatedProcess) {
                            throw new SecurityException("BIND_PACKAGE_ISOLATED_PROCESS cannot be "
                                    + "applied to an external service.");
                        }
                        if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
                                    + className + " is not an isolatedProcess");
@@ -4448,20 +4465,30 @@ public final class ActiveServices {
                    throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
                            " is not an externalService");
                }
                if (inSharedIsolatedProcess) {
                if (inSharedIsolatedProcess && inPrivateSharedIsolatedProcess) {
                    throw new SecurityException("Either BIND_SHARED_ISOLATED_PROCESS or "
                            + "BIND_PACKAGE_ISOLATED_PROCESS should be set. Not both.");
                }
                if (inSharedIsolatedProcess || inPrivateSharedIsolatedProcess) {
                    if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
                        throw new SecurityException("BIND_SHARED_ISOLATED_PROCESS failed, "
                                + className + " is not an isolatedProcess");
                    }
                    if ((sInfo.flags & ServiceInfo.FLAG_ALLOW_SHARED_ISOLATED_PROCESS) == 0) {
                        throw new SecurityException("BIND_SHARED_ISOLATED_PROCESS failed, "
                                + className + " has not set the allowSharedIsolatedProcess "
                                + " attribute.");
                }
                if (inPrivateSharedIsolatedProcess && isDefaultProcessService(sInfo)) {
                    throw new SecurityException("BIND_PACKAGE_ISOLATED_PROCESS cannot be used for "
                            + "services running in the main app process.");
                }
                if (inSharedIsolatedProcess) {
                    if (instanceName == null) {
                        throw new IllegalArgumentException("instanceName must be provided for "
                                + "binding a service into a shared isolated process.");
                    }
                    if ((sInfo.flags & ServiceInfo.FLAG_ALLOW_SHARED_ISOLATED_PROCESS) == 0) {
                        throw new SecurityException("BIND_SHARED_ISOLATED_PROCESS failed, "
                                + className + " has not set the allowSharedIsolatedProcess "
                                + " attribute.");
                    }
                }
                if (userId > 0) {
                    if (mAm.isSystemUserOnly(sInfo.flags)) {
@@ -4503,11 +4530,13 @@ public final class ActiveServices {
                            = new Intent.FilterComparison(service.cloneFilter());
                    final ServiceRestarter res = new ServiceRestarter();
                    String processName = getProcessNameForService(sInfo, name, callingPackage,
                            instanceName, isSdkSandboxService, inSharedIsolatedProcess);
                            instanceName, isSdkSandboxService, inSharedIsolatedProcess,
                            inPrivateSharedIsolatedProcess);
                    r = new ServiceRecord(mAm, className, name, definingPackageName,
                            definingUid, filter, sInfo, callingFromFg, res,
                            processName, sdkSandboxClientAppUid,
                            sdkSandboxClientAppPackage, inSharedIsolatedProcess);
                            sdkSandboxClientAppPackage,
                            (inSharedIsolatedProcess || inPrivateSharedIsolatedProcess));
                    res.setService(r);
                    smap.mServicesByInstanceName.put(name, r);
                    smap.mServicesByIntent.put(filter, r);
@@ -8504,7 +8533,8 @@ public final class ActiveServices {
                null /* sdkSandboxClientAppPackage */, null /* resolvedType */, callingPackage,
                callingPid, callingUid, userId, true /* createIfNeeded */,
                false /* callingFromFg */, false /* isBindExternal */, false /* allowInstant */ ,
                options, false /* inSharedIsolatedProcess */);
                options, false /* inSharedIsolatedProcess */,
                false /*inPrivateSharedIsolatedProcess*/);
        if (res == null || res.record == null) {
            Slog.d(TAG,
                    "startForegroundServiceDelegateLocked retrieveServiceLocked returns null");
Loading