Loading api/test-current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -6305,7 +6305,7 @@ package android.app.admin { method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); method public boolean isBackupServiceEnabled(android.content.ComponentName); method public deprecated boolean isCallerApplicationRestrictionsManagingPackage(); method public boolean isDefaultInputMethodSetByOwner(android.os.UserHandle); method public boolean isCurrentInputMethodSetByOwner(); method public boolean isDeviceManaged(); method public boolean isDeviceOwnerApp(java.lang.String); method public boolean isLockTaskPermitted(java.lang.String); core/java/android/app/admin/DevicePolicyManager.java +6 −11 Original line number Diff line number Diff line Loading @@ -7937,34 +7937,29 @@ public class DevicePolicyManager { } /** * Called by the system to find out whether the user's IME was set by the device/profile owner * or the user. * Called by the system to find out whether the current user's IME was set by the device/profile * owner or the user. * * @param user The user for whom to retrieve information. * @return {@code true} if the user's IME was set by the device or profile owner, {@code false} * otherwise. * @throws SecurityException if the caller does not have permission to retrieve information * about the given user's default IME. Device Owner and Profile Owner can retrieve * information about the user they run on; the System can retrieve information about any * user. * @throws SecurityException if the caller is not the device owner/profile owner. * * @hide */ @TestApi public boolean isDefaultInputMethodSetByOwner(@NonNull UserHandle user) { public boolean isCurrentInputMethodSetByOwner() { try { return mService.isDefaultInputMethodSetByOwner(user); return mService.isCurrentInputMethodSetByOwner(); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Called by the system to get a list of CA certificates that were installed by the device or * profile owner. * * <p> The caller must be the target user's Device Owner/Profile owner or hold the * <p> The caller must be the target user's device owner/profile Owner or hold the * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. * * @param user The user for whom to retrieve information. Loading core/java/android/app/admin/IDevicePolicyManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -349,6 +349,6 @@ interface IDevicePolicyManager { boolean isResetPasswordTokenActive(in ComponentName admin); boolean resetPasswordWithToken(in ComponentName admin, String password, in byte[] token, int flags); boolean isDefaultInputMethodSetByOwner(in UserHandle user); boolean isCurrentInputMethodSetByOwner(); StringParceledListSlice getOwnerInstalledCaCerts(in UserHandle user); } services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +18 −23 Original line number Diff line number Diff line Loading @@ -243,7 +243,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_ADMIN_BROADCAST_PENDING = "admin-broadcast-pending"; private static final String TAG_DEFAULT_INPUT_METHOD_SET = "default-ime-set"; private static final String TAG_CURRENT_INPUT_METHOD_SET = "current-ime-set"; private static final String TAG_OWNER_INSTALLED_CA_CERT = "owner-installed-ca-cert"; Loading Loading @@ -509,7 +509,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long mLastNetworkLogsRetrievalTime = -1; boolean mDefaultInputMethodSet = false; boolean mCurrentInputMethodSet = false; // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. Set<String> mOwnerInstalledCaCerts = new ArraySet<>(); Loading Loading @@ -2607,9 +2607,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endTag(null, TAG_PASSWORD_TOKEN_HANDLE); } if (policy.mDefaultInputMethodSet) { out.startTag(null, TAG_DEFAULT_INPUT_METHOD_SET); out.endTag(null, TAG_DEFAULT_INPUT_METHOD_SET); if (policy.mCurrentInputMethodSet) { out.startTag(null, TAG_CURRENT_INPUT_METHOD_SET); out.endTag(null, TAG_CURRENT_INPUT_METHOD_SET); } for (final String cert : policy.mOwnerInstalledCaCerts) { Loading Loading @@ -2828,8 +2828,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (TAG_PASSWORD_TOKEN_HANDLE.equals(tag)) { policy.mPasswordTokenHandle = Long.parseLong( parser.getAttributeValue(null, ATTR_VALUE)); } else if (TAG_DEFAULT_INPUT_METHOD_SET.equals(tag)) { policy.mDefaultInputMethodSet = true; } else if (TAG_CURRENT_INPUT_METHOD_SET.equals(tag)) { policy.mCurrentInputMethodSet = true; } else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) { policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS)); } else { Loading Loading @@ -6680,7 +6680,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; policyData.mCurrentInputMethodSet = false; saveSettingsLocked(userId); final DevicePolicyData systemPolicyData = getUserData(UserHandle.USER_SYSTEM); systemPolicyData.mLastSecurityLogRetrievalTime = -1; Loading Loading @@ -6785,7 +6785,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin.defaultEnabledRestrictionsAlreadySet.clear(); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; policyData.mCurrentInputMethodSet = false; policyData.mOwnerInstalledCaCerts.clear(); saveSettingsLocked(userId); clearUserPoliciesLocked(userId); Loading Loading @@ -7231,9 +7231,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforceManageUsers(); } private void enforceProfileOwnerOrSystemUser(ComponentName admin) { private void enforceProfileOwnerOrSystemUser() { synchronized (this) { if (getActiveAdminWithPolicyForUidLocked(admin, if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid()) != null) { return; Loading Loading @@ -8887,7 +8887,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // to trigger. This is a corner case that will have no impact in practice. mSetupContentObserver.addPendingChangeByOwnerLocked(callingUserId); } getUserData(callingUserId).mDefaultInputMethodSet = true; getUserData(callingUserId).mCurrentInputMethodSet = true; saveSettingsLocked(callingUserId); } mInjector.settingsSecurePutStringForUser(setting, value, callingUserId); Loading Loading @@ -9071,13 +9071,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (mDefaultImeChanged.equals(uri)) { synchronized (DevicePolicyManagerService.this) { if (mUserIdsWithPendingChangesByOwner.contains(userId)) { // This change notification was triggered by the owner changing the default // This change notification was triggered by the owner changing the current // IME. Ignore it. mUserIdsWithPendingChangesByOwner.remove(userId); } else { // This change notification was triggered by the user manually changing the // default IME. getUserData(userId).mDefaultInputMethodSet = false; // current IME. getUserData(userId).mCurrentInputMethodSet = false; saveSettingsLocked(userId); } } Loading Loading @@ -10962,14 +10962,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override public boolean isDefaultInputMethodSetByOwner(@NonNull UserHandle user) { final int userId = user.getIdentifier(); enforceProfileOwnerOrSystemUser(null); if (!isCallerWithSystemUid() && mInjector.userHandleGetCallingUserId() != userId) { throw new SecurityException( "Only the system can use this method to query information about another user"); } return getUserData(userId).mDefaultInputMethodSet; public boolean isCurrentInputMethodSetByOwner() { enforceProfileOwnerOrSystemUser(); return getUserData(mInjector.userHandleGetCallingUserId()).mCurrentInputMethodSet; } @Override Loading services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +125 −106 Original line number Diff line number Diff line Loading @@ -3807,143 +3807,162 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertTrue(dpm.clearResetPasswordToken(admin1)); } public void testIsDefaultInputMethodSetByOwnerForDeviceOwner() throws Exception { final String defaultIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri defaultImeUri = Settings.Secure.getUriFor(defaultIme); final UserHandle firstUser = UserHandle.SYSTEM; final UserHandle secondUser = UserHandle.of(DpmMockContext.CALLER_USER_HANDLE); public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception { final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); final int deviceOwnerUid = DpmMockContext.CALLER_SYSTEM_USER_UID; final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, DpmMockContext.SYSTEM_UID); final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); // Set up a Device Owner. mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; // Set up a device owner. mContext.binder.callingUid = deviceOwnerUid; setupDeviceOwner(); // First and second user set default IMEs manually. final long ident = mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First and second user set IMEs manually. mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Device Owner changes default IME for first user. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, UserHandle.USER_SYSTEM)) // Device owner changes IME for first user. mContext.binder.callingUid = deviceOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM)) .thenReturn("ime1"); dpm.setSecureSetting(admin1, defaultIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime2", dpm.setSecureSetting(admin1, currentIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2", UserHandle.USER_SYSTEM); reset(mContext.settings); dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Second user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Device Owner changes default IME for first user again. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, UserHandle.USER_SYSTEM)) dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Second user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // First user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Device owner changes IME for first user again. mContext.binder.callingUid = deviceOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM)) .thenReturn("ime2"); dpm.setSecureSetting(admin1, defaultIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime3", dpm.setSecureSetting(admin1, currentIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3", UserHandle.USER_SYSTEM); dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Restarting the DPMS should not lose information. initializeDpms(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Device Owner can find out whether it set the default IME itself. assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); // Device owner can find out whether it set the current IME itself. mContext.binder.callingUid = deviceOwnerUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Removing the Device Owner should clear the information that it set the default IME. // Removing the device owner should clear the information that it set the current IME. clearDeviceOwner(); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); } public void testIsDefaultInputMethodSetByOwnerForProfileOwner() throws Exception { final String defaultIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri defaultImeUri = Settings.Secure.getUriFor(defaultIme); final UserHandle firstUser = UserHandle.SYSTEM; final UserHandle secondUser = UserHandle.of(DpmMockContext.CALLER_USER_HANDLE); public void testIsCurrentInputMethodSetByOwnerForProfileOwner() throws Exception { final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); final int profileOwnerUid = DpmMockContext.CALLER_UID; final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, DpmMockContext.SYSTEM_UID); final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); // Set up a profile owner. mContext.binder.callingUid = profileOwnerUid; setupProfileOwner(); // First and second user set default IMEs manually. final long ident = mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First and second user set IMEs manually. mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Profile Owner changes default IME for second user. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, // Profile owner changes IME for second user. mContext.binder.callingUid = profileOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1"); dpm.setSecureSetting(admin1, defaultIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime2", dpm.setSecureSetting(admin1, currentIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2", DpmMockContext.CALLER_USER_HANDLE); reset(mContext.settings); dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Second user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Profile Owner changes default IME for second user again. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // First user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Second user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Profile owner changes IME for second user again. mContext.binder.callingUid = profileOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2"); dpm.setSecureSetting(admin1, defaultIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime3", dpm.setSecureSetting(admin1, currentIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3", DpmMockContext.CALLER_USER_HANDLE); dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Restarting the DPMS should not lose information. initializeDpms(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Profile Owner can find out whether it set the default IME itself. assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); // Profile owner can find out whether it set the current IME itself. mContext.binder.callingUid = profileOwnerUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Removing the Profile Owner should clear the information that it set the default IME. // Removing the profile owner should clear the information that it set the current IME. dpm.clearProfileOwner(admin1); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); } public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception { Loading Loading
api/test-current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -6305,7 +6305,7 @@ package android.app.admin { method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String); method public boolean isBackupServiceEnabled(android.content.ComponentName); method public deprecated boolean isCallerApplicationRestrictionsManagingPackage(); method public boolean isDefaultInputMethodSetByOwner(android.os.UserHandle); method public boolean isCurrentInputMethodSetByOwner(); method public boolean isDeviceManaged(); method public boolean isDeviceOwnerApp(java.lang.String); method public boolean isLockTaskPermitted(java.lang.String);
core/java/android/app/admin/DevicePolicyManager.java +6 −11 Original line number Diff line number Diff line Loading @@ -7937,34 +7937,29 @@ public class DevicePolicyManager { } /** * Called by the system to find out whether the user's IME was set by the device/profile owner * or the user. * Called by the system to find out whether the current user's IME was set by the device/profile * owner or the user. * * @param user The user for whom to retrieve information. * @return {@code true} if the user's IME was set by the device or profile owner, {@code false} * otherwise. * @throws SecurityException if the caller does not have permission to retrieve information * about the given user's default IME. Device Owner and Profile Owner can retrieve * information about the user they run on; the System can retrieve information about any * user. * @throws SecurityException if the caller is not the device owner/profile owner. * * @hide */ @TestApi public boolean isDefaultInputMethodSetByOwner(@NonNull UserHandle user) { public boolean isCurrentInputMethodSetByOwner() { try { return mService.isDefaultInputMethodSetByOwner(user); return mService.isCurrentInputMethodSetByOwner(); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } /** * Called by the system to get a list of CA certificates that were installed by the device or * profile owner. * * <p> The caller must be the target user's Device Owner/Profile owner or hold the * <p> The caller must be the target user's device owner/profile Owner or hold the * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. * * @param user The user for whom to retrieve information. Loading
core/java/android/app/admin/IDevicePolicyManager.aidl +1 −1 Original line number Diff line number Diff line Loading @@ -349,6 +349,6 @@ interface IDevicePolicyManager { boolean isResetPasswordTokenActive(in ComponentName admin); boolean resetPasswordWithToken(in ComponentName admin, String password, in byte[] token, int flags); boolean isDefaultInputMethodSetByOwner(in UserHandle user); boolean isCurrentInputMethodSetByOwner(); StringParceledListSlice getOwnerInstalledCaCerts(in UserHandle user); }
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +18 −23 Original line number Diff line number Diff line Loading @@ -243,7 +243,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private static final String TAG_ADMIN_BROADCAST_PENDING = "admin-broadcast-pending"; private static final String TAG_DEFAULT_INPUT_METHOD_SET = "default-ime-set"; private static final String TAG_CURRENT_INPUT_METHOD_SET = "current-ime-set"; private static final String TAG_OWNER_INSTALLED_CA_CERT = "owner-installed-ca-cert"; Loading Loading @@ -509,7 +509,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long mLastNetworkLogsRetrievalTime = -1; boolean mDefaultInputMethodSet = false; boolean mCurrentInputMethodSet = false; // TODO(b/35385311): Keep track of metadata in TrustedCertificateStore instead. Set<String> mOwnerInstalledCaCerts = new ArraySet<>(); Loading Loading @@ -2607,9 +2607,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endTag(null, TAG_PASSWORD_TOKEN_HANDLE); } if (policy.mDefaultInputMethodSet) { out.startTag(null, TAG_DEFAULT_INPUT_METHOD_SET); out.endTag(null, TAG_DEFAULT_INPUT_METHOD_SET); if (policy.mCurrentInputMethodSet) { out.startTag(null, TAG_CURRENT_INPUT_METHOD_SET); out.endTag(null, TAG_CURRENT_INPUT_METHOD_SET); } for (final String cert : policy.mOwnerInstalledCaCerts) { Loading Loading @@ -2828,8 +2828,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (TAG_PASSWORD_TOKEN_HANDLE.equals(tag)) { policy.mPasswordTokenHandle = Long.parseLong( parser.getAttributeValue(null, ATTR_VALUE)); } else if (TAG_DEFAULT_INPUT_METHOD_SET.equals(tag)) { policy.mDefaultInputMethodSet = true; } else if (TAG_CURRENT_INPUT_METHOD_SET.equals(tag)) { policy.mCurrentInputMethodSet = true; } else if (TAG_OWNER_INSTALLED_CA_CERT.equals(tag)) { policy.mOwnerInstalledCaCerts.add(parser.getAttributeValue(null, ATTR_ALIAS)); } else { Loading Loading @@ -6680,7 +6680,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; policyData.mCurrentInputMethodSet = false; saveSettingsLocked(userId); final DevicePolicyData systemPolicyData = getUserData(UserHandle.USER_SYSTEM); systemPolicyData.mLastSecurityLogRetrievalTime = -1; Loading Loading @@ -6785,7 +6785,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin.defaultEnabledRestrictionsAlreadySet.clear(); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; policyData.mCurrentInputMethodSet = false; policyData.mOwnerInstalledCaCerts.clear(); saveSettingsLocked(userId); clearUserPoliciesLocked(userId); Loading Loading @@ -7231,9 +7231,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { enforceManageUsers(); } private void enforceProfileOwnerOrSystemUser(ComponentName admin) { private void enforceProfileOwnerOrSystemUser() { synchronized (this) { if (getActiveAdminWithPolicyForUidLocked(admin, if (getActiveAdminWithPolicyForUidLocked(null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid()) != null) { return; Loading Loading @@ -8887,7 +8887,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // to trigger. This is a corner case that will have no impact in practice. mSetupContentObserver.addPendingChangeByOwnerLocked(callingUserId); } getUserData(callingUserId).mDefaultInputMethodSet = true; getUserData(callingUserId).mCurrentInputMethodSet = true; saveSettingsLocked(callingUserId); } mInjector.settingsSecurePutStringForUser(setting, value, callingUserId); Loading Loading @@ -9071,13 +9071,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else if (mDefaultImeChanged.equals(uri)) { synchronized (DevicePolicyManagerService.this) { if (mUserIdsWithPendingChangesByOwner.contains(userId)) { // This change notification was triggered by the owner changing the default // This change notification was triggered by the owner changing the current // IME. Ignore it. mUserIdsWithPendingChangesByOwner.remove(userId); } else { // This change notification was triggered by the user manually changing the // default IME. getUserData(userId).mDefaultInputMethodSet = false; // current IME. getUserData(userId).mCurrentInputMethodSet = false; saveSettingsLocked(userId); } } Loading Loading @@ -10962,14 +10962,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override public boolean isDefaultInputMethodSetByOwner(@NonNull UserHandle user) { final int userId = user.getIdentifier(); enforceProfileOwnerOrSystemUser(null); if (!isCallerWithSystemUid() && mInjector.userHandleGetCallingUserId() != userId) { throw new SecurityException( "Only the system can use this method to query information about another user"); } return getUserData(userId).mDefaultInputMethodSet; public boolean isCurrentInputMethodSetByOwner() { enforceProfileOwnerOrSystemUser(); return getUserData(mInjector.userHandleGetCallingUserId()).mCurrentInputMethodSet; } @Override Loading
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +125 −106 Original line number Diff line number Diff line Loading @@ -3807,143 +3807,162 @@ public class DevicePolicyManagerTest extends DpmTestBase { assertTrue(dpm.clearResetPasswordToken(admin1)); } public void testIsDefaultInputMethodSetByOwnerForDeviceOwner() throws Exception { final String defaultIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri defaultImeUri = Settings.Secure.getUriFor(defaultIme); final UserHandle firstUser = UserHandle.SYSTEM; final UserHandle secondUser = UserHandle.of(DpmMockContext.CALLER_USER_HANDLE); public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception { final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); final int deviceOwnerUid = DpmMockContext.CALLER_SYSTEM_USER_UID; final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, DpmMockContext.SYSTEM_UID); final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); // Set up a Device Owner. mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; // Set up a device owner. mContext.binder.callingUid = deviceOwnerUid; setupDeviceOwner(); // First and second user set default IMEs manually. final long ident = mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First and second user set IMEs manually. mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Device Owner changes default IME for first user. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, UserHandle.USER_SYSTEM)) // Device owner changes IME for first user. mContext.binder.callingUid = deviceOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM)) .thenReturn("ime1"); dpm.setSecureSetting(admin1, defaultIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime2", dpm.setSecureSetting(admin1, currentIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2", UserHandle.USER_SYSTEM); reset(mContext.settings); dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Second user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Device Owner changes default IME for first user again. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, UserHandle.USER_SYSTEM)) dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Second user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // First user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Device owner changes IME for first user again. mContext.binder.callingUid = deviceOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM)) .thenReturn("ime2"); dpm.setSecureSetting(admin1, defaultIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime3", dpm.setSecureSetting(admin1, currentIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3", UserHandle.USER_SYSTEM); dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Restarting the DPMS should not lose information. initializeDpms(); assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); mContext.binder.callingUid = firstUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Device Owner can find out whether it set the default IME itself. assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser)); // Device owner can find out whether it set the current IME itself. mContext.binder.callingUid = deviceOwnerUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Removing the Device Owner should clear the information that it set the default IME. // Removing the device owner should clear the information that it set the current IME. clearDeviceOwner(); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); } public void testIsDefaultInputMethodSetByOwnerForProfileOwner() throws Exception { final String defaultIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri defaultImeUri = Settings.Secure.getUriFor(defaultIme); final UserHandle firstUser = UserHandle.SYSTEM; final UserHandle secondUser = UserHandle.of(DpmMockContext.CALLER_USER_HANDLE); public void testIsCurrentInputMethodSetByOwnerForProfileOwner() throws Exception { final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); final int profileOwnerUid = DpmMockContext.CALLER_UID; final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, DpmMockContext.SYSTEM_UID); final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); // Set up a profile owner. mContext.binder.callingUid = profileOwnerUid; setupProfileOwner(); // First and second user set default IMEs manually. final long ident = mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First and second user set IMEs manually. mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Profile Owner changes default IME for second user. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, // Profile owner changes IME for second user. mContext.binder.callingUid = profileOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1"); dpm.setSecureSetting(admin1, defaultIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime2", dpm.setSecureSetting(admin1, currentIme, "ime2"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2", DpmMockContext.CALLER_USER_HANDLE); reset(mContext.settings); dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // First user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Second user changes default IME manually. dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); // Profile Owner changes default IME for second user again. when(mContext.settings.settingsSecureGetStringForUser(defaultIme, dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // First user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Second user changes IME manually. dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); // Profile owner changes IME for second user again. mContext.binder.callingUid = profileOwnerUid; when(mContext.settings.settingsSecureGetStringForUser(currentIme, DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2"); dpm.setSecureSetting(admin1, defaultIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime3", dpm.setSecureSetting(admin1, currentIme, "ime3"); verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3", DpmMockContext.CALLER_USER_HANDLE); dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Restarting the DPMS should not lose information. initializeDpms(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.restoreCallingIdentity(ident); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Profile Owner can find out whether it set the default IME itself. assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser)); // Profile owner can find out whether it set the current IME itself. mContext.binder.callingUid = profileOwnerUid; assertTrue(dpm.isCurrentInputMethodSetByOwner()); // Removing the Profile Owner should clear the information that it set the default IME. // Removing the profile owner should clear the information that it set the current IME. dpm.clearProfileOwner(admin1); mContext.binder.clearCallingIdentity(); assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser)); assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser)); mContext.binder.callingUid = firstUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); mContext.binder.callingUid = secondUserSystemUid; assertFalse(dpm.isCurrentInputMethodSetByOwner()); } public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception { Loading