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

Commit f0f3f910 authored by Shuo Qian's avatar Shuo Qian Committed by sqian
Browse files

Integrate OTA emergency number database with EmergencyNumberTracker

Integrate OTA emergency number database with EmergencyNumberTracker,
 compare the OTA emergency number database and Asset emergency number
database, and pick up the higher-version database as the usage.

Fix a minor comment mistake.

Test: Manually configured a database in the corresponding file partition;
Observed the database is cached: https://paste.googleplex.com/6568325855313920

Bug: 136027884

Change-Id: I916cd7676ecaf0891e4c233fc78b623349135c2e
Merged-In: I916cd7676ecaf0891e4c233fc78b623349135c2e
(cherry picked from commit 6ce2c118)
parent 7bc44233
Loading
Loading
Loading
Loading
+125 −10
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncResult;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
@@ -49,11 +50,11 @@ import com.android.internal.util.IndentingPrintWriter;
import com.android.phone.ecc.nano.ProtobufEccData;
import com.android.phone.ecc.nano.ProtobufEccData.EccInfo;

import libcore.io.IoUtils;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
@@ -70,6 +71,12 @@ import java.util.zip.GZIPInputStream;
public class EmergencyNumberTracker extends Handler {
    private static final String TAG = EmergencyNumberTracker.class.getSimpleName();

    private static final int INVALID_DATABASE_VERSION = -1;
    private static final String EMERGENCY_NUMBER_DB_OTA_FILE_NAME = "emergency_number_db";
    private static final String EMERGENCY_NUMBER_DB_OTA_FILE_PATH =
            "misc/emergencynumberdb/" + EMERGENCY_NUMBER_DB_OTA_FILE_NAME;


    /** @hide */
    public static boolean DBG = false;
    /** @hide */
@@ -82,6 +89,7 @@ public class EmergencyNumberTracker extends Handler {
    private final CommandsInterface mCi;
    private final Phone mPhone;
    private String mCountryIso;
    private int mCurrentDatabaseVersion = INVALID_DATABASE_VERSION;
    /**
     * Indicates if the country iso is set by another subscription.
     * @hide
@@ -114,6 +122,8 @@ public class EmergencyNumberTracker extends Handler {
    private static final int EVENT_UPDATE_EMERGENCY_NUMBER_TEST_MODE = 3;
    /** Event indicating the update for the emergency number prefix from carrier config. */
    private static final int EVENT_UPDATE_EMERGENCY_NUMBER_PREFIX = 4;
    /** Event indicating the update for the OTA emergency number database. */
    private static final int EVENT_UPDATE_OTA_EMERGENCY_NUMBER_DB = 5;

    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
@@ -133,7 +143,7 @@ public class EmergencyNumberTracker extends Handler {
                    // Sometimes the country is updated as an empty string when the network signal
                    // is lost; though we may not call emergency when there is no signal, we want
                    // to keep the old country iso to provide country-related emergency numbers,
                    // because they think they are still in that country. So we do need to update
                    // because they think they are still in that country. We don't need to update
                    // country change in this case.
                    if (TextUtils.isEmpty(countryIso)) {
                        return;
@@ -143,6 +153,11 @@ public class EmergencyNumberTracker extends Handler {
                    updateEmergencyCountryIsoAllPhones(countryIso);
                }
                return;
            } else if (intent.getAction().equals(
                    TelephonyManager.ACTION_OTA_EMERGENCY_NUMBER_DB_INSTALLED)) {
                logd("ACTION_OTA_EMERGENCY_NUMBER_DB_INSTALLED: triggered");
                updateOtaEmergencyNumberDatabase();
                return;
            }
        }
    };
@@ -168,6 +183,8 @@ public class EmergencyNumberTracker extends Handler {
                    CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
            // Receive Telephony Network Country Changes
            filter.addAction(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
            // Receive Emergency Number OTA Update Changes
            filter.addAction(TelephonyManager.ACTION_OTA_EMERGENCY_NUMBER_DB_INSTALLED);

            mPhone.getContext().registerReceiver(mIntentReceiver, filter);
        } else {
@@ -223,7 +240,10 @@ public class EmergencyNumberTracker extends Handler {
                } else {
                    updateEmergencyNumberPrefixAndNotify((String[]) msg.obj);
                }

                break;
            case EVENT_UPDATE_OTA_EMERGENCY_NUMBER_DB:
                updateOtaEmergencyNumberListDatabaseAndNotify();
                break;
        }
    }

@@ -312,6 +332,15 @@ public class EmergencyNumberTracker extends Handler {
        this.obtainMessage(EVENT_UPDATE_DB_COUNTRY_ISO_CHANGED, countryIso).sendToTarget();
    }

