/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.sysprop.TelephonyProperties;
import android.telephony.CellInfo;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.LocalLog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.MccTable.MccMnc;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;

/**
 * The locale tracker keeps tracking the current locale of the phone.
 */
public class LocaleTracker extends Handler {
    private static final boolean DBG = true;

    /** Event for getting cell info from the modem */
    private static final int EVENT_REQUEST_CELL_INFO = 1;

    /** Event for service state changed */
    private static final int EVENT_SERVICE_STATE_CHANGED = 2;

    /** Event for sim state changed */
    private static final int EVENT_SIM_STATE_CHANGED = 3;

    /** Event for incoming unsolicited cell info */
    private static final int EVENT_UNSOL_CELL_INFO = 4;

    /** Event for incoming cell info */
    private static final int EVENT_RESPONSE_CELL_INFO = 5;

    /** Event to fire if the operator from ServiceState is considered truly lost */
    private static final int EVENT_OPERATOR_LOST = 6;

    /** Event to override the current locale */
    private static final int EVENT_OVERRIDE_LOCALE = 7;

    /**
     * The broadcast intent action to override the current country for testing purposes
     *
     * <p> This broadcast is not effective on user build.
     *
     * <p>Example: To override the current country <code>
     * adb shell am broadcast -a com.android.internal.telephony.action.COUNTRY_OVERRIDE
     * --es country us </code>
     *
     * <p> To remove the override <code>
     * adb shell am broadcast -a com.android.internal.telephony.action.COUNTRY_OVERRIDE
     * --ez reset true</code>
     */
    private static final String ACTION_COUNTRY_OVERRIDE =
            "com.android.internal.telephony.action.COUNTRY_OVERRIDE";

    /** The extra for country override */
    private static final String EXTRA_COUNTRY = "country";

    /** The extra for country override reset */
    private static final String EXTRA_RESET = "reset";

    // Todo: Read this from Settings.
    /** The minimum delay to get cell info from the modem */
    private static final long CELL_INFO_MIN_DELAY_MS = 2 * SECOND_IN_MILLIS;

    // Todo: Read this from Settings.
    /** The maximum delay to get cell info from the modem */
    private static final long CELL_INFO_MAX_DELAY_MS = 10 * MINUTE_IN_MILLIS;

    // Todo: Read this from Settings.
    /** The delay for periodically getting cell info from the modem */
    private static final long CELL_INFO_PERIODIC_POLLING_DELAY_MS = 10 * MINUTE_IN_MILLIS;

    /**
     * The delay after the last time the device camped on a cell before declaring that the
     * ServiceState's MCC information can no longer be used (and thus kicking in the CellInfo
     * based tracking.
     */
    private static final long SERVICE_OPERATOR_LOST_DELAY_MS = 10 * MINUTE_IN_MILLIS;

    /** The maximum fail count to prevent delay time overflow */
    private static final int MAX_FAIL_COUNT = 30;

    /** The last known country iso */
    private static final String LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY =
            "last_known_country_iso";

    private String mTag;

    private final Phone mPhone;

    private final NitzStateMachine mNitzStateMachine;

    /** SIM card state. Must be one of TelephonyManager.SIM_STATE_XXX */
    private int mSimState;

    /** Current serving PLMN's MCC/MNC */
    @Nullable
    private String mOperatorNumeric;

    /** Current cell tower information */
    @Nullable
    private List<CellInfo> mCellInfoList;

    /** Count of invalid cell info we've got so far. Will reset once we get a successful one */
    private int mFailCellInfoCount;

    /** The ISO-3166 two-letter code of device's current country */
    @Nullable
    private String mCurrentCountryIso;

    /** The country override for testing purposes */
    @Nullable
    private String mCountryOverride;

    /** Current service state. Must be one of ServiceState.STATE_XXX. */
    private int mLastServiceState = ServiceState.STATE_POWER_OFF;

    private boolean mIsTracking = false;

    private final LocalLog mLocalLog = new LocalLog(50);

