Add support for updating apns when only resource changed

Apn added in RRO is not added when rebooting after firmware upgrade.

On initial boot the apn database will consist of a merge between:
com.android.internal.R.xml.apns and one of the files below;
- /system/etc/apns-conf.xml
- /oem/telephony/apns-conf.xml
- /data/misc/apns-conf.xml

For the database to be upgraded after a firmware upgrade, one of the three
apns-conf files above need to be changed, no consideration is given
that the RRO might have been updated.

This commit adds the checksum for resources to the selected file for
a total checksum that is then compared to persisted value.

Bug: 79876418

Test: Start device and check the apns in settings
Add an RRO that contains another set of apns
Remove /data/user_de/0/com.android.providers.telephony/shared_prefs/build-id.xml
to simulate that the fingerprint is updated
Restart the device and the new matching apns exists in settings

Change-Id: I41852ebb22c341c17fafba7e337a2af56f018dc1
diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 48fcbfd..f809380 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -116,15 +116,18 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.zip.CRC32;
 
 public class TelephonyProvider extends ContentProvider
 {
@@ -518,9 +521,32 @@
             } catch (IOException e) {
                 loge("IOException for " + file.getAbsolutePath() + ":" + e);
             }
+
+            // The RRO may have been updated in a firmware upgrade. Add checksum for the
+            // resources to the total checksum so that apns in an RRO update is not missed.
+            try (InputStream inputStream = mContext.getResources().
+                        openRawResource(com.android.internal.R.xml.apns)) {
+                byte[] array = toByteArray(inputStream);
+                CRC32 c = new CRC32();
+                c.update(array);
+                checksum += c.getValue();
+                if (DBG) log("Checksum after adding resource is " + checksum);
+            } catch (IOException | Resources.NotFoundException e) {
+                loge("Exception when calculating checksum for internal apn resources: " + e);
+            }
             return checksum;
         }
 
+        private static byte[] toByteArray(InputStream input) throws IOException {
+            byte[] buffer = new byte[128];
+            int bytesRead;
+            ByteArrayOutputStream output = new ByteArrayOutputStream();
+            while ((bytesRead = input.read(buffer)) != -1) {
+                output.write(buffer, 0, bytesRead);
+            }
+            return output.toByteArray();
+        }
+
         private long getApnConfChecksum() {
             SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
             return sp.getLong(APN_CONF_CHECKSUM, -1);