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

Commit a9b60717 authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Update seinfo for sdk sandbox" into udc-dev am: 55e23e0f am: 2149856d"

parents 2aa22aae c54037b5
Loading
Loading
Loading
Loading
+93 −2
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.storage.StorageManagerInternal;
import android.provider.DeviceConfig;
import android.system.Os;
import android.system.OsConstants;
import android.text.TextUtils;
@@ -181,6 +182,8 @@ public final class ProcessList {
    static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY =
            "persist.sys.vold_app_data_isolation_enabled";

    private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext";

    // OOM adjustments for processes in various states:

    // Uninitialized value for any major or minor adj fields
@@ -538,6 +541,78 @@ public final class ProcessList {

    ActivityManagerGlobalLock mProcLock;

    private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS =
            "apply_sdk_sandbox_next_restrictions";
    private static final boolean DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = false;

    @GuardedBy("mService")
    private ProcessListSettingsListener mProcessListSettingsListener;

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    ProcessListSettingsListener getProcessListSettingsListener() {
        synchronized (mService) {
            if (mProcessListSettingsListener == null) {
                mProcessListSettingsListener = new ProcessListSettingsListener(mService.mContext);
                mProcessListSettingsListener.registerObserver();
            }
            return mProcessListSettingsListener;
        }
    }

    static class ProcessListSettingsListener implements DeviceConfig.OnPropertiesChangedListener {

        private final Context mContext;
        private final Object mLock = new Object();

        @GuardedBy("mLock")
        private boolean mSdkSandboxApplyRestrictionsNext =
                DeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_ADSERVICES,
                PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
                DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);

        ProcessListSettingsListener(Context context) {
            mContext = context;
        }

        private void registerObserver() {
            DeviceConfig.addOnPropertiesChangedListener(
                    DeviceConfig.NAMESPACE_ADSERVICES, mContext.getMainExecutor(), this);
        }

        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
        void unregisterObserver() {
            DeviceConfig.removeOnPropertiesChangedListener(this);
        }

        boolean applySdkSandboxRestrictionsNext() {
            synchronized (mLock) {
                return mSdkSandboxApplyRestrictionsNext;
            }
        }

        @Override
        public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
            synchronized (mLock) {
                for (String name : properties.getKeyset()) {
                    if (name == null) {
                        continue;
                    }

                    switch (name) {
                        case PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS:
                            mSdkSandboxApplyRestrictionsNext =
                                properties.getBoolean(
                                    PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS,
                                    DEFAULT_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
                            break;
                        default:
                    }
                }
            }
        }
    }

    final class IsolatedUidRange {
        @VisibleForTesting
        public final int mFirstUid;
@@ -1883,8 +1958,9 @@ public final class ProcessList {
                        new IllegalStateException("SELinux tag not defined for "
                                + app.info.packageName + " (uid " + app.uid + ")"));
            }
            final String seInfo = app.info.seInfo
                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);

            String seInfo = updateSeInfo(app);

            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            final String entryPoint = "android.app.ActivityThread";
@@ -1907,6 +1983,21 @@ public final class ProcessList {
        }
    }

    @VisibleForTesting
    @GuardedBy("mService")
    String updateSeInfo(ProcessRecord app) {
        String extraInfo = "";
        // By the time the first the SDK sandbox process is started, device config service
        // should be available.
        if (app.isSdkSandbox
                && getProcessListSettingsListener().applySdkSandboxRestrictionsNext()) {
            extraInfo = APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS;
        }

        return app.info.seInfo
                + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser) + extraInfo;
    }


    @GuardedBy("mService")
    boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
+96 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import static com.android.server.am.ProcessList.NETWORK_STATE_BLOCK;
import static com.android.server.am.ProcessList.NETWORK_STATE_NO_CHANGE;
import static com.android.server.am.ProcessList.NETWORK_STATE_UNBLOCK;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import static org.junit.Assert.assertEquals;
@@ -60,6 +61,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.Manifest;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
@@ -82,13 +84,16 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;

import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;

import com.android.dx.mockito.inline.extended.ExtendedMockito;
import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService.StickyBroadcast;
import com.android.server.am.ProcessList.IsolatedUidRange;
@@ -106,6 +111,7 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;