    /** Broadcast receiver to get SIM card state changed event */
    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals(intent.getAction())) {
                int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
                if (phoneId == mPhone.getPhoneId()) {
                    obtainMessage(EVENT_SIM_STATE_CHANGED,
                            intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE,
                                    TelephonyManager.SIM_STATE_UNKNOWN), 0).sendToTarget();
                }
            } else if (ACTION_COUNTRY_OVERRIDE.equals(intent.getAction())) {
                String countryOverride = intent.getStringExtra(EXTRA_COUNTRY);
                boolean reset = intent.getBooleanExtra(EXTRA_RESET, false);
                if (reset) countryOverride = null;
                log("Received country override: " + countryOverride);
                // countryOverride null to reset the override.
                obtainMessage(EVENT_OVERRIDE_LOCALE, countryOverride).sendToTarget();
            }
        }
    };

    /**
     * Message handler
     *
     * @param msg The message
     */
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case EVENT_REQUEST_CELL_INFO:
                mPhone.requestCellInfoUpdate(null, obtainMessage(EVENT_RESPONSE_CELL_INFO));
                break;

            case EVENT_UNSOL_CELL_INFO:
                processCellInfo((AsyncResult) msg.obj);
                // If the unsol happened to be useful, use it; otherwise, pretend it didn't happen.
                if (mCellInfoList != null && mCellInfoList.size() > 0) requestNextCellInfo(true);
                break;

            case EVENT_RESPONSE_CELL_INFO:
                processCellInfo((AsyncResult) msg.obj);
                // If the cellInfo was non-empty then it's business as usual. Either way, this
                // cell info was requested by us, so it's our trigger to schedule another one.
                requestNextCellInfo(mCellInfoList != null && mCellInfoList.size() > 0);
                break;

            case EVENT_SERVICE_STATE_CHANGED:
                AsyncResult ar = (AsyncResult) msg.obj;
                onServiceStateChanged((ServiceState) ar.result);
                break;

            case EVENT_SIM_STATE_CHANGED:
                onSimCardStateChanged(msg.arg1);
                break;

            case EVENT_OPERATOR_LOST:
                updateOperatorNumericImmediate("");
                updateTrackingStatus();
                break;

            case EVENT_OVERRIDE_LOCALE:
                mCountryOverride = (String) msg.obj;
                updateLocale();
                break;

            default:
                throw new IllegalStateException("Unexpected message arrives. msg = " + msg.what);
        }
    }

    /**
     * Constructor
     *
     * @param phone The phone object
     * @param nitzStateMachine NITZ state machine
     * @param looper The looper message handler
     */
    public LocaleTracker(Phone phone, NitzStateMachine nitzStateMachine, Looper looper)  {
        super(looper);
        mPhone = phone;
        mNitzStateMachine = nitzStateMachine;
        mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
        mTag = LocaleTracker.class.getSimpleName() + "-" + mPhone.getPhoneId();

        final IntentFilter filter = new IntentFilter();
        filter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
        if (TelephonyUtils.IS_DEBUGGABLE) {
            filter.addAction(ACTION_COUNTRY_OVERRIDE);
        }
        mPhone.getContext().registerReceiver(mBroadcastReceiver, filter);

        mPhone.registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null);
        mPhone.registerForCellInfo(this, EVENT_UNSOL_CELL_INFO, null);
    }

    private @NonNull String getCarrierCountry() {
        // The locale from the "ro.carrier" system property or R.array.carrier_properties.
        // This will be overwritten by the Locale from the SIM language settings (EF-PL, EF-LI)
        // if applicable.
        final Locale carrierLocale = mPhone.getLocaleFromCarrierProperties();
        if (carrierLocale != null && !TextUtils.isEmpty(carrierLocale.getCountry())) {
            return carrierLocale.getCountry();
        }
        return "";
    }

    /**
     * Get the device's current country.
     *
     * @return The device's current country. Empty string if the information is not available.
     */
    @NonNull
    public String getCurrentCountry() {
        return (mCurrentCountryIso != null) ? mCurrentCountryIso : "";
    }

    /**
     * Get the MCC from cell tower information.
     *
     * @return MCC in string format. Null if the information is not available.
     */
    @Nullable
    private String getMccFromCellInfo() {
        String selectedMcc = null;
        if (mCellInfoList != null) {
            Map<String, Integer> mccMap = new HashMap<>();
            int maxCount = 0;
            for (CellInfo cellInfo : mCellInfoList) {
                String mcc = cellInfo.getCellIdentity().getMccString();
                if (mcc != null) {
                    int count = 1;
                    if (mccMap.containsKey(mcc)) {
                        count = mccMap.get(mcc) + 1;
                    }
                    mccMap.put(mcc, count);
                    // This is unlikely, but if MCC from cell info looks different, we choose the
                    // MCC that occurs most.
                    if (count > maxCount) {
                        maxCount = count;
                        selectedMcc = mcc;
                    }
                }
            }
        }
        return selectedMcc;
    }

    /**
     * Get the most frequent MCC + MNC combination with the specified MCC using cell tower
     * information. If no one combination is more frequent than any other an arbitrary MCC + MNC is
     * returned with the matching MCC. The MNC value returned can be null if it is not provided by
     * the cell tower information.
     *
     * @param mccToMatch the MCC to match
     * @return a matching {@link MccMnc}. Null if the information is not available.
     */
    @Nullable
    private MccMnc getMccMncFromCellInfo(@NonNull String mccToMatch) {
        MccMnc selectedMccMnc = null;
        if (mCellInfoList != null) {
            Map<MccMnc, Integer> mccMncMap = new HashMap<>();
            int maxCount = 0;
            for (CellInfo cellInfo : mCellInfoList) {
                String mcc = cellInfo.getCellIdentity().getMccString();
                if (Objects.equals(mcc, mccToMatch)) {
                    String mnc = cellInfo.getCellIdentity().getMncString();
                    MccMnc mccMnc = new MccMnc(mcc, mnc);
                    int count = 1;
                    if (mccMncMap.containsKey(mccMnc)) {
                        count = mccMncMap.get(mccMnc) + 1;
                    }
                    mccMncMap.put(mccMnc, count);
                    // We keep track of the MCC+MNC combination that occurs most frequently, if
                    // there is one. A null MNC is treated like any other distinct MCC+MNC
                    // combination.
                    if (count > maxCount) {
                        maxCount = count;
                        selectedMccMnc = mccMnc;
                    }
                }
            }
        }
        return selectedMccMnc;
    }

    /**
     * Called when SIM card state changed. Only when we absolutely know the SIM is absent, we get
     * cell info from the network. Other SIM states like NOT_READY might be just a transitioning
     * state.
     *
     * @param state SIM card state. Must be one of TelephonyManager.SIM_STATE_XXX.
     */
    private void onSimCardStateChanged(int state) {
        mSimState = state;
        updateLocale();
        updateTrackingStatus();
    }

    /**
     * Called when service state changed.
     *
     * @param serviceState Service state
     */
    private void onServiceStateChanged(ServiceState serviceState) {
        mLastServiceState = serviceState.getState();
        updateLocale();
        updateTrackingStatus();
    }

    /**
     * Update MCC/MNC from network service state.
     *
     * @param operatorNumeric MCC/MNC of the operator
     */
    public void updateOperatorNumeric(String operatorNumeric) {
        if (TextUtils.isEmpty(operatorNumeric)) {
            sendMessageDelayed(obtainMessage(EVENT_OPERATOR_LOST), SERVICE_OPERATOR_LOST_DELAY_MS);
        } else {
            removeMessages(EVENT_OPERATOR_LOST);
            updateOperatorNumericImmediate(operatorNumeric);
        }
    }

    private void updateOperatorNumericImmediate(String operatorNumeric) {
        // Check if the operator numeric changes.
        if (!operatorNumeric.equals(mOperatorNumeric)) {
            String msg = "Operator numeric changes to \"" + operatorNumeric + "\"";
            if (DBG) log(msg);
            mLocalLog.log(msg);
            mOperatorNumeric = operatorNumeric;
            updateLocale();
        }
    }

    private void processCellInfo(AsyncResult ar) {
        if (ar == null || ar.exception != null) {
            mCellInfoList = null;
            return;
        }
        List<CellInfo> cellInfoList = (List<CellInfo>) ar.result;
        String msg = "processCellInfo: cell info=" + cellInfoList;
        if (DBG) log(msg);
        mCellInfoList = cellInfoList;
        updateLocale();
    }

    private void requestNextCellInfo(boolean succeeded) {
        if (!mIsTracking) return;

        removeMessages(EVENT_REQUEST_CELL_INFO);
        if (succeeded) {
            resetCellInfoRetry();
            // Now we need to get the cell info from the modem periodically
            // even if we already got the cell info because the user can move.
            removeMessages(EVENT_UNSOL_CELL_INFO);
            removeMessages(EVENT_RESPONSE_CELL_INFO);
            sendMessageDelayed(obtainMessage(EVENT_REQUEST_CELL_INFO),
                    CELL_INFO_PERIODIC_POLLING_DELAY_MS);
        } else {
            // If we can't get a valid cell info. Try it again later.
            long delay = getCellInfoDelayTime(++mFailCellInfoCount);
            if (DBG) log("Can't get cell info. Try again in " + delay / 1000 + " secs.");
            sendMessageDelayed(obtainMessage(EVENT_REQUEST_CELL_INFO), delay);
        }
    }

    /**
     * Get the delay time to get cell info from modem. The delay time grows exponentially to prevent
     * battery draining.
     *
     * @param failCount Count of invalid cell info we've got so far.
     * @return The delay time for next get cell info
     */
    @VisibleForTesting
    public static long getCellInfoDelayTime(int failCount) {
        // Exponentially grow the delay time. Note we limit the fail count to MAX_FAIL_COUNT to
        // prevent overflow in Math.pow().
        long delay = CELL_INFO_MIN_DELAY_MS
                * (long) Math.pow(2, Math.min(failCount, MAX_FAIL_COUNT) - 1);
        return Math.min(Math.max(delay, CELL_INFO_MIN_DELAY_MS), CELL_INFO_MAX_DELAY_MS);
    }

    /**
     * Stop retrying getting cell info from the modem. It cancels any scheduled cell info retrieving
     * request.
     */
    private void resetCellInfoRetry() {
        mFailCellInfoCount = 0;
        removeMessages(EVENT_REQUEST_CELL_INFO);
    }

    private void updateTrackingStatus() {
        boolean shouldTrackLocale =
                (mSimState == TelephonyManager.SIM_STATE_ABSENT
                        || TextUtils.isEmpty(mOperatorNumeric))
                && (mLastServiceState == ServiceState.STATE_OUT_OF_SERVICE
                        || mLastServiceState == ServiceState.STATE_EMERGENCY_ONLY);
        if (shouldTrackLocale) {
            startTracking();
        } else {
            stopTracking();
        }
    }

    private void stopTracking() {
        if (!mIsTracking) return;
        mIsTracking = false;
        String msg = "Stopping LocaleTracker";
        if (DBG) log(msg);
        mLocalLog.log(msg);
        mCellInfoList = null;
        resetCellInfoRetry();
    }

    private void startTracking() {
        if (mIsTracking) return;
        String msg = "Starting LocaleTracker";
        mLocalLog.log(msg);
        if (DBG) log(msg);
        mIsTracking = true;
        sendMessage(obtainMessage(EVENT_REQUEST_CELL_INFO));
    }

    /**
     * Update the device's current locale
     */
    private synchronized void updateLocale() {
        // If MCC is available from network service state, use it first.
        String countryIso = getCarrierCountry();
        String countryIsoDebugInfo = "getCarrierCountry()";

        // For time zone detection we want the best geographical match we can get, which may differ
        // from the countryIso.
        String timeZoneCountryIso = null;
        String timeZoneCountryIsoDebugInfo = null;

        if (!TextUtils.isEmpty(mOperatorNumeric)) {
            MccMnc mccMnc = MccMnc.fromOperatorNumeric(mOperatorNumeric);
            if (mccMnc != null) {
                countryIso = MccTable.countryCodeForMcc(mccMnc.mcc);
                countryIsoDebugInfo = "OperatorNumeric(" + mOperatorNumeric
                        + "): MccTable.countryCodeForMcc(\"" + mccMnc.mcc + "\")";
                timeZoneCountryIso = MccTable.geoCountryCodeForMccMnc(mccMnc);
                timeZoneCountryIsoDebugInfo =
                        "OperatorNumeric: MccTable.geoCountryCodeForMccMnc(" + mccMnc + ")";
            } else {
                loge("updateLocale: Can't get country from operator numeric. mOperatorNumeric = "
                        + mOperatorNumeric);
            }
        }

        // If for any reason we can't get country from operator numeric, try to get it from cell
        // info.
        if (TextUtils.isEmpty(countryIso)) {
            String mcc = getMccFromCellInfo();
            if (mcc != null) {
                countryIso = MccTable.countryCodeForMcc(mcc);
                countryIsoDebugInfo = "CellInfo: MccTable.countryCodeForMcc(\"" + mcc + "\")";

                MccMnc mccMnc = getMccMncFromCellInfo(mcc);
                if (mccMnc != null) {
                    timeZoneCountryIso = MccTable.geoCountryCodeForMccMnc(mccMnc);
                    timeZoneCountryIsoDebugInfo =
                            "CellInfo: MccTable.geoCountryCodeForMccMnc(" + mccMnc + ")";
                }
            }
        }

        if (mCountryOverride != null) {
            countryIso = mCountryOverride;
            countryIsoDebugInfo = "mCountryOverride = \"" + mCountryOverride + "\"";
            timeZoneCountryIso = countryIso;
            timeZoneCountryIsoDebugInfo = countryIsoDebugInfo;
        }

        if (mLastServiceState == ServiceState.STATE_POWER_OFF) {
            countryIso = "";
        }

        log("updateLocale: countryIso = " + countryIso
                + ", countryIsoDebugInfo = " + countryIsoDebugInfo);
        if (!Objects.equals(countryIso, mCurrentCountryIso)) {
            String msg = "updateLocale: Change the current country to \"" + countryIso + "\""
                    + ", countryIsoDebugInfo = " + countryIsoDebugInfo
                    + ", mCellInfoList = " + mCellInfoList;
            log(msg);
            mLocalLog.log(msg);
            mCurrentCountryIso = countryIso;

            // Update the last known country ISO
            if (!TextUtils.isEmpty(mCurrentCountryIso)) {
                updateLastKnownCountryIso(mCurrentCountryIso);
            }

            int phoneId = mPhone.getPhoneId();
            if (SubscriptionManager.isValidPhoneId(phoneId)) {
                List<String> newProp = new ArrayList<>(
                        TelephonyProperties.operator_iso_country());
                while (newProp.size() <= phoneId) newProp.add(null);
                newProp.set(phoneId, mCurrentCountryIso);
                TelephonyProperties.operator_iso_country(newProp);
            }

            Intent intent = new Intent(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED);
            intent.putExtra(TelephonyManager.EXTRA_NETWORK_COUNTRY, countryIso);
            intent.putExtra(TelephonyManager.EXTRA_LAST_KNOWN_NETWORK_COUNTRY,
                    getLastKnownCountryIso());
            SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
            mPhone.getContext().sendBroadcast(intent);
        }

        // Pass the geographical country information to the telephony time zone detection code.

        boolean isTestMcc = false;
        if (!TextUtils.isEmpty(mOperatorNumeric)) {
            // For a test cell (MCC 001), the NitzStateMachine requires handleCountryDetected("") in
            // order to pass compliance tests. http://b/142840879
            if (mOperatorNumeric.startsWith("001")) {
                isTestMcc = true;
                timeZoneCountryIso = "";
                timeZoneCountryIsoDebugInfo = "Test cell: " + mOperatorNumeric;
            }
        }
        if (timeZoneCountryIso == null) {
            // After this timeZoneCountryIso may still be null.
            timeZoneCountryIso = countryIso;
            timeZoneCountryIsoDebugInfo = "Defaulted: " + countryIsoDebugInfo;
        }
        log("updateLocale: timeZoneCountryIso = " + timeZoneCountryIso
                + ", timeZoneCountryIsoDebugInfo = " + timeZoneCountryIsoDebugInfo);

        if (TextUtils.isEmpty(timeZoneCountryIso) && !isTestMcc) {
            mNitzStateMachine.handleCountryUnavailable();
        } else {
            mNitzStateMachine.handleCountryDetected(timeZoneCountryIso);
        }
    }

    /** Exposed for testing purposes */
    public boolean isTracking() {
        return mIsTracking;
    }

    private void updateLastKnownCountryIso(String countryIso) {
        if (!TextUtils.isEmpty(countryIso)) {
            final SharedPreferences prefs = mPhone.getContext().getSharedPreferences(
                    LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, Context.MODE_PRIVATE);
            final SharedPreferences.Editor editor = prefs.edit();
            editor.putString(LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, countryIso);
            editor.commit();
            log("update country iso in sharedPrefs " + countryIso);
        }
    }

    /**
     *  Return the last known country ISO before device is not camping on a network
     *  (e.g. Airplane Mode)
     *
     *  @return The device's last known country ISO.
     */
    @NonNull
    public String getLastKnownCountryIso() {
        final SharedPreferences prefs = mPhone.getContext().getSharedPreferences(
                LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, Context.MODE_PRIVATE);
        return prefs.getString(LAST_KNOWN_COUNTRY_ISO_SHARED_PREFS_KEY, "");
    }

    private void log(String msg) {
        Rlog.d(mTag, msg);
    }

    private void loge(String msg) {
        Rlog.e(mTag, msg);
    }

    /**
     * Print the DeviceStateMonitor into the given stream.
     *
     * @param fd The raw file descriptor that the dump is being sent to.
     * @param pw A PrintWriter to which the dump is to be set.
     * @param args Additional arguments to the dump request.
     */
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
        pw.println("LocaleTracker-" + mPhone.getPhoneId() + ":");
        ipw.increaseIndent();
        ipw.println("mIsTracking = " + mIsTracking);
        ipw.println("mOperatorNumeric = " + mOperatorNumeric);
        ipw.println("mSimState = " + mSimState);
        ipw.println("mCellInfoList = " + mCellInfoList);
        ipw.println("mCurrentCountryIso = " + mCurrentCountryIso);
        ipw.println("mFailCellInfoCount = " + mFailCellInfoCount);
        ipw.println("Local logs:");
        ipw.increaseIndent();
        mLocalLog.dump(fd, ipw, args);
        ipw.decreaseIndent();
        ipw.decreaseIndent();
        ipw.flush();
    }
}
