diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java index 00abb37855f7b..f0bcb815ebe21 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java @@ -317,14 +317,35 @@ public class RecoverableKeyStoreManager { mListenersStorage.setSnapshotListener(uid, intent); } + /** + * Set the server params for the user's key chain. This is used to uniquely identify a key + * chain. Along with the counter ID, it is used to uniquely identify an instance of a vault. + */ public void setServerParams(@NonNull byte[] serverParams) throws RemoteException { checkRecoverKeyStorePermission(); int userId = UserHandle.getCallingUserId(); int uid = Binder.getCallingUid(); - long updatedRows = mDatabase.setServerParams(userId, uid, serverParams); - if (updatedRows > 0) { - mDatabase.setShouldCreateSnapshot(userId, uid, true); + + byte[] currentServerParams = mDatabase.getServerParams(userId, uid); + + if (Arrays.equals(serverParams, currentServerParams)) { + Log.v(TAG, "Not updating server params - same as old value."); + return; } + + long updatedRows = mDatabase.setServerParams(userId, uid, serverParams); + if (updatedRows < 1) { + throw new ServiceSpecificException( + ERROR_SERVICE_INTERNAL_ERROR, "Database failure trying to set server params."); + } + + if (currentServerParams == null) { + Log.i(TAG, "Initialized server params."); + return; + } + + Log.i(TAG, "Updated server params. Snapshot pending."); + mDatabase.setShouldCreateSnapshot(userId, uid, true); } /** diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java index fc2da39da7eb2..445e50a4f8198 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java @@ -895,6 +895,51 @@ public class RecoverableKeyStoreManagerTest { verify(mMockListenersStorage).setSnapshotListener(eq(uid), any(PendingIntent.class)); } + @Test + public void setServerParams_updatesServerParams() throws Exception { + int uid = Binder.getCallingUid(); + int userId = UserHandle.getCallingUserId(); + byte[] serverParams = new byte[] { 1 }; + + mRecoverableKeyStoreManager.setServerParams(serverParams); + + assertThat(mRecoverableKeyStoreDb.getServerParams(userId, uid)).isEqualTo(serverParams); + } + + @Test + public void setServerParams_doesNotSetSnapshotPendingIfInitializing() throws Exception { + int uid = Binder.getCallingUid(); + int userId = UserHandle.getCallingUserId(); + byte[] serverParams = new byte[] { 1 }; + + mRecoverableKeyStoreManager.setServerParams(serverParams); + + assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse(); + } + + @Test + public void setServerParams_doesNotSetSnapshotPendingIfSettingSameValue() throws Exception { + int uid = Binder.getCallingUid(); + int userId = UserHandle.getCallingUserId(); + byte[] serverParams = new byte[] { 1 }; + + mRecoverableKeyStoreManager.setServerParams(serverParams); + mRecoverableKeyStoreManager.setServerParams(serverParams); + + assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse(); + } + + @Test + public void setServerParams_setsSnapshotPendingIfUpdatingValue() throws Exception { + int uid = Binder.getCallingUid(); + int userId = UserHandle.getCallingUserId(); + + mRecoverableKeyStoreManager.setServerParams(new byte[] { 1 }); + mRecoverableKeyStoreManager.setServerParams(new byte[] { 2 }); + + assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue(); + } + @Test public void setRecoverySecretTypes() throws Exception { int[] types1 = new int[]{11, 2000};