Merge "Update seinfo for sdk sandbox" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
55e23e0ff9
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user