import java.io.File;
import java.util.ArrayList;
@@ -137,7 +143,9 @@ public class ActivityManagerServiceTest {

    private static final String TEST_EXTRA_KEY1 = "com.android.server.am.TEST_EXTRA_KEY1";
    private static final String TEST_EXTRA_VALUE1 = "com.android.server.am.TEST_EXTRA_VALUE1";

    private static final String PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS =
            "apply_sdk_sandbox_next_restrictions";
    private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext";
    private static final int TEST_UID = 11111;
    private static final int USER_ID = 666;

@@ -154,6 +162,7 @@ public class ActivityManagerServiceTest {
    };

    private static PackageManagerInternal sPackageManagerInternal;
    private static ProcessList.ProcessListSettingsListener sProcessListSettingsListener;

    @BeforeClass
    public static void setUpOnce() {
@@ -181,7 +190,6 @@ public class ActivityManagerServiceTest {
    private ActivityManagerService mAms;
    private HandlerThread mHandlerThread;
    private TestHandler mHandler;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
@@ -203,6 +211,15 @@ public class ActivityManagerServiceTest {
        mAms.mActivityTaskManager.initialize(null, null, mHandler.getLooper());
        mHandler.setRunnablesToIgnore(
                List.of(mAms.mUidObserverController.getDispatchRunnableForTest()));

        // Required for updating DeviceConfig.
        InstrumentationRegistry.getInstrumentation()
                .getUiAutomation()
                .adoptShellPermissionIdentity(
                Manifest.permission.READ_DEVICE_CONFIG,
                Manifest.permission.WRITE_DEVICE_CONFIG);
        sProcessListSettingsListener = mAms.mProcessList.getProcessListSettingsListener();
        assertThat(sProcessListSettingsListener).isNotNull();
    }

    private void mockNoteOperation() {
@@ -216,6 +233,12 @@ public class ActivityManagerServiceTest {
    @After
    public void tearDown() {
        mHandlerThread.quit();
        InstrumentationRegistry.getInstrumentation()
            .getUiAutomation()
            .dropShellPermissionIdentity();
        if (sProcessListSettingsListener != null) {
            sProcessListSettingsListener.unregisterObserver();
        }
    }

    @SuppressWarnings("GuardedBy")
@@ -268,6 +291,77 @@ public class ActivityManagerServiceTest {
                false); // expectNotify
    }

    @SuppressWarnings("GuardedBy")
    @SmallTest
    @Test
    public void defaultSdkSandboxNextRestrictions() throws Exception {
        sProcessListSettingsListener.onPropertiesChanged(
                new DeviceConfig.Properties(
                DeviceConfig.NAMESPACE_ADSERVICES,
                Map.of(PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, "")));
        assertThat(
            sProcessListSettingsListener.applySdkSandboxRestrictionsNext())
            .isFalse();
    }

    @SuppressWarnings("GuardedBy")
    @SmallTest
    @Test
    public void doNotApplySdkSandboxNextRestrictions() throws Exception {
        MockitoSession mockitoSession =
                ExtendedMockito.mockitoSession().spyStatic(Process.class).startMocking();
        try {
            sProcessListSettingsListener.onPropertiesChanged(
                    new DeviceConfig.Properties(
                    DeviceConfig.NAMESPACE_ADSERVICES,
                    Map.of(PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, "false")));
            assertThat(
                sProcessListSettingsListener.applySdkSandboxRestrictionsNext())
                .isFalse();
            ExtendedMockito.doReturn(true).when(() -> Process.isSdkSandboxUid(anyInt()));
            ApplicationInfo info = new ApplicationInfo();
            info.packageName = "com.android.sdksandbox";
            info.seInfo = "default:targetSdkVersion=34:complete";
            final ProcessRecord appRec = new ProcessRecord(
                    mAms, info, TAG, Process.FIRST_SDK_SANDBOX_UID,
                    /* sdkSandboxClientPackageName= */ "com.example.client",
                    /* definingUid= */ 0, /* definingProcessName= */ "");
            assertThat(mAms.mProcessList.updateSeInfo(appRec)).doesNotContain(
                    APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
        } finally {
            mockitoSession.finishMocking();
        }
    }
    @SuppressWarnings("GuardedBy")
    @SmallTest
    @Test
    public void applySdkSandboxNextRestrictions() throws Exception {
        MockitoSession mockitoSession =
                ExtendedMockito.mockitoSession().spyStatic(Process.class).startMocking();
        try {
            sProcessListSettingsListener.onPropertiesChanged(
                    new DeviceConfig.Properties(
                    DeviceConfig.NAMESPACE_ADSERVICES,
                    Map.of(PROPERTY_APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS, "true")));
            assertThat(
                sProcessListSettingsListener.applySdkSandboxRestrictionsNext())
                .isTrue();
            ExtendedMockito.doReturn(true).when(() -> Process.isSdkSandboxUid(anyInt()));
            ApplicationInfo info = new ApplicationInfo();
            info.packageName = "com.android.sdksandbox";
            info.seInfo = "default:targetSdkVersion=34:complete";
            final ProcessRecord appRec = new ProcessRecord(
                    mAms, info, TAG, Process.FIRST_SDK_SANDBOX_UID,
                    /* sdkSandboxClientPackageName= */ "com.example.client",
                    /* definingUid= */ 0, /* definingProcessName= */ "");
            assertThat(mAms.mProcessList.updateSeInfo(appRec)).contains(
                    APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS);
        } finally {
            mockitoSession.finishMocking();
        }
    }


    private UidRecord addUidRecord(int uid) {
        final UidRecord uidRec = new UidRecord(uid, mAms);
        uidRec.procStateSeqWaitingForNetwork = 1;