    /**
     * Update changed OTA Emergency Number database.
     *
     * @hide
     */
    public void updateOtaEmergencyNumberDatabase() {
        this.obtainMessage(EVENT_UPDATE_OTA_EMERGENCY_NUMBER_DB).sendToTarget();
    }

    private EmergencyNumber convertEmergencyNumberFromEccInfo(EccInfo eccInfo, String countryIso) {
        String phoneNumber = eccInfo.phoneNumber.trim();
        if (phoneNumber.isEmpty()) {
@@ -351,25 +380,29 @@ public class EmergencyNumberTracker extends Handler {
    private void cacheEmergencyDatabaseByCountry(String countryIso) {
        BufferedInputStream inputStream = null;
        ProtobufEccData.AllInfo allEccMessages = null;
        List<EmergencyNumber> updatedEmergencyNumberList = new ArrayList<>();
        int assetsDatabaseVersion = INVALID_DATABASE_VERSION;

        // Read the Asset emergency number database
        List<EmergencyNumber> updatedAssetEmergencyNumberList = new ArrayList<>();
        try {
            inputStream = new BufferedInputStream(
                    mPhone.getContext().getAssets().open(EMERGENCY_NUMBER_DB_ASSETS_FILE));
            allEccMessages = ProtobufEccData.AllInfo.parseFrom(readInputStreamToByteArray(
                    new GZIPInputStream(inputStream)));
            logd(countryIso + " emergency database is loaded. ");
            assetsDatabaseVersion = allEccMessages.revision;
            logd(countryIso + " asset emergency database is loaded. Ver: " + assetsDatabaseVersion
                    + " Phone Id: " + mPhone.getPhoneId());
            for (ProtobufEccData.CountryInfo countryEccInfo : allEccMessages.countries) {
                if (countryEccInfo.isoCode.equals(countryIso.toUpperCase())) {
                    for (ProtobufEccData.EccInfo eccInfo : countryEccInfo.eccs) {
                        updatedEmergencyNumberList.add(convertEmergencyNumberFromEccInfo(
                        updatedAssetEmergencyNumberList.add(convertEmergencyNumberFromEccInfo(
                                eccInfo, countryIso));
                    }
                }
            }
            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(updatedEmergencyNumberList);
            mEmergencyNumberListFromDatabase = updatedEmergencyNumberList;
            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(updatedAssetEmergencyNumberList);
        } catch (IOException ex) {
            loge("Cache emergency database failure: " + ex);
            loge("Cache asset emergency database failure: " + ex);
        } finally {
            // close quietly by catching non-runtime exceptions.
            if (inputStream != null) {
@@ -381,6 +414,69 @@ public class EmergencyNumberTracker extends Handler {
                }
            }
        }

        // Cache OTA emergency number database
        int otaDatabaseVersion = cacheOtaEmergencyNumberDatabase();

        // Use a valid database that has higher version.
        if (otaDatabaseVersion == INVALID_DATABASE_VERSION
                && assetsDatabaseVersion == INVALID_DATABASE_VERSION) {
            loge("No database available. Phone Id: " + mPhone.getPhoneId());
            return;
        } else if (assetsDatabaseVersion > otaDatabaseVersion) {
            logd("Using Asset Emergency database. Version: " + assetsDatabaseVersion);
            mCurrentDatabaseVersion = assetsDatabaseVersion;
            mEmergencyNumberListFromDatabase = updatedAssetEmergencyNumberList;
        } else {
            logd("Using Ota Emergency database. Version: " + otaDatabaseVersion);
        }
    }

    private int cacheOtaEmergencyNumberDatabase() {
        BufferedInputStream inputStream = null;
        ProtobufEccData.AllInfo allEccMessages = null;
        int otaDatabaseVersion = INVALID_DATABASE_VERSION;

        // Read the OTA emergency number database
        List<EmergencyNumber> updatedOtaEmergencyNumberList = new ArrayList<>();
        try {
            inputStream = new BufferedInputStream(
                    new FileInputStream(new File(Environment.getDataDirectory(),
                            EMERGENCY_NUMBER_DB_OTA_FILE_PATH)));
            allEccMessages = ProtobufEccData.AllInfo.parseFrom(readInputStreamToByteArray(
                    new GZIPInputStream(inputStream)));
            logd(mCountryIso + " ota emergency database is loaded. Ver: " + otaDatabaseVersion);
            otaDatabaseVersion = allEccMessages.revision;
            for (ProtobufEccData.CountryInfo countryEccInfo : allEccMessages.countries) {
                if (countryEccInfo.isoCode.equals(mCountryIso.toUpperCase())) {
                    for (ProtobufEccData.EccInfo eccInfo : countryEccInfo.eccs) {
                        updatedOtaEmergencyNumberList.add(convertEmergencyNumberFromEccInfo(
                                eccInfo, mCountryIso));
                    }
                }
            }
            EmergencyNumber.mergeSameNumbersInEmergencyNumberList(updatedOtaEmergencyNumberList);
        } catch (IOException ex) {
            loge("Cache ota emergency database failure: " + ex);
        } finally {
            // close quietly by catching non-runtime exceptions.
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (RuntimeException rethrown) {
                    throw rethrown;
                } catch (Exception ignored) {
                }
            }
        }

        // Use a valid database that has higher version.
        if (otaDatabaseVersion != INVALID_DATABASE_VERSION
                && mCurrentDatabaseVersion < otaDatabaseVersion) {
            mCurrentDatabaseVersion = otaDatabaseVersion;
            mEmergencyNumberListFromDatabase = updatedOtaEmergencyNumberList;
        }
        return otaDatabaseVersion;
    }

    /**
@@ -443,6 +539,25 @@ public class EmergencyNumberTracker extends Handler {
        notifyEmergencyNumberList();
    }

    private void updateOtaEmergencyNumberListDatabaseAndNotify() {
        logd("updateOtaEmergencyNumberListDatabaseAndNotify():"
                + " receiving Emegency Number database OTA update");
        if (cacheOtaEmergencyNumberDatabase() != INVALID_DATABASE_VERSION) {
            writeUpdatedEmergencyNumberListMetrics(mEmergencyNumberListFromDatabase);
            if (!DBG) {
                mEmergencyNumberListDatabaseLocalLog.log(
                        "updateOtaEmergencyNumberListDatabaseAndNotify:"
                            + mEmergencyNumberListFromDatabase);
            }
            updateEmergencyNumberList();
            if (!DBG) {
                mEmergencyNumberListLocalLog.log("updateOtaEmergencyNumberListDatabaseAndNotify:"
                        + mEmergencyNumberList);
            }
            notifyEmergencyNumberList();
        }
    }

    private void updateEmergencyNumberPrefixAndNotify(String[] emergencyNumberPrefix) {
        logd("updateEmergencyNumberPrefixAndNotify(): receiving emergencyNumberPrefix: "
                + Arrays.toString(emergencyNumberPrefix));