diff options
| -rw-r--r-- | services/core/java/com/android/server/os/BugreportManagerServiceImpl.java | 8 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java | 59 |
2 files changed, 62 insertions, 5 deletions
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java index 4f86adfe2d8d..4eb8b2b980cb 100644 --- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java +++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java @@ -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) { @@ -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; @@ -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) diff --git a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java index e0ef035de735..a6f2196cf05b 100644 --- a/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java +++ b/services/tests/servicestests/src/com/android/server/os/BugreportManagerServiceImplTest.java @@ -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; @@ -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; @@ -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(); @@ -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; @@ -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. @@ -190,6 +197,33 @@ public class BugreportManagerServiceImplTest { } @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); @@ -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) { @@ -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; + } } } |