Loading api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6292,6 +6292,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 isDeviceManaged(); method public boolean isDeviceOwnerApp(java.lang.String); method public boolean isLockTaskPermitted(java.lang.String); core/java/android/app/admin/DevicePolicyManager.java +23 −0 Original line number Diff line number Diff line Loading @@ -7871,4 +7871,27 @@ public class DevicePolicyManager { throw re.rethrowFromSystemServer(); } } /** * Called by the system to find out whether the 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. * * @hide */ @TestApi public boolean isDefaultInputMethodSetByOwner(@NonNull UserHandle user) { try { return mService.isDefaultInputMethodSetByOwner(user); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } } core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -347,4 +347,6 @@ interface IDevicePolicyManager { boolean clearResetPasswordToken(in ComponentName admin); boolean isResetPasswordTokenActive(in ComponentName admin); boolean resetPasswordWithToken(in ComponentName admin, String password, in byte[] token, int flags); boolean isDefaultInputMethodSetByOwner(in UserHandle user); } services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +83 −9 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.statusbar.IStatusBarService; Loading Loading @@ -238,6 +239,8 @@ 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 ATTR_ID = "id"; private static final String ATTR_VALUE = "value"; Loading Loading @@ -402,6 +405,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean(); private final AtomicBoolean mRemoteBugreportSharingAccepted = new AtomicBoolean(); private SetupContentObserver mSetupContentObserver; private final Runnable mRemoteBugreportTimeoutRunnable = new Runnable() { @Override public void run() { Loading Loading @@ -504,6 +509,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long mLastNetworkLogsRetrievalTime = -1; boolean mDefaultInputMethodSet = false; // Used for initialization of users created by createAndManageUsers. boolean mAdminBroadcastPending = false; PersistableBundle mInitBundle = null; Loading Loading @@ -1701,6 +1708,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { name, def, userHandle); } String settingsSecureGetStringForUser(String name, int userHandle) { return Settings.Secure.getStringForUser(mContext.getContentResolver(), name, userHandle); } void settingsSecurePutIntForUser(String name, int value, int userHandle) { Settings.Secure.putIntForUser(mContext.getContentResolver(), name, value, userHandle); Loading Loading @@ -1816,6 +1828,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); LocalServices.addService(DevicePolicyManagerInternal.class, mLocalService); mSetupContentObserver = new SetupContentObserver(mHandler); } /** Loading Loading @@ -2568,6 +2582,11 @@ 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); } out.endTag(null, "policies"); out.endDocument(); Loading Loading @@ -2777,6 +2796,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 { Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); Loading Loading @@ -2897,8 +2918,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { onStartUser(UserHandle.USER_SYSTEM); // Register an observer for watching for user setup complete. new SetupContentObserver(mHandler).register(); // Register an observer for watching for user setup complete and settings changes. mSetupContentObserver.register(); // Initialize the user setup state, to handle the upgrade case. updateUserSetupCompleteAndPaired(); Loading Loading @@ -6558,12 +6579,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin.forceEphemeralUsers = false; admin.isNetworkLoggingEnabled = false; mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers); final DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM); policyData.mLastSecurityLogRetrievalTime = -1; policyData.mLastBugReportRequestTime = -1; policyData.mLastNetworkLogsRetrievalTime = -1; saveSettingsLocked(UserHandle.USER_SYSTEM); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; saveSettingsLocked(userId); final DevicePolicyData systemPolicyData = getUserData(UserHandle.USER_SYSTEM); systemPolicyData.mLastSecurityLogRetrievalTime = -1; systemPolicyData.mLastBugReportRequestTime = -1; systemPolicyData.mLastNetworkLogsRetrievalTime = -1; saveSettingsLocked(UserHandle.USER_SYSTEM); clearUserPoliciesLocked(userId); mOwners.clearDeviceOwner(); Loading Loading @@ -6648,6 +6672,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin.userRestrictions = null; admin.defaultEnabledRestrictionsAlreadySet.clear(); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; saveSettingsLocked(userId); clearUserPoliciesLocked(userId); mOwners.removeProfileOwner(userId); mOwners.writeProfileOwner(userId); Loading Loading @@ -8698,6 +8725,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long id = mInjector.binderClearCallingIdentity(); try { if (Settings.Secure.DEFAULT_INPUT_METHOD.equals(setting)) { final String currentValue = mInjector.settingsSecureGetStringForUser( Settings.Secure.DEFAULT_INPUT_METHOD, callingUserId); if (!TextUtils.equals(currentValue, value)) { // Tell the content observer that the next change will be due to the owner // changing the value. There is a small race condition here that we cannot // avoid: Change notifications are sent asynchronously, so it is possible // that there are prior notifications queued up before the one we are about // to trigger. This is a corner case that will have no impact in practice. mSetupContentObserver.addPendingChangeByOwnerLocked(callingUserId); } getUserData(callingUserId).mDefaultInputMethodSet = true; saveSettingsLocked(callingUserId); } mInjector.settingsSecurePutStringForUser(setting, value, callingUserId); } finally { mInjector.binderRestoreCallingIdentity(id); Loading Loading @@ -8838,12 +8879,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private class SetupContentObserver extends ContentObserver { private final Uri mUserSetupComplete = Settings.Secure.getUriFor( Settings.Secure.USER_SETUP_COMPLETE); private final Uri mDeviceProvisioned = Settings.Global.getUriFor( Settings.Global.DEVICE_PROVISIONED); private final Uri mPaired = Settings.Secure.getUriFor(Settings.Secure.DEVICE_PAIRED); private final Uri mDefaultImeChanged = Settings.Secure.getUriFor( Settings.Secure.DEFAULT_INPUT_METHOD); @GuardedBy("DevicePolicyManagerService.this") private Set<Integer> mUserIdsWithPendingChangesByOwner = new ArraySet<>(); public SetupContentObserver(Handler handler) { super(handler); Loading @@ -8855,10 +8900,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (mIsWatch) { mInjector.registerContentObserver(mPaired, false, this, UserHandle.USER_ALL); } mInjector.registerContentObserver(mDefaultImeChanged, false, this, UserHandle.USER_ALL); } private void addPendingChangeByOwnerLocked(int userId) { mUserIdsWithPendingChangesByOwner.add(userId); } @Override public void onChange(boolean selfChange, Uri uri) { public void onChange(boolean selfChange, Uri uri, int userId) { if (mUserSetupComplete.equals(uri) || (mIsWatch && mPaired.equals(uri))) { updateUserSetupCompleteAndPaired(); } else if (mDeviceProvisioned.equals(uri)) { Loading @@ -8867,6 +8917,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // is delayed until device is marked as provisioned. setDeviceOwnerSystemPropertyLocked(); } } else if (mDefaultImeChanged.equals(uri)) { synchronized (DevicePolicyManagerService.this) { if (mUserIdsWithPendingChangesByOwner.contains(userId)) { // This change notification was triggered by the owner changing the default // IME. Ignore it. mUserIdsWithPendingChangesByOwner.remove(userId); } else { // This change notification was triggered by the user manually changing the // default IME. getUserData(userId).mDefaultInputMethodSet = false; saveSettingsLocked(userId); } } } } } Loading Loading @@ -10745,4 +10808,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } return false; } @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; } } services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +5 −0 Original line number Diff line number Diff line Loading @@ -312,6 +312,11 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi return context.settings.settingsSecureGetIntForUser(name, def, userHandle); } @Override String settingsSecureGetStringForUser(String name, int userHandle) { return context.settings.settingsSecureGetStringForUser(name, userHandle); } @Override void settingsSecurePutIntForUser(String name, int value, int userHandle) { context.settings.settingsSecurePutIntForUser(name, value, userHandle); Loading Loading
api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -6292,6 +6292,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 isDeviceManaged(); method public boolean isDeviceOwnerApp(java.lang.String); method public boolean isLockTaskPermitted(java.lang.String);
core/java/android/app/admin/DevicePolicyManager.java +23 −0 Original line number Diff line number Diff line Loading @@ -7871,4 +7871,27 @@ public class DevicePolicyManager { throw re.rethrowFromSystemServer(); } } /** * Called by the system to find out whether the 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. * * @hide */ @TestApi public boolean isDefaultInputMethodSetByOwner(@NonNull UserHandle user) { try { return mService.isDefaultInputMethodSetByOwner(user); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); } } }
core/java/android/app/admin/IDevicePolicyManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -347,4 +347,6 @@ interface IDevicePolicyManager { boolean clearResetPasswordToken(in ComponentName admin); boolean isResetPasswordTokenActive(in ComponentName admin); boolean resetPasswordWithToken(in ComponentName admin, String password, in byte[] token, int flags); boolean isDefaultInputMethodSetByOwner(in UserHandle user); }
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +83 −9 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodManager; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.statusbar.IStatusBarService; Loading Loading @@ -238,6 +239,8 @@ 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 ATTR_ID = "id"; private static final String ATTR_VALUE = "value"; Loading Loading @@ -402,6 +405,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private final AtomicBoolean mRemoteBugreportServiceIsActive = new AtomicBoolean(); private final AtomicBoolean mRemoteBugreportSharingAccepted = new AtomicBoolean(); private SetupContentObserver mSetupContentObserver; private final Runnable mRemoteBugreportTimeoutRunnable = new Runnable() { @Override public void run() { Loading Loading @@ -504,6 +509,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long mLastNetworkLogsRetrievalTime = -1; boolean mDefaultInputMethodSet = false; // Used for initialization of users created by createAndManageUsers. boolean mAdminBroadcastPending = false; PersistableBundle mInitBundle = null; Loading Loading @@ -1701,6 +1708,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { name, def, userHandle); } String settingsSecureGetStringForUser(String name, int userHandle) { return Settings.Secure.getStringForUser(mContext.getContentResolver(), name, userHandle); } void settingsSecurePutIntForUser(String name, int value, int userHandle) { Settings.Secure.putIntForUser(mContext.getContentResolver(), name, value, userHandle); Loading Loading @@ -1816,6 +1828,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler); LocalServices.addService(DevicePolicyManagerInternal.class, mLocalService); mSetupContentObserver = new SetupContentObserver(mHandler); } /** Loading Loading @@ -2568,6 +2582,11 @@ 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); } out.endTag(null, "policies"); out.endDocument(); Loading Loading @@ -2777,6 +2796,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 { Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); Loading Loading @@ -2897,8 +2918,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { onStartUser(UserHandle.USER_SYSTEM); // Register an observer for watching for user setup complete. new SetupContentObserver(mHandler).register(); // Register an observer for watching for user setup complete and settings changes. mSetupContentObserver.register(); // Initialize the user setup state, to handle the upgrade case. updateUserSetupCompleteAndPaired(); Loading Loading @@ -6558,12 +6579,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin.forceEphemeralUsers = false; admin.isNetworkLoggingEnabled = false; mUserManagerInternal.setForceEphemeralUsers(admin.forceEphemeralUsers); final DevicePolicyData policyData = getUserData(UserHandle.USER_SYSTEM); policyData.mLastSecurityLogRetrievalTime = -1; policyData.mLastBugReportRequestTime = -1; policyData.mLastNetworkLogsRetrievalTime = -1; saveSettingsLocked(UserHandle.USER_SYSTEM); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; saveSettingsLocked(userId); final DevicePolicyData systemPolicyData = getUserData(UserHandle.USER_SYSTEM); systemPolicyData.mLastSecurityLogRetrievalTime = -1; systemPolicyData.mLastBugReportRequestTime = -1; systemPolicyData.mLastNetworkLogsRetrievalTime = -1; saveSettingsLocked(UserHandle.USER_SYSTEM); clearUserPoliciesLocked(userId); mOwners.clearDeviceOwner(); Loading Loading @@ -6648,6 +6672,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin.userRestrictions = null; admin.defaultEnabledRestrictionsAlreadySet.clear(); } final DevicePolicyData policyData = getUserData(userId); policyData.mDefaultInputMethodSet = false; saveSettingsLocked(userId); clearUserPoliciesLocked(userId); mOwners.removeProfileOwner(userId); mOwners.writeProfileOwner(userId); Loading Loading @@ -8698,6 +8725,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long id = mInjector.binderClearCallingIdentity(); try { if (Settings.Secure.DEFAULT_INPUT_METHOD.equals(setting)) { final String currentValue = mInjector.settingsSecureGetStringForUser( Settings.Secure.DEFAULT_INPUT_METHOD, callingUserId); if (!TextUtils.equals(currentValue, value)) { // Tell the content observer that the next change will be due to the owner // changing the value. There is a small race condition here that we cannot // avoid: Change notifications are sent asynchronously, so it is possible // that there are prior notifications queued up before the one we are about // to trigger. This is a corner case that will have no impact in practice. mSetupContentObserver.addPendingChangeByOwnerLocked(callingUserId); } getUserData(callingUserId).mDefaultInputMethodSet = true; saveSettingsLocked(callingUserId); } mInjector.settingsSecurePutStringForUser(setting, value, callingUserId); } finally { mInjector.binderRestoreCallingIdentity(id); Loading Loading @@ -8838,12 +8879,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } private class SetupContentObserver extends ContentObserver { private final Uri mUserSetupComplete = Settings.Secure.getUriFor( Settings.Secure.USER_SETUP_COMPLETE); private final Uri mDeviceProvisioned = Settings.Global.getUriFor( Settings.Global.DEVICE_PROVISIONED); private final Uri mPaired = Settings.Secure.getUriFor(Settings.Secure.DEVICE_PAIRED); private final Uri mDefaultImeChanged = Settings.Secure.getUriFor( Settings.Secure.DEFAULT_INPUT_METHOD); @GuardedBy("DevicePolicyManagerService.this") private Set<Integer> mUserIdsWithPendingChangesByOwner = new ArraySet<>(); public SetupContentObserver(Handler handler) { super(handler); Loading @@ -8855,10 +8900,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (mIsWatch) { mInjector.registerContentObserver(mPaired, false, this, UserHandle.USER_ALL); } mInjector.registerContentObserver(mDefaultImeChanged, false, this, UserHandle.USER_ALL); } private void addPendingChangeByOwnerLocked(int userId) { mUserIdsWithPendingChangesByOwner.add(userId); } @Override public void onChange(boolean selfChange, Uri uri) { public void onChange(boolean selfChange, Uri uri, int userId) { if (mUserSetupComplete.equals(uri) || (mIsWatch && mPaired.equals(uri))) { updateUserSetupCompleteAndPaired(); } else if (mDeviceProvisioned.equals(uri)) { Loading @@ -8867,6 +8917,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // is delayed until device is marked as provisioned. setDeviceOwnerSystemPropertyLocked(); } } else if (mDefaultImeChanged.equals(uri)) { synchronized (DevicePolicyManagerService.this) { if (mUserIdsWithPendingChangesByOwner.contains(userId)) { // This change notification was triggered by the owner changing the default // IME. Ignore it. mUserIdsWithPendingChangesByOwner.remove(userId); } else { // This change notification was triggered by the user manually changing the // default IME. getUserData(userId).mDefaultInputMethodSet = false; saveSettingsLocked(userId); } } } } } Loading Loading @@ -10745,4 +10808,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } return false; } @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; } }
services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +5 −0 Original line number Diff line number Diff line Loading @@ -312,6 +312,11 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi return context.settings.settingsSecureGetIntForUser(name, def, userHandle); } @Override String settingsSecureGetStringForUser(String name, int userHandle) { return context.settings.settingsSecureGetStringForUser(name, userHandle); } @Override void settingsSecurePutIntForUser(String name, int value, int userHandle) { context.settings.settingsSecurePutIntForUser(name, value, userHandle); Loading