Fix purge bug for program list update

Fix the bug that using keySet and removing items of mPrograms at
the same time during program list update

Bug: 238199883
Test: atest android.hardware.radio.tests.functional
Test: atest com.android.server.broadcastradio.hal2
Change-Id: Ie958b3686780de8c6f3b9912c71dcfe7c07befd0
Merged-In: Ie958b3686780de8c6f3b9912c71dcfe7c07befd0
(cherry picked from commit 92a2339b7b5b04f283fee11b96c61aadb50862fe)
diff --git a/core/java/android/hardware/radio/ProgramList.java b/core/java/android/hardware/radio/ProgramList.java
index e8e4fc9..f2525d1 100644
--- a/core/java/android/hardware/radio/ProgramList.java
+++ b/core/java/android/hardware/radio/ProgramList.java
@@ -22,10 +22,11 @@
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.ArrayMap;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -41,7 +42,7 @@
 
     private final Object mLock = new Object();
     private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mPrograms =
-            new HashMap<>();
+            new ArrayMap<>();
 
     private final List<ListCallback> mListCallbacks = new ArrayList<>();
     private final List<OnCompleteListener> mOnCompleteListeners = new ArrayList<>();
@@ -184,8 +185,14 @@
             listCallbacksCopied = new ArrayList<>(mListCallbacks);
 
             if (chunk.isPurge()) {
-                for (ProgramSelector.Identifier id : mPrograms.keySet()) {
-                    removeLocked(id, removedList);
+                Iterator<Map.Entry<ProgramSelector.Identifier, RadioManager.ProgramInfo>>
+                        programsIterator = mPrograms.entrySet().iterator();
+                while (programsIterator.hasNext()) {
+                    RadioManager.ProgramInfo removed = programsIterator.next().getValue();
+                    if (removed != null) {
+                        removedList.add(removed.getSelector().getPrimaryId());
+                    }
+                    programsIterator.remove();
                 }
             }