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

Commit 10bd8988 authored by Alex Johnston's avatar Alex Johnston
Browse files

refactor reportPasswordChanged

* Refactor method to call saveSettingsLocked
  once for each userId

Manual testing steps
* Set up device with an admin eg. Device Owner
* Add PIN
* Change PIN

Bug: 71536124
Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest
      Manual Testing
Change-Id: Idf9b30498117db649a7326653e48e38c55cc3b70
parent 1b6a8f87
Loading
Loading
Loading
Loading
+40 −21
Original line number Diff line number Diff line
@@ -3570,6 +3570,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        return new JournaledFile(new File(base), new File(base + ".tmp"));
    }
    /**
     * Persist modified values to disk by calling {@link #saveSettingsLocked} for each
     * affected user ID.
     */
    @GuardedBy("getLockObject()")
    private void saveSettingsForUsersLocked(Set<Integer> affectedUserIds) {
        for (int userId : affectedUserIds) {
            saveSettingsLocked(userId);
        }
    }
    private void saveSettingsLocked(int userHandle) {
        DevicePolicyData policy = getUserData(userHandle);
        JournaledFile journal = makeJournaledFile(userHandle);
@@ -4785,13 +4796,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
    /**
     * Updates a flag that tells us whether the user's password currently satisfies the
     * requirements set by all of the user's active admins. The flag is updated both in memory
     * and persisted to disk by calling {@link #saveSettingsLocked}, for the value of the flag
     * be the correct one upon boot.
     * This should be called whenever the password or the admin policies have changed.
     * requirements set by all of the user's active admins.
     * This should be called whenever the password or the admin policies have changed. The caller
     * is responsible for calling {@link #saveSettingsLocked} to persist the change.
     *
     * @return the set of user IDs that have been affected
     */
    @GuardedBy("getLockObject()")
    private void updatePasswordValidityCheckpointLocked(int userHandle, boolean parent) {
    private Set<Integer> updatePasswordValidityCheckpointLocked(int userHandle, boolean parent) {
        final ArraySet<Integer> affectedUserIds = new ArraySet<>();
        final int credentialOwner = getCredentialOwner(userHandle, parent);
        DevicePolicyData policy = getUserData(credentialOwner);
        PasswordMetrics metrics = mLockSettingsInternal.getUserPasswordMetrics(credentialOwner);
@@ -4801,9 +4814,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                    metrics, userHandle, parent);
            if (newCheckpoint != policy.mPasswordValidAtLastCheckpoint) {
                policy.mPasswordValidAtLastCheckpoint = newCheckpoint;
                saveSettingsLocked(credentialOwner);
                affectedUserIds.add(credentialOwner);
            }
        }
        return affectedUserIds;
    }
    /**
@@ -6175,7 +6189,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
    }
    private void removeCaApprovalsIfNeeded(int userId) {
    private Set<Integer> removeCaApprovalsIfNeeded(int userId) {
        final ArraySet<Integer> affectedUserIds = new ArraySet<>();
        for (UserInfo userInfo : mUserManager.getProfiles(userId)) {
            boolean isSecure = mLockPatternUtils.isSecure(userInfo.id);
            if (userInfo.isManagedProfile()){
@@ -6184,11 +6199,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            if (!isSecure) {
                synchronized (getLockObject()) {
                    getUserData(userInfo.id).mAcceptedCaCertificates.clear();
                    saveSettingsLocked(userInfo.id);
                    affectedUserIds.add(userInfo.id);
                }
                mCertificateMonitor.onCertificateApprovalsChanged(userId);
            }
        }
        return affectedUserIds;
    }
    @Override
@@ -7458,42 +7474,45 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        DevicePolicyData policy = getUserData(userId);
        final ArraySet<Integer> affectedUserIds = new ArraySet<>();
        synchronized (getLockObject()) {
            policy.mFailedPasswordAttempts = 0;
            updatePasswordValidityCheckpointLocked(userId, /* parent */ false);
            saveSettingsLocked(userId);
            updatePasswordExpirationsLocked(userId);
            affectedUserIds.add(userId);
            affectedUserIds.addAll(updatePasswordValidityCheckpointLocked(
                    userId, /* parent */ false));
            affectedUserIds.addAll(updatePasswordExpirationsLocked(userId));
            setExpirationAlarmCheckLocked(mContext, userId, /* parent */ false);
            // Send a broadcast to each profile using this password as its primary unlock.
            sendAdminCommandForLockscreenPoliciesLocked(
                    DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userId);
            affectedUserIds.addAll(removeCaApprovalsIfNeeded(userId));
            saveSettingsForUsersLocked(affectedUserIds);
        }
        removeCaApprovalsIfNeeded(userId);
    }
    /**
     * Called any time the device password is updated. Resets all password expiration clocks.
     *
     * @return the set of user IDs that have been affected
     */
    private void updatePasswordExpirationsLocked(int userHandle) {
        ArraySet<Integer> affectedUserIds = new ArraySet<Integer>();
    private Set<Integer> updatePasswordExpirationsLocked(int userHandle) {
        final ArraySet<Integer> affectedUserIds = new ArraySet<>();
        List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(
                userHandle, /* parent */ false);
        final int N = admins.size();
        for (int i = 0; i < N; i++) {
        for (int i = 0; i < admins.size(); i++) {
            ActiveAdmin admin = admins.get(i);
            if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
                affectedUserIds.add(admin.getUserHandle().getIdentifier());
                long timeout = admin.passwordExpirationTimeout;
                long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
                admin.passwordExpirationDate = expiration;
            }
                admin.passwordExpirationDate =
                        timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
            }
        for (int affectedUserId : affectedUserIds) {
            saveSettingsLocked(affectedUserId);
        }
        return affectedUserIds;
    }
    @Override
+1 −16
Original line number Diff line number Diff line
@@ -48,8 +48,6 @@ import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
@@ -4931,20 +4929,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
                .thenReturn(passwordMetrics);
        dpm.reportPasswordChanged(userHandle);

        // Drain ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED broadcasts as part of
        // reportPasswordChanged()
        // This broadcast should be sent 2-4 times:
        // * Twice from calls to DevicePolicyManagerService.updatePasswordExpirationsLocked,
        //   once for each affected user, in DevicePolicyManagerService.reportPasswordChanged.
        // * Optionally, at most twice from calls to DevicePolicyManagerService.saveSettingsLocked
        //   in DevicePolicyManagerService.reportPasswordChanged, once with the userId
        //   the password change is relevant to and another with the credential owner of said
        //   userId, if the password checkpoint value changes.
        verify(mContext.spiedContext, atMost(4)).sendBroadcastAsUser(
                MockUtils.checkIntentAction(
                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
                MockUtils.checkUserHandle(userHandle));
        verify(mContext.spiedContext, atLeast(2)).sendBroadcastAsUser(
        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
                MockUtils.checkIntentAction(
                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
                MockUtils.checkUserHandle(userHandle));