From 8beafe3ab0771cc6de2c4258da5a6f837097e0c4 Mon Sep 17 00:00:00 2001 From: Yasin Kilicdere Date: Fri, 25 Nov 2022 18:55:44 +0000 Subject: [PATCH] Fixes collection modified while iterating by cloning the collection. During a user switch, in MediaRouterService, a collection of users was modified while iterating, which ends up skipping some elements of the collection unintentionally. This CL creates a clone of the collection before the for loop to prevent the issue. Bug: 260410380 Test: n/a Change-Id: Iec4d460ba0a0ca1325506e729f58715bb2d68898 --- .../com/android/server/media/MediaRouter2ServiceImpl.java | 8 +++++--- .../java/com/android/server/media/MediaRouterService.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index f5ec880ed2356..ca63b1e7da250 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -645,9 +645,11 @@ class MediaRouter2ServiceImpl { "userId: %d", newActiveUserId)); mCurrentActiveUserId = newActiveUserId; - for (int i = 0; i < mUserRecords.size(); i++) { - int userId = mUserRecords.keyAt(i); - UserRecord userRecord = mUserRecords.valueAt(i); + // disposeUserIfNeededLocked might modify the collection, hence clone + final var userRecords = mUserRecords.clone(); + for (int i = 0; i < userRecords.size(); i++) { + int userId = userRecords.keyAt(i); + UserRecord userRecord = userRecords.valueAt(i); if (isUserActiveLocked(userId)) { // userId corresponds to the active user, or one of its profiles. We // ensure the associated structures are initialized. diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java index 0f6192aa10208..bc0a2a423c3de 100644 --- a/services/core/java/com/android/server/media/MediaRouterService.java +++ b/services/core/java/com/android/server/media/MediaRouterService.java @@ -665,9 +665,11 @@ public final class MediaRouterService extends IMediaRouterService.Stub synchronized (mLock) { if (mCurrentActiveUserId != newActiveUserId) { mCurrentActiveUserId = newActiveUserId; - for (int i = 0; i < mUserRecords.size(); i++) { - int userId = mUserRecords.keyAt(i); - UserRecord userRecord = mUserRecords.valueAt(i); + // disposeUserIfNeededLocked might modify the collection, hence clone + final var userRecords = mUserRecords.clone(); + for (int i = 0; i < userRecords.size(); i++) { + int userId = userRecords.keyAt(i); + UserRecord userRecord = userRecords.valueAt(i); if (isUserActiveLocked(userId)) { // userId corresponds to the active user, or one of its profiles. We // ensure the associated structures are initialized.