Loading services/core/java/com/android/server/appop/AppOpsService.java +9 −0 Original line number Diff line number Diff line Loading @@ -1180,6 +1180,8 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.pkgOps.put(packageName, new Ops(packageName, uidState)); } createSandboxUidStateIfNotExistsForAppLocked(uid); } } } Loading Loading @@ -1261,6 +1263,8 @@ public class AppOpsService extends IAppOpsService.Stub { ops.put(code, new Op(uidState, packageName, code, uid)); } } createSandboxUidStateIfNotExistsForAppLocked(uid); } /** Loading Loading @@ -4011,6 +4015,11 @@ public class AppOpsService extends IAppOpsService.Stub { return uidState; } private void createSandboxUidStateIfNotExistsForAppLocked(int uid) { final int sandboxUid = Process.toSdkSandboxUid(uid); getUidStateLocked(sandboxUid, true); } private void updateAppWidgetVisibility(SparseArray<String> uidPackageNames, boolean visible) { synchronized (this) { getUidStateTracker().updateAppWidgetVisibility(uidPackageNames, visible); Loading services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java +62 −11 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ import static android.app.AppOpsManager.MODE_ERRORED; import static android.app.AppOpsManager.OP_COARSE_LOCATION; import static android.app.AppOpsManager.OP_FLAGS_ALL; import static android.app.AppOpsManager.OP_FLAG_SELF; import static android.app.AppOpsManager.OP_READ_DEVICE_IDENTIFIERS; import static android.app.AppOpsManager.OP_READ_SMS; import static android.app.AppOpsManager.OP_TAKE_AUDIO_FOCUS; import static android.app.AppOpsManager.OP_WIFI_SCAN; import static android.app.AppOpsManager.OP_WRITE_SMS; import static android.os.UserHandle.getAppId; Loading Loading @@ -49,8 +51,10 @@ import static org.mockito.ArgumentMatchers.nullable; import android.app.AppOpsManager; import android.app.AppOpsManager.OpEntry; import android.app.AppOpsManager.PackageOps; import android.app.SyncNotedAppOp; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Handler; import android.os.HandlerThread; Loading @@ -58,6 +62,7 @@ import android.os.Process; import android.permission.PermissionManager; import android.provider.Settings; import android.util.ArrayMap; import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; Loading @@ -79,7 +84,6 @@ import org.junit.runner.RunWith; import org.mockito.quality.Strictness; import java.io.File; import java.util.Collections; import java.util.List; import java.util.Map; Loading @@ -99,12 +103,15 @@ public class AppOpsServiceTest { private static final Context sContext = InstrumentationRegistry.getTargetContext(); private static final String sMyPackageName = sContext.getOpPackageName(); private static final String sSdkSandboxPackageName = sContext.getPackageManager() .getSdkSandboxPackageName(); private File mStorageFile; private File mRecentAccessesFile; private Handler mHandler; private AppOpsService mAppOpsService; private int mMyUid; private int mSdkSandboxPackageUid; private long mTestStartMillis; private StaticMockitoSession mMockingSession; Loading Loading @@ -132,6 +139,7 @@ public class AppOpsServiceTest { handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mMyUid = Process.myUid(); mSdkSandboxPackageUid = resolveSdkSandboxPackageUid(); initializeStaticMocks(); Loading @@ -152,6 +160,39 @@ public class AppOpsServiceTest { mMockingSession.finishMocking(); } private static int resolveSdkSandboxPackageUid() { try { return sContext.getPackageManager().getPackageUid( sSdkSandboxPackageName, PackageManager.PackageInfoFlags.of(0) ); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Can't resolve sandbox package uid", e); return Process.INVALID_UID; } } private static void mockGetPackage( PackageManagerInternal managerMock, String packageName ) { AndroidPackage packageMock = mock(AndroidPackage.class); when(managerMock.getPackage(packageName)).thenReturn(packageMock); } private static void mockGetPackageStateInternal( PackageManagerInternal managerMock, String packageName, int uid ) { PackageStateInternal packageStateInternalMock = mock(PackageStateInternal.class); when(packageStateInternalMock.isPrivileged()).thenReturn(false); when(packageStateInternalMock.getAppId()).thenReturn(uid); when(packageStateInternalMock.getAndroidPackage()).thenReturn(mock(AndroidPackage.class)); when(managerMock.getPackageStateInternal(packageName)) .thenReturn(packageStateInternalMock); } private void initializeStaticMocks() { mMockingSession = mockitoSession() .strictness(Strictness.LENIENT) Loading @@ -163,16 +204,11 @@ public class AppOpsServiceTest { // Mock LocalServices.getService(PackageManagerInternal.class).getPackageStateInternal // and getPackage dependency needed by AppOpsService PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class); AndroidPackage mockMyPkg = mock(AndroidPackage.class); when(mockMyPkg.getAttributions()).thenReturn(Collections.emptyList()); PackageStateInternal mockMyPSInternal = mock(PackageStateInternal.class); when(mockMyPSInternal.isPrivileged()).thenReturn(false); when(mockMyPSInternal.getAppId()).thenReturn(mMyUid); when(mockMyPSInternal.getAndroidPackage()).thenReturn(mockMyPkg); when(mockPackageManagerInternal.getPackageStateInternal(sMyPackageName)) .thenReturn(mockMyPSInternal); when(mockPackageManagerInternal.getPackage(sMyPackageName)).thenReturn(mockMyPkg); mockGetPackage(mockPackageManagerInternal, sMyPackageName); mockGetPackageStateInternal(mockPackageManagerInternal, sMyPackageName, mMyUid); mockGetPackage(mockPackageManagerInternal, sSdkSandboxPackageName); mockGetPackageStateInternal(mockPackageManagerInternal, sSdkSandboxPackageName, mSdkSandboxPackageUid); when(mockPackageManagerInternal.getPackageUid(eq(sMyPackageName), anyLong(), eq(getUserId(mMyUid)))).thenReturn(mMyUid); doReturn(mockPackageManagerInternal).when( Loading Loading @@ -233,6 +269,21 @@ public class AppOpsServiceTest { assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED); } @Test public void testNoteOperationFromSdkSandbox() { int sandboxUid = Process.toSdkSandboxUid(mMyUid); // Note an op that's allowed. SyncNotedAppOp allowedResult = mAppOpsService.noteOperation(OP_TAKE_AUDIO_FOCUS, sandboxUid, sSdkSandboxPackageName, null, false, null, false); assertThat(allowedResult.getOpMode()).isEqualTo(MODE_ALLOWED); // Note another op that's not allowed. SyncNotedAppOp erroredResult = mAppOpsService.noteOperation(OP_READ_DEVICE_IDENTIFIERS, sandboxUid, sSdkSandboxPackageName, null, false, null, false); assertThat(erroredResult.getOpMode()).isEqualTo(MODE_ERRORED); } /** * Tests the scenario where an operation's permission is controlled by another operation. * For example the results of a WIFI_SCAN can be used to infer the location of a user, so the Loading Loading
services/core/java/com/android/server/appop/AppOpsService.java +9 −0 Original line number Diff line number Diff line Loading @@ -1180,6 +1180,8 @@ public class AppOpsService extends IAppOpsService.Stub { uidState.pkgOps.put(packageName, new Ops(packageName, uidState)); } createSandboxUidStateIfNotExistsForAppLocked(uid); } } } Loading Loading @@ -1261,6 +1263,8 @@ public class AppOpsService extends IAppOpsService.Stub { ops.put(code, new Op(uidState, packageName, code, uid)); } } createSandboxUidStateIfNotExistsForAppLocked(uid); } /** Loading Loading @@ -4011,6 +4015,11 @@ public class AppOpsService extends IAppOpsService.Stub { return uidState; } private void createSandboxUidStateIfNotExistsForAppLocked(int uid) { final int sandboxUid = Process.toSdkSandboxUid(uid); getUidStateLocked(sandboxUid, true); } private void updateAppWidgetVisibility(SparseArray<String> uidPackageNames, boolean visible) { synchronized (this) { getUidStateTracker().updateAppWidgetVisibility(uidPackageNames, visible); Loading
services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java +62 −11 Original line number Diff line number Diff line Loading @@ -20,7 +20,9 @@ import static android.app.AppOpsManager.MODE_ERRORED; import static android.app.AppOpsManager.OP_COARSE_LOCATION; import static android.app.AppOpsManager.OP_FLAGS_ALL; import static android.app.AppOpsManager.OP_FLAG_SELF; import static android.app.AppOpsManager.OP_READ_DEVICE_IDENTIFIERS; import static android.app.AppOpsManager.OP_READ_SMS; import static android.app.AppOpsManager.OP_TAKE_AUDIO_FOCUS; import static android.app.AppOpsManager.OP_WIFI_SCAN; import static android.app.AppOpsManager.OP_WRITE_SMS; import static android.os.UserHandle.getAppId; Loading Loading @@ -49,8 +51,10 @@ import static org.mockito.ArgumentMatchers.nullable; import android.app.AppOpsManager; import android.app.AppOpsManager.OpEntry; import android.app.AppOpsManager.PackageOps; import android.app.SyncNotedAppOp; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.os.Handler; import android.os.HandlerThread; Loading @@ -58,6 +62,7 @@ import android.os.Process; import android.permission.PermissionManager; import android.provider.Settings; import android.util.ArrayMap; import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; Loading @@ -79,7 +84,6 @@ import org.junit.runner.RunWith; import org.mockito.quality.Strictness; import java.io.File; import java.util.Collections; import java.util.List; import java.util.Map; Loading @@ -99,12 +103,15 @@ public class AppOpsServiceTest { private static final Context sContext = InstrumentationRegistry.getTargetContext(); private static final String sMyPackageName = sContext.getOpPackageName(); private static final String sSdkSandboxPackageName = sContext.getPackageManager() .getSdkSandboxPackageName(); private File mStorageFile; private File mRecentAccessesFile; private Handler mHandler; private AppOpsService mAppOpsService; private int mMyUid; private int mSdkSandboxPackageUid; private long mTestStartMillis; private StaticMockitoSession mMockingSession; Loading Loading @@ -132,6 +139,7 @@ public class AppOpsServiceTest { handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mMyUid = Process.myUid(); mSdkSandboxPackageUid = resolveSdkSandboxPackageUid(); initializeStaticMocks(); Loading @@ -152,6 +160,39 @@ public class AppOpsServiceTest { mMockingSession.finishMocking(); } private static int resolveSdkSandboxPackageUid() { try { return sContext.getPackageManager().getPackageUid( sSdkSandboxPackageName, PackageManager.PackageInfoFlags.of(0) ); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Can't resolve sandbox package uid", e); return Process.INVALID_UID; } } private static void mockGetPackage( PackageManagerInternal managerMock, String packageName ) { AndroidPackage packageMock = mock(AndroidPackage.class); when(managerMock.getPackage(packageName)).thenReturn(packageMock); } private static void mockGetPackageStateInternal( PackageManagerInternal managerMock, String packageName, int uid ) { PackageStateInternal packageStateInternalMock = mock(PackageStateInternal.class); when(packageStateInternalMock.isPrivileged()).thenReturn(false); when(packageStateInternalMock.getAppId()).thenReturn(uid); when(packageStateInternalMock.getAndroidPackage()).thenReturn(mock(AndroidPackage.class)); when(managerMock.getPackageStateInternal(packageName)) .thenReturn(packageStateInternalMock); } private void initializeStaticMocks() { mMockingSession = mockitoSession() .strictness(Strictness.LENIENT) Loading @@ -163,16 +204,11 @@ public class AppOpsServiceTest { // Mock LocalServices.getService(PackageManagerInternal.class).getPackageStateInternal // and getPackage dependency needed by AppOpsService PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class); AndroidPackage mockMyPkg = mock(AndroidPackage.class); when(mockMyPkg.getAttributions()).thenReturn(Collections.emptyList()); PackageStateInternal mockMyPSInternal = mock(PackageStateInternal.class); when(mockMyPSInternal.isPrivileged()).thenReturn(false); when(mockMyPSInternal.getAppId()).thenReturn(mMyUid); when(mockMyPSInternal.getAndroidPackage()).thenReturn(mockMyPkg); when(mockPackageManagerInternal.getPackageStateInternal(sMyPackageName)) .thenReturn(mockMyPSInternal); when(mockPackageManagerInternal.getPackage(sMyPackageName)).thenReturn(mockMyPkg); mockGetPackage(mockPackageManagerInternal, sMyPackageName); mockGetPackageStateInternal(mockPackageManagerInternal, sMyPackageName, mMyUid); mockGetPackage(mockPackageManagerInternal, sSdkSandboxPackageName); mockGetPackageStateInternal(mockPackageManagerInternal, sSdkSandboxPackageName, mSdkSandboxPackageUid); when(mockPackageManagerInternal.getPackageUid(eq(sMyPackageName), anyLong(), eq(getUserId(mMyUid)))).thenReturn(mMyUid); doReturn(mockPackageManagerInternal).when( Loading Loading @@ -233,6 +269,21 @@ public class AppOpsServiceTest { assertContainsOp(loggedOps, OP_WRITE_SMS, -1, mTestStartMillis, MODE_ERRORED); } @Test public void testNoteOperationFromSdkSandbox() { int sandboxUid = Process.toSdkSandboxUid(mMyUid); // Note an op that's allowed. SyncNotedAppOp allowedResult = mAppOpsService.noteOperation(OP_TAKE_AUDIO_FOCUS, sandboxUid, sSdkSandboxPackageName, null, false, null, false); assertThat(allowedResult.getOpMode()).isEqualTo(MODE_ALLOWED); // Note another op that's not allowed. SyncNotedAppOp erroredResult = mAppOpsService.noteOperation(OP_READ_DEVICE_IDENTIFIERS, sandboxUid, sSdkSandboxPackageName, null, false, null, false); assertThat(erroredResult.getOpMode()).isEqualTo(MODE_ERRORED); } /** * Tests the scenario where an operation's permission is controlled by another operation. * For example the results of a WIFI_SCAN can be used to infer the location of a user, so the Loading