Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f7e1fc9 authored by Bartosz Fabianowski's avatar Bartosz Fabianowski Committed by Android (Google) Code Review
Browse files

Merge "Add API for checking whether the default IME was set by the DO/PO"

parents a63a9d4c aff5e9c2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+23 −0
Original line number Diff line number Diff line
@@ -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();
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -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);
}
+83 −9
Original line number Diff line number Diff line
@@ -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;
@@ -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";
@@ -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() {
@@ -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;
@@ -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);
@@ -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);
    }

    /**
@@ -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();
@@ -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);
@@ -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();

@@ -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();
@@ -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);
@@ -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);
@@ -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);
@@ -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)) {
@@ -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);
                    }
                }
            }
        }
    }
@@ -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;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -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