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

Commit 55e23e0f authored by Mugdha Lakhani's avatar Mugdha Lakhani Committed by Android (Google) Code Review
Browse files

Merge "Update seinfo for sdk sandbox" into udc-dev

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


    private static final String APPLY_SDK_SANDBOX_NEXT_RESTRICTIONS = ":isSdkSandboxNext";

    // OOM adjustments for processes in various states:
    // OOM adjustments for processes in various states:


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


    ActivityManagerGlobalLock mProcLock;
    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 {
    final class IsolatedUidRange {
        @VisibleForTesting
        @VisibleForTesting
        public final int mFirstUid;
        public final int mFirstUid;
@@ -1883,8 +1958,9 @@ public final class ProcessList {
                        new IllegalStateException("SELinux tag not defined for "
                        new IllegalStateException("SELinux tag not defined for "
                                + app.info.packageName + " (uid " + app.uid + ")"));
                                + 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
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            // the PID of the new process, or else throw a RuntimeException.
            final String entryPoint = "android.app.ActivityThread";
            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")
    @GuardedBy("mService")
    boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
    boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
+96 −2
Original line number Original line 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_NO_CHANGE;
import static com.android.server.am.ProcessList.NETWORK_STATE_UNBLOCK;
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 com.google.common.truth.Truth.assertWithMessage;


import static org.junit.Assert.assertEquals;
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.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;


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


import androidx.test.filters.MediumTest;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
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.LocalServices;
import com.android.server.am.ActivityManagerService.StickyBroadcast;
import com.android.server.am.ActivityManagerService.StickyBroadcast;
import com.android.server.am.ProcessList.IsolatedUidRange;
import com.android.server.am.ProcessList.IsolatedUidRange;
@@ -106,6 +111,7 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;


import java.io.File;
import java.io.File;
import java.util.ArrayList;
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_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 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 TEST_UID = 11111;
    private static final int USER_ID = 666;
    private static final int USER_ID = 666;


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


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


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

    @Before
    @Before
    public void setUp() {
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
@@ -203,6 +211,15 @@ public class ActivityManagerServiceTest {
        mAms.mActivityTaskManager.initialize(null, null, mHandler.getLooper());
        mAms.mActivityTaskManager.initialize(null, null, mHandler.getLooper());
        mHandler.setRunnablesToIgnore(
        mHandler.setRunnablesToIgnore(
                List.of(mAms.mUidObserverController.getDispatchRunnableForTest()));
                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() {
    private void mockNoteOperation() {
@@ -216,6 +233,12 @@ public class ActivityManagerServiceTest {
    @After
    @After
    public void tearDown() {
    public void tearDown() {
        mHandlerThread.quit();
        mHandlerThread.quit();
        InstrumentationRegistry.getInstrumentation()
            .getUiAutomation()
            .dropShellPermissionIdentity();
        if (sProcessListSettingsListener != null) {
            sProcessListSettingsListener.unregisterObserver();
        }
    }
    }


    @SuppressWarnings("GuardedBy")
    @SuppressWarnings("GuardedBy")
@@ -268,6 +291,77 @@ public class ActivityManagerServiceTest {
                false); // expectNotify
                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) {
    private UidRecord addUidRecord(int uid) {
        final UidRecord uidRec = new UidRecord(uid, mAms);
        final UidRecord uidRec = new UidRecord(uid, mAms);
        uidRec.procStateSeqWaitingForNetwork = 1;
        uidRec.procStateSeqWaitingForNetwork = 1;