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

Commit f0dce34c authored by Shuo Qian's avatar Shuo Qian Committed by android-build-merger
Browse files

Merge "Integrate OTA emergency number database with EmergencyNumberTracker"

am: 3b47c9a1

Change-Id: I17c376326ece9a953c4a1098a87812a975b1dbb4
parents d733fecd 3b47c9a1
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));