Loading services/core/java/com/android/server/os/BugreportManagerServiceImpl.java +6 −2 Original line number Diff line number Diff line Loading @@ -354,6 +354,10 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { DevicePolicyManager getDevicePolicyManager() { return mContext.getSystemService(DevicePolicyManager.class); } void setSystemProperty(String key, String value) { SystemProperties.set(key, value); } } BugreportManagerServiceImpl(Context context) { Loading Loading @@ -737,7 +741,7 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { @GuardedBy("mLock") private IDumpstate startAndGetDumpstateBinderServiceLocked() { // Start bugreport service. SystemProperties.set("ctl.start", BUGREPORT_SERVICE); mInjector.setSystemProperty("ctl.start", BUGREPORT_SERVICE); IDumpstate ds = null; boolean timedOut = false; Loading Loading @@ -769,7 +773,7 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { // This tells init to cancel bugreportd service. Note that this is achieved through // setting a system property which is not thread-safe. So the lock here offers // thread-safety only among callers of the API. SystemProperties.set("ctl.stop", BUGREPORT_SERVICE); mInjector.setSystemProperty("ctl.stop", BUGREPORT_SERVICE); } @RequiresPermission(android.Manifest.permission.DUMP) Loading services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java +56 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.app.admin.flags.Flags; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Binder; import android.os.BugreportManager.BugreportCallback; import android.os.BugreportParams; Loading @@ -37,6 +38,7 @@ import android.os.IBinder; import android.os.IDumpstateListener; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; Loading Loading @@ -67,6 +69,9 @@ import java.util.function.Consumer; @RunWith(AndroidJUnit4.class) public class BugreportManagerServiceImplTest { private static final UserInfo ADMIN_USER_INFO = new UserInfo(/* id= */ 5678, "adminUser", UserInfo.FLAG_ADMIN); @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); Loading @@ -82,6 +87,8 @@ public class BugreportManagerServiceImplTest { @Mock private DevicePolicyManager mMockDevicePolicyManager; private TestInjector mInjector; private int mCallingUid = 1234; private String mCallingPackage = "test.package"; private AtomicFile mMappingFile; Loading @@ -96,9 +103,9 @@ public class BugreportManagerServiceImplTest { mMappingFile = new AtomicFile(mContext.getFilesDir(), "bugreport-mapping.xml"); ArraySet<String> mAllowlistedPackages = new ArraySet<>(); mAllowlistedPackages.add(mContext.getPackageName()); mService = new BugreportManagerServiceImpl( new TestInjector(mContext, mAllowlistedPackages, mMappingFile, mMockUserManager, mMockDevicePolicyManager)); mInjector = new TestInjector(mContext, mAllowlistedPackages, mMappingFile, mMockUserManager, mMockDevicePolicyManager); mService = new BugreportManagerServiceImpl(mInjector); mBugreportFileManager = new BugreportManagerServiceImpl.BugreportFileManager(mMappingFile); when(mPackageManager.getPackageUidAsUser(anyString(), anyInt())).thenReturn(mCallingUid); // The calling user is an admin user by default. Loading Loading @@ -189,6 +196,33 @@ public class BugreportManagerServiceImplTest { /* forceUpdateMapping= */ true)); } @Test public void testStartBugreport() throws Exception { mService.startBugreport(mCallingUid, mContext.getPackageName(), new FileDescriptor(), /* screenshotFd= */ null, BugreportParams.BUGREPORT_MODE_FULL, /* flags= */ 0, new Listener(new CountDownLatch(1)), /* isScreenshotRequested= */ false); assertThat(mInjector.isBugreportStarted()).isTrue(); } @Test public void testStartBugreport_nonAdminProfileOfAdminCurrentUser() throws Exception { int callingUid = Binder.getCallingUid(); int callingUserId = UserHandle.getUserId(callingUid); when(mMockUserManager.isUserAdmin(callingUserId)).thenReturn(false); when(mMockUserManager.getProfileParent(callingUserId)).thenReturn(ADMIN_USER_INFO); mService.startBugreport(mCallingUid, mContext.getPackageName(), new FileDescriptor(), /* screenshotFd= */ null, BugreportParams.BUGREPORT_MODE_FULL, /* flags= */ 0, new Listener(new CountDownLatch(1)), /* isScreenshotRequested= */ false); assertThat(mInjector.isBugreportStarted()).isTrue(); } @Test public void testStartBugreport_throwsForNonAdminUser() throws Exception { when(mMockUserManager.isUserAdmin(anyInt())).thenReturn(false); Loading Loading @@ -317,8 +351,12 @@ public class BugreportManagerServiceImplTest { private static class TestInjector extends BugreportManagerServiceImpl.Injector { private static final String SYSTEM_PROPERTY_BUGREPORT_START = "ctl.start"; private static final String SYSTEM_PROPERTY_BUGREPORT_STOP = "ctl.stop"; private final UserManager mUserManager; private final DevicePolicyManager mDevicePolicyManager; private boolean mBugreportStarted = false; TestInjector(Context context, ArraySet<String> allowlistedPackages, AtomicFile mappingFile, UserManager um, DevicePolicyManager dpm) { Loading @@ -336,5 +374,20 @@ public class BugreportManagerServiceImplTest { public DevicePolicyManager getDevicePolicyManager() { return mDevicePolicyManager; } @Override public void setSystemProperty(String key, String value) { // Calling SystemProperties.set() will throw a RuntimeException due to permission error. // Instead, we are just marking a flag to store the state for testing. if (SYSTEM_PROPERTY_BUGREPORT_START.equals(key)) { mBugreportStarted = true; } else if (SYSTEM_PROPERTY_BUGREPORT_STOP.equals(key)) { mBugreportStarted = false; } } public boolean isBugreportStarted() { return mBugreportStarted; } } } Loading
services/core/java/com/android/server/os/BugreportManagerServiceImpl.java +6 −2 Original line number Diff line number Diff line Loading @@ -354,6 +354,10 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { DevicePolicyManager getDevicePolicyManager() { return mContext.getSystemService(DevicePolicyManager.class); } void setSystemProperty(String key, String value) { SystemProperties.set(key, value); } } BugreportManagerServiceImpl(Context context) { Loading Loading @@ -737,7 +741,7 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { @GuardedBy("mLock") private IDumpstate startAndGetDumpstateBinderServiceLocked() { // Start bugreport service. SystemProperties.set("ctl.start", BUGREPORT_SERVICE); mInjector.setSystemProperty("ctl.start", BUGREPORT_SERVICE); IDumpstate ds = null; boolean timedOut = false; Loading Loading @@ -769,7 +773,7 @@ class BugreportManagerServiceImpl extends IDumpstate.Stub { // This tells init to cancel bugreportd service. Note that this is achieved through // setting a system property which is not thread-safe. So the lock here offers // thread-safety only among callers of the API. SystemProperties.set("ctl.stop", BUGREPORT_SERVICE); mInjector.setSystemProperty("ctl.stop", BUGREPORT_SERVICE); } @RequiresPermission(android.Manifest.permission.DUMP) Loading
services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java +56 −3 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.app.admin.flags.Flags; import android.app.role.RoleManager; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Binder; import android.os.BugreportManager.BugreportCallback; import android.os.BugreportParams; Loading @@ -37,6 +38,7 @@ import android.os.IBinder; import android.os.IDumpstateListener; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.platform.test.annotations.RequiresFlagsDisabled; import android.platform.test.annotations.RequiresFlagsEnabled; Loading Loading @@ -67,6 +69,9 @@ import java.util.function.Consumer; @RunWith(AndroidJUnit4.class) public class BugreportManagerServiceImplTest { private static final UserInfo ADMIN_USER_INFO = new UserInfo(/* id= */ 5678, "adminUser", UserInfo.FLAG_ADMIN); @Rule public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); Loading @@ -82,6 +87,8 @@ public class BugreportManagerServiceImplTest { @Mock private DevicePolicyManager mMockDevicePolicyManager; private TestInjector mInjector; private int mCallingUid = 1234; private String mCallingPackage = "test.package"; private AtomicFile mMappingFile; Loading @@ -96,9 +103,9 @@ public class BugreportManagerServiceImplTest { mMappingFile = new AtomicFile(mContext.getFilesDir(), "bugreport-mapping.xml"); ArraySet<String> mAllowlistedPackages = new ArraySet<>(); mAllowlistedPackages.add(mContext.getPackageName()); mService = new BugreportManagerServiceImpl( new TestInjector(mContext, mAllowlistedPackages, mMappingFile, mMockUserManager, mMockDevicePolicyManager)); mInjector = new TestInjector(mContext, mAllowlistedPackages, mMappingFile, mMockUserManager, mMockDevicePolicyManager); mService = new BugreportManagerServiceImpl(mInjector); mBugreportFileManager = new BugreportManagerServiceImpl.BugreportFileManager(mMappingFile); when(mPackageManager.getPackageUidAsUser(anyString(), anyInt())).thenReturn(mCallingUid); // The calling user is an admin user by default. Loading Loading @@ -189,6 +196,33 @@ public class BugreportManagerServiceImplTest { /* forceUpdateMapping= */ true)); } @Test public void testStartBugreport() throws Exception { mService.startBugreport(mCallingUid, mContext.getPackageName(), new FileDescriptor(), /* screenshotFd= */ null, BugreportParams.BUGREPORT_MODE_FULL, /* flags= */ 0, new Listener(new CountDownLatch(1)), /* isScreenshotRequested= */ false); assertThat(mInjector.isBugreportStarted()).isTrue(); } @Test public void testStartBugreport_nonAdminProfileOfAdminCurrentUser() throws Exception { int callingUid = Binder.getCallingUid(); int callingUserId = UserHandle.getUserId(callingUid); when(mMockUserManager.isUserAdmin(callingUserId)).thenReturn(false); when(mMockUserManager.getProfileParent(callingUserId)).thenReturn(ADMIN_USER_INFO); mService.startBugreport(mCallingUid, mContext.getPackageName(), new FileDescriptor(), /* screenshotFd= */ null, BugreportParams.BUGREPORT_MODE_FULL, /* flags= */ 0, new Listener(new CountDownLatch(1)), /* isScreenshotRequested= */ false); assertThat(mInjector.isBugreportStarted()).isTrue(); } @Test public void testStartBugreport_throwsForNonAdminUser() throws Exception { when(mMockUserManager.isUserAdmin(anyInt())).thenReturn(false); Loading Loading @@ -317,8 +351,12 @@ public class BugreportManagerServiceImplTest { private static class TestInjector extends BugreportManagerServiceImpl.Injector { private static final String SYSTEM_PROPERTY_BUGREPORT_START = "ctl.start"; private static final String SYSTEM_PROPERTY_BUGREPORT_STOP = "ctl.stop"; private final UserManager mUserManager; private final DevicePolicyManager mDevicePolicyManager; private boolean mBugreportStarted = false; TestInjector(Context context, ArraySet<String> allowlistedPackages, AtomicFile mappingFile, UserManager um, DevicePolicyManager dpm) { Loading @@ -336,5 +374,20 @@ public class BugreportManagerServiceImplTest { public DevicePolicyManager getDevicePolicyManager() { return mDevicePolicyManager; } @Override public void setSystemProperty(String key, String value) { // Calling SystemProperties.set() will throw a RuntimeException due to permission error. // Instead, we are just marking a flag to store the state for testing. if (SYSTEM_PROPERTY_BUGREPORT_START.equals(key)) { mBugreportStarted = true; } else if (SYSTEM_PROPERTY_BUGREPORT_STOP.equals(key)) { mBugreportStarted = false; } } public boolean isBugreportStarted() { return mBugreportStarted; } } }