Loading core/java/android/app/admin/DevicePolicyManager.java +24 −6 Original line number Diff line number Diff line Loading @@ -8260,6 +8260,11 @@ public class DevicePolicyManager { * actual package file remain. This function can be called by a device owner, profile owner, or * by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via * {@link #setDelegatedScopes}. * <p> * This method can be called on the {@link DevicePolicyManager} instance, returned by * {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner * of an organization-owned managed profile and the package must be a system package. If called * on the parent instance, then the package is hidden or unhidden in the personal profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if the caller is a package access delegate. Loading @@ -8267,17 +8272,20 @@ public class DevicePolicyManager { * @param hidden {@code true} if the package should be hidden, {@code false} if it should be * unhidden. * @return boolean Whether the hidden setting of the package was successfully updated. * @throws SecurityException if {@code admin} is not a device or profile owner. * @throws SecurityException if {@code admin} is not a device or profile owner or if called on * the parent profile and the {@code admin} is not a profile owner of an * organization-owned managed profile. * @throws IllegalArgumentException if called on the parent profile and the package provided * is not a system package. * @see #setDelegatedScopes * @see #DELEGATION_PACKAGE_ACCESS */ public boolean setApplicationHidden(@NonNull ComponentName admin, String packageName, boolean hidden) { throwIfParentInstance("setApplicationHidden"); if (mService != null) { try { return mService.setApplicationHidden(admin, mContext.getPackageName(), packageName, hidden); hidden, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading @@ -8289,20 +8297,30 @@ public class DevicePolicyManager { * Determine if a package is hidden. This function can be called by a device owner, profile * owner, or by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via * {@link #setDelegatedScopes}. * <p> * This method can be called on the {@link DevicePolicyManager} instance, returned by * {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner * of an organization-owned managed profile and the package must be a system package. If called * on the parent instance, this will determine whether the package is hidden or unhidden in the * personal profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if the caller is a package access delegate. * @param packageName The name of the package to retrieve the hidden status of. * @return boolean {@code true} if the package is hidden, {@code false} otherwise. * @throws SecurityException if {@code admin} is not a device or profile owner. * @throws SecurityException if {@code admin} is not a device or profile owner or if called on * the parent profile and the {@code admin} is not a profile owner of an * organization-owned managed profile. * @throws IllegalArgumentException if called on the parent profile and the package provided * is not a system package. * @see #setDelegatedScopes * @see #DELEGATION_PACKAGE_ACCESS */ public boolean isApplicationHidden(@NonNull ComponentName admin, String packageName) { throwIfParentInstance("isApplicationHidden"); if (mService != null) { try { return mService.isApplicationHidden(admin, mContext.getPackageName(), packageName); return mService.isApplicationHidden(admin, mContext.getPackageName(), packageName, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading core/java/android/app/admin/IDevicePolicyManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -233,8 +233,8 @@ interface IDevicePolicyManager { boolean isNotificationListenerServicePermitted(in String packageName, int userId); Intent createAdminSupportIntent(in String restriction); boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden); boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName); boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden, boolean parent); boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean parent); UserHandle createAndManageUser(in ComponentName who, in String name, in ComponentName profileOwner, in PersistableBundle adminExtras, in int flags); boolean removeUser(in ComponentName who, in UserHandle userHandle); Loading services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +45 −24 Original line number Diff line number Diff line Loading @@ -10737,30 +10737,35 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean setApplicationHidden(ComponentName who, String callerPackage, String packageName, boolean hidden) { int callingUserId = UserHandle.getCallingUserId(); boolean result = false; boolean hidden, boolean parent) { final int userId = parent ? getProfileParentId(UserHandle.getCallingUserId()) : UserHandle.getCallingUserId(); boolean result; synchronized (getLockObject()) { // Ensure the caller is a DO/PO or a package access delegate. enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_PACKAGE_ACCESS); long id = mInjector.binderClearCallingIdentity(); try { result = mIPackageManager .setApplicationHiddenSettingAsUser(packageName, hidden, callingUserId); } catch (RemoteException re) { // shouldn't happen Slog.e(LOG_TAG, "Failed to setApplicationHiddenSetting", re); } finally { mInjector.binderRestoreCallingIdentity(id); if (parent) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent); // Ensure the package provided is a system package, this is to ensure that this // API cannot be used to leak if certain non-system package exists in the person // profile. mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(packageName, hidden, userId)); } result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager .setApplicationHiddenSettingAsUser(packageName, hidden, userId)); } final boolean isDelegate = (who == null); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_APPLICATION_HIDDEN) .setAdmin(callerPackage) .setBoolean(isDelegate) .setBoolean(parent) .setStrings(packageName, hidden ? "hidden" : "not_hidden") .write(); return result; Loading @@ -10768,24 +10773,40 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isApplicationHidden(ComponentName who, String callerPackage, String packageName) { int callingUserId = UserHandle.getCallingUserId(); String packageName, boolean parent) { final int userId = parent ? getProfileParentId(UserHandle.getCallingUserId()) : UserHandle.getCallingUserId(); synchronized (getLockObject()) { // Ensure the caller is a DO/PO or a package access delegate. enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_PACKAGE_ACCESS); long id = mInjector.binderClearCallingIdentity(); try { return mIPackageManager.getApplicationHiddenSettingAsUser( packageName, callingUserId); } catch (RemoteException re) { // shouldn't happen Slog.e(LOG_TAG, "Failed to getApplicationHiddenSettingAsUser", re); } finally { mInjector.binderRestoreCallingIdentity(id); if (parent) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent); // Ensure the package provided is a system package. mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(packageName, false, userId)); } return false; return mInjector.binderWithCleanCallingIdentity( () -> mIPackageManager.getApplicationHiddenSettingAsUser(packageName, userId)); } } private void enforcePackageIsSystemPackage(String packageName, boolean hidden, int userId) throws RemoteException { int flags = PackageManager.MATCH_SYSTEM_ONLY; // If the package is currently hidden then it is considered uninstalled and // the MATCH_UNINSTALLED_PACKAGES flag has to be added. if (!hidden) { flags |= PackageManager.MATCH_UNINSTALLED_PACKAGES; } PackageInfo packageInfo = mIPackageManager.getPackageInfo(packageName, flags, userId); if (packageInfo == null || !packageInfo.applicationInfo.isSystemApp()) { throw new IllegalArgumentException( "The provided package is not a system package"); } } Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +57 −0 Original line number Diff line number Diff line Loading @@ -2183,6 +2183,63 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertThat(actualAccounts).containsExactlyElementsIn(expectedAccounts); } public void testSetApplicationHiddenWithDO() throws Exception { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); mContext.packageName = admin1.getPackageName(); setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); String packageName = "com.google.android.test"; dpm.setApplicationHidden(admin1, packageName, true); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, true, UserHandle.USER_SYSTEM); dpm.setApplicationHidden(admin1, packageName, false); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, false, UserHandle.USER_SYSTEM); verify(getServices().ipackageManager, never()).getPackageInfo(packageName, PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); verify(getServices().ipackageManager, never()).getPackageInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); } public void testSetApplicationHiddenWithPOOfOrganizationOwnedDevice() throws Exception { final int MANAGED_PROFILE_USER_ID = DpmMockContext.CALLER_USER_HANDLE; final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE); mContext.packageName = admin1.getPackageName(); setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); String packageName = "com.google.android.test"; PackageInfo packageInfo = new PackageInfo(); packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; when(getServices().userManager.getProfileParent(MANAGED_PROFILE_USER_ID)) .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); when(getServices().ipackageManager.getPackageInfo(packageName, PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM)).thenReturn( packageInfo); when(getServices().ipackageManager.getPackageInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM)).thenReturn(packageInfo); parentDpm.setApplicationHidden(admin1, packageName, true); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, true, UserHandle.USER_SYSTEM); parentDpm.setApplicationHidden(admin1, packageName, false); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, false, UserHandle.USER_SYSTEM); } public void testGetMacAddress() throws Exception { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); Loading Loading
core/java/android/app/admin/DevicePolicyManager.java +24 −6 Original line number Diff line number Diff line Loading @@ -8260,6 +8260,11 @@ public class DevicePolicyManager { * actual package file remain. This function can be called by a device owner, profile owner, or * by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via * {@link #setDelegatedScopes}. * <p> * This method can be called on the {@link DevicePolicyManager} instance, returned by * {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner * of an organization-owned managed profile and the package must be a system package. If called * on the parent instance, then the package is hidden or unhidden in the personal profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if the caller is a package access delegate. Loading @@ -8267,17 +8272,20 @@ public class DevicePolicyManager { * @param hidden {@code true} if the package should be hidden, {@code false} if it should be * unhidden. * @return boolean Whether the hidden setting of the package was successfully updated. * @throws SecurityException if {@code admin} is not a device or profile owner. * @throws SecurityException if {@code admin} is not a device or profile owner or if called on * the parent profile and the {@code admin} is not a profile owner of an * organization-owned managed profile. * @throws IllegalArgumentException if called on the parent profile and the package provided * is not a system package. * @see #setDelegatedScopes * @see #DELEGATION_PACKAGE_ACCESS */ public boolean setApplicationHidden(@NonNull ComponentName admin, String packageName, boolean hidden) { throwIfParentInstance("setApplicationHidden"); if (mService != null) { try { return mService.setApplicationHidden(admin, mContext.getPackageName(), packageName, hidden); hidden, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading @@ -8289,20 +8297,30 @@ public class DevicePolicyManager { * Determine if a package is hidden. This function can be called by a device owner, profile * owner, or by a delegate given the {@link #DELEGATION_PACKAGE_ACCESS} scope via * {@link #setDelegatedScopes}. * <p> * This method can be called on the {@link DevicePolicyManager} instance, returned by * {@link #getParentProfileInstance(ComponentName)}, where the caller must be the profile owner * of an organization-owned managed profile and the package must be a system package. If called * on the parent instance, this will determine whether the package is hidden or unhidden in the * personal profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or * {@code null} if the caller is a package access delegate. * @param packageName The name of the package to retrieve the hidden status of. * @return boolean {@code true} if the package is hidden, {@code false} otherwise. * @throws SecurityException if {@code admin} is not a device or profile owner. * @throws SecurityException if {@code admin} is not a device or profile owner or if called on * the parent profile and the {@code admin} is not a profile owner of an * organization-owned managed profile. * @throws IllegalArgumentException if called on the parent profile and the package provided * is not a system package. * @see #setDelegatedScopes * @see #DELEGATION_PACKAGE_ACCESS */ public boolean isApplicationHidden(@NonNull ComponentName admin, String packageName) { throwIfParentInstance("isApplicationHidden"); if (mService != null) { try { return mService.isApplicationHidden(admin, mContext.getPackageName(), packageName); return mService.isApplicationHidden(admin, mContext.getPackageName(), packageName, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -233,8 +233,8 @@ interface IDevicePolicyManager { boolean isNotificationListenerServicePermitted(in String packageName, int userId); Intent createAdminSupportIntent(in String restriction); boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden); boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName); boolean setApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean hidden, boolean parent); boolean isApplicationHidden(in ComponentName admin, in String callerPackage, in String packageName, boolean parent); UserHandle createAndManageUser(in ComponentName who, in String name, in ComponentName profileOwner, in PersistableBundle adminExtras, in int flags); boolean removeUser(in ComponentName who, in UserHandle userHandle); Loading
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +45 −24 Original line number Diff line number Diff line Loading @@ -10737,30 +10737,35 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean setApplicationHidden(ComponentName who, String callerPackage, String packageName, boolean hidden) { int callingUserId = UserHandle.getCallingUserId(); boolean result = false; boolean hidden, boolean parent) { final int userId = parent ? getProfileParentId(UserHandle.getCallingUserId()) : UserHandle.getCallingUserId(); boolean result; synchronized (getLockObject()) { // Ensure the caller is a DO/PO or a package access delegate. enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_PACKAGE_ACCESS); long id = mInjector.binderClearCallingIdentity(); try { result = mIPackageManager .setApplicationHiddenSettingAsUser(packageName, hidden, callingUserId); } catch (RemoteException re) { // shouldn't happen Slog.e(LOG_TAG, "Failed to setApplicationHiddenSetting", re); } finally { mInjector.binderRestoreCallingIdentity(id); if (parent) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent); // Ensure the package provided is a system package, this is to ensure that this // API cannot be used to leak if certain non-system package exists in the person // profile. mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(packageName, hidden, userId)); } result = mInjector.binderWithCleanCallingIdentity(() -> mIPackageManager .setApplicationHiddenSettingAsUser(packageName, hidden, userId)); } final boolean isDelegate = (who == null); DevicePolicyEventLogger .createEvent(DevicePolicyEnums.SET_APPLICATION_HIDDEN) .setAdmin(callerPackage) .setBoolean(isDelegate) .setBoolean(parent) .setStrings(packageName, hidden ? "hidden" : "not_hidden") .write(); return result; Loading @@ -10768,24 +10773,40 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean isApplicationHidden(ComponentName who, String callerPackage, String packageName) { int callingUserId = UserHandle.getCallingUserId(); String packageName, boolean parent) { final int userId = parent ? getProfileParentId(UserHandle.getCallingUserId()) : UserHandle.getCallingUserId(); synchronized (getLockObject()) { // Ensure the caller is a DO/PO or a package access delegate. enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, DELEGATION_PACKAGE_ACCESS); long id = mInjector.binderClearCallingIdentity(); try { return mIPackageManager.getApplicationHiddenSettingAsUser( packageName, callingUserId); } catch (RemoteException re) { // shouldn't happen Slog.e(LOG_TAG, "Failed to getApplicationHiddenSettingAsUser", re); } finally { mInjector.binderRestoreCallingIdentity(id); if (parent) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_ORGANIZATION_OWNED_PROFILE_OWNER, parent); // Ensure the package provided is a system package. mInjector.binderWithCleanCallingIdentity(() -> enforcePackageIsSystemPackage(packageName, false, userId)); } return false; return mInjector.binderWithCleanCallingIdentity( () -> mIPackageManager.getApplicationHiddenSettingAsUser(packageName, userId)); } } private void enforcePackageIsSystemPackage(String packageName, boolean hidden, int userId) throws RemoteException { int flags = PackageManager.MATCH_SYSTEM_ONLY; // If the package is currently hidden then it is considered uninstalled and // the MATCH_UNINSTALLED_PACKAGES flag has to be added. if (!hidden) { flags |= PackageManager.MATCH_UNINSTALLED_PACKAGES; } PackageInfo packageInfo = mIPackageManager.getPackageInfo(packageName, flags, userId); if (packageInfo == null || !packageInfo.applicationInfo.isSystemApp()) { throw new IllegalArgumentException( "The provided package is not a system package"); } } Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +57 −0 Original line number Diff line number Diff line Loading @@ -2183,6 +2183,63 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertThat(actualAccounts).containsExactlyElementsIn(expectedAccounts); } public void testSetApplicationHiddenWithDO() throws Exception { mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; setupDeviceOwner(); mContext.packageName = admin1.getPackageName(); setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); String packageName = "com.google.android.test"; dpm.setApplicationHidden(admin1, packageName, true); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, true, UserHandle.USER_SYSTEM); dpm.setApplicationHidden(admin1, packageName, false); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, false, UserHandle.USER_SYSTEM); verify(getServices().ipackageManager, never()).getPackageInfo(packageName, PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); verify(getServices().ipackageManager, never()).getPackageInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); } public void testSetApplicationHiddenWithPOOfOrganizationOwnedDevice() throws Exception { final int MANAGED_PROFILE_USER_ID = DpmMockContext.CALLER_USER_HANDLE; final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE); mContext.packageName = admin1.getPackageName(); setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); String packageName = "com.google.android.test"; PackageInfo packageInfo = new PackageInfo(); packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; when(getServices().userManager.getProfileParent(MANAGED_PROFILE_USER_ID)) .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); when(getServices().ipackageManager.getPackageInfo(packageName, PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM)).thenReturn( packageInfo); when(getServices().ipackageManager.getPackageInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM)).thenReturn(packageInfo); parentDpm.setApplicationHidden(admin1, packageName, true); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, true, UserHandle.USER_SYSTEM); parentDpm.setApplicationHidden(admin1, packageName, false); verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, false, UserHandle.USER_SYSTEM); } public void testGetMacAddress() throws Exception { mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); Loading