1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/*
23345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Copyright (C) 2011 The Android Open Source Project
33345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *
43345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * Licensed under the Apache License, Version 2.0 (the "License");
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * you may not use this file except in compliance with the License.
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * You may obtain a copy of the License at
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *      http://www.apache.org/licenses/LICENSE-2.0
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Unless required by applicable law or agreed to in writing, software
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * distributed under the License is distributed on an "AS IS" BASIS,
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen * See the License for the specific language governing permissions and
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick * limitations under the License.
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenpackage com.android.cellbroadcastreceiver;
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickimport android.content.BroadcastReceiver;
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickimport android.content.Context;
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.content.Intent;
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.content.SharedPreferences;
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickimport android.content.pm.PackageManager;
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickimport android.os.RemoteException;
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickimport android.os.ServiceManager;
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.os.UserHandle;
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.preference.PreferenceManager;
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.provider.Telephony;
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.telephony.CellBroadcastMessage;
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.telephony.PhoneStateListener;
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.telephony.ServiceState;
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.telephony.TelephonyManager;
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.telephony.cdma.CdmaSmsCbProgramData;
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenimport android.util.Log;
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickimport com.android.internal.telephony.ITelephony;
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickimport com.android.internal.telephony.cdma.sms.SmsEnvelope;
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickpublic class CellBroadcastReceiver extends BroadcastReceiver {
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    private static final String TAG = "CellBroadcastReceiver";
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    static final boolean DBG = true;    // STOPSHIP: change to false before ship
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    private static final String GET_LATEST_CB_AREA_INFO_ACTION =
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            "android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO";
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    @Override
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    public void onReceive(Context context, Intent intent) {
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        onReceiveWithPrivilege(context, intent, false);
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    protected void onReceiveWithPrivilege(Context context, Intent intent, boolean privileged) {
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (DBG) log("onReceive " + intent);
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        String action = intent.getAction();
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (DBG) log("Registering for ServiceState updates");
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            TelephonyManager tm = (TelephonyManager) context.getSystemService(
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    Context.TELEPHONY_SERVICE);
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            tm.listen(new ServiceStateListener(context.getApplicationContext()),
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    PhoneStateListener.LISTEN_SERVICE_STATE);
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            boolean airplaneModeOn = intent.getBooleanExtra("state", false);
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (DBG) log("airplaneModeOn: " + airplaneModeOn);
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (!airplaneModeOn) {
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                startConfigService(context);
673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen            }
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } else if (Telephony.Sms.Intents.SMS_EMERGENCY_CB_RECEIVED_ACTION.equals(action) ||
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION.equals(action)) {
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            // If 'privileged' is false, it means that the intent was delivered to the base
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            // no-permissions receiver class.  If we get an SMS_CB_RECEIVED message that way, it
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            // means someone has tried to spoof the message by delivering it outside the normal
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            // permission-checked route, so we just ignore it.
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (privileged) {
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                intent.setClass(context, CellBroadcastAlertService.class);
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                context.startService(intent);
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            } else {
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                loge("ignoring unprivileged action received " + action);
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            }
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } else if (Telephony.Sms.Intents.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED_ACTION
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                .equals(action)) {
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (privileged) {
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                CdmaSmsCbProgramData[] programDataList = (CdmaSmsCbProgramData[])
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        intent.getParcelableArrayExtra("program_data_list");
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                if (programDataList != null) {
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    handleCdmaSmsCbProgramData(context, programDataList);
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                } else {
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    loge("SCPD intent received with no program_data_list");
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                }
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            } else {
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                loge("ignoring unprivileged action received " + action);
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            }
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } else if (GET_LATEST_CB_AREA_INFO_ACTION.equals(action)) {
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (privileged) {
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                CellBroadcastMessage message = CellBroadcastReceiverApp.getLatestAreaInfo();
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                if (message != null) {
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    Intent areaInfoIntent = new Intent(
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            CellBroadcastAlertService.CB_AREA_INFO_RECEIVED_ACTION);
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    areaInfoIntent.putExtra("message", message);
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    context.sendBroadcastAsUser(areaInfoIntent, UserHandle.ALL,
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            android.Manifest.permission.READ_PHONE_STATE);
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                }
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            } else {
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                Log.e(TAG, "caller missing READ_PHONE_STATE permission, returning");
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            }
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        } else {
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            Log.w(TAG, "onReceive() unexpected action " + action);
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Handle Service Category Program Data message.
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * TODO: Send Service Category Program Results response message to sender
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     *
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * @param context
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     * @param programDataList
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     */
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    private void handleCdmaSmsCbProgramData(Context context,
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            CdmaSmsCbProgramData[] programDataList) {
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        for (CdmaSmsCbProgramData programData : programDataList) {
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            switch (programData.getOperation()) {
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                case CdmaSmsCbProgramData.OPERATION_ADD_CATEGORY:
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    tryCdmaSetCategory(context, programData.getCategory(), true);
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    break;
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                case CdmaSmsCbProgramData.OPERATION_DELETE_CATEGORY:
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    tryCdmaSetCategory(context, programData.getCategory(), false);
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    break;
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                case CdmaSmsCbProgramData.OPERATION_CLEAR_CATEGORIES:
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    tryCdmaSetCategory(context,
1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT, false);
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    tryCdmaSetCategory(context,
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT, false);
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    tryCdmaSetCategory(context,
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY, false);
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    tryCdmaSetCategory(context,
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE, false);
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    break;
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                default:
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    loge("Ignoring unknown SCPD operation " + programData.getOperation());
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            }
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    private void tryCdmaSetCategory(Context context, int category, boolean enable) {
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        switch (category) {
1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            case SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT:
1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                sharedPrefs.edit().putBoolean(
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        CellBroadcastSettings.KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS, enable)
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        .apply();
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                break;
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            case SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT:
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                sharedPrefs.edit().putBoolean(
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        CellBroadcastSettings.KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS, enable)
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        .apply();
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                break;
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            case SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY:
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                sharedPrefs.edit().putBoolean(
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        CellBroadcastSettings.KEY_ENABLE_CMAS_AMBER_ALERTS, enable).apply();
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                break;
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            case SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE:
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                sharedPrefs.edit().putBoolean(
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        CellBroadcastSettings.KEY_ENABLE_CMAS_TEST_ALERTS, enable).apply();
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                break;
1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            default:
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                Log.w(TAG, "Ignoring SCPD command to " + (enable ? "enable" : "disable")
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        + " alerts in category " + category);
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    /**
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     * Tell {@link CellBroadcastConfigService} to enable the CB channels.
1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     * @param context the broadcast receiver context
1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     */
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    static void startConfigService(Context context) {
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        Intent serviceIntent = new Intent(CellBroadcastConfigService.ACTION_ENABLE_CHANNELS,
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                null, context, CellBroadcastConfigService.class);
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        context.startService(serviceIntent);
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    /**
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     * @return true if the phone is a CDMA phone type
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick     */
1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    static boolean phoneIsCdma() {
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        boolean isCdma = false;
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        try {
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (phone != null) {
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                isCdma = (phone.getActivePhoneType() == TelephonyManager.PHONE_TYPE_CDMA);
1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            }
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        } catch (RemoteException e) {
2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            Log.w(TAG, "phone.getActivePhoneType() failed", e);
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        return isCdma;
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    private static class ServiceStateListener extends PhoneStateListener {
206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        private final Context mContext;
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        private int mServiceState = -1;
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        ServiceStateListener(Context context) {
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            mContext = context;
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        @Override
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        public void onServiceStateChanged(ServiceState ss) {
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            int newState = ss.getState();
2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            if (newState != mServiceState) {
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                Log.d(TAG, "Service state changed! " + newState + " Full: " + ss);
2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                mServiceState = newState;
2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                if (newState == ServiceState.STATE_IN_SERVICE ||
2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        newState == ServiceState.STATE_EMERGENCY_ONLY) {
2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    startConfigService(mContext);
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                }
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            }
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    private static void log(String msg) {
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        Log.d(TAG, msg);
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    private static void loge(String msg) {
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        Log.e(TAG, msg);
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick