1705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek/* 2705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * Copyright (C) 2016 The Android Open Source Project 3705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * 4705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * Licensed under the Apache License, Version 2.0 (the "License"); 5705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * you may not use this file except in compliance with the License. 6705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * You may obtain a copy of the License at 7705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * 8705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * http://www.apache.org/licenses/LICENSE-2.0 9705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * 10705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * Unless required by applicable law or agreed to in writing, software 11705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * distributed under the License is distributed on an "AS IS" BASIS, 12705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * See the License for the specific language governing permissions and 14705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * limitations under the License 15705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek */ 16705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 17705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekpackage com.android.server.emergency; 18705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 19705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.content.BroadcastReceiver; 20705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.content.Context; 21705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.content.Intent; 22705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.content.IntentFilter; 23705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.os.Handler; 24705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.os.HandlerThread; 25705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.os.Looper; 26705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.os.Message; 27705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.provider.Settings; 28705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.CellInfo; 29705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.CellInfoGsm; 30705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.CellInfoLte; 31705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.CellInfoWcdma; 32705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.CellLocation; 33705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.PhoneStateListener; 34705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.SubscriptionInfo; 35705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.SubscriptionManager; 36705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport android.telephony.TelephonyManager; 37705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 38705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport com.android.server.SystemService; 39705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 40705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport java.util.ArrayList; 41705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport java.util.Arrays; 42705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekimport java.util.List; 43705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 44705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek/** 45705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * A service that listens to connectivity and SIM card changes and determines if the emergency mode 46705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * should be enabled 47705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek */ 48705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinekpublic class EmergencyAffordanceService extends SystemService { 49705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 50705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private static final String TAG = "EmergencyAffordanceService"; 51705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 52705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private static final int NUM_SCANS_UNTIL_ABORT = 4; 53705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 54705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private static final int INITIALIZE_STATE = 1; 55705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private static final int CELL_INFO_STATE_CHANGED = 2; 56705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private static final int SUBSCRIPTION_CHANGED = 3; 57705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 58705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek /** 59705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * Global setting, whether the last scan of the sim cards reveal that a sim was inserted that 60705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * requires the emergency affordance. The value is a boolean (1 or 0). 61705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek * @hide 62705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek */ 63705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private static final String EMERGENCY_SIM_INSERTED_SETTING = "emergency_sim_inserted_before"; 64705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 65705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private final Context mContext; 66705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private final ArrayList<Integer> mEmergencyCallMccNumbers; 67705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 68705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private final Object mLock = new Object(); 69705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 70705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private TelephonyManager mTelephonyManager; 71705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private SubscriptionManager mSubscriptionManager; 72705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean mEmergencyAffordanceNeeded; 73705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private MyHandler mHandler; 74705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private int mScansCompleted; 75705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { 76705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek @Override 77705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public void onCellInfoChanged(List<CellInfo> cellInfo) { 78705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (!isEmergencyAffordanceNeeded()) { 79705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek requestCellScan(); 80705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 81705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 82705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 83705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek @Override 84705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public void onCellLocationChanged(CellLocation location) { 85705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (!isEmergencyAffordanceNeeded()) { 86705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek requestCellScan(); 87705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 88705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 89705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek }; 90705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private BroadcastReceiver mAirplaneModeReceiver = new BroadcastReceiver() { 91705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek @Override 92705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public void onReceive(Context context, Intent intent) { 93705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (Settings.Global.getInt(context.getContentResolver(), 94705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek Settings.Global.AIRPLANE_MODE_ON, 0) == 0) { 95705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek startScanning(); 96705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek requestCellScan(); 97705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 98705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 99705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek }; 100705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean mSimNeedsEmergencyAffordance; 101705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean mNetworkNeedsEmergencyAffordance; 102bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek private boolean mVoiceCapable; 103705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 104705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void requestCellScan() { 105705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mHandler.obtainMessage(CELL_INFO_STATE_CHANGED).sendToTarget(); 106705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 107705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 108705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionChangedListener 109705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek = new SubscriptionManager.OnSubscriptionsChangedListener() { 110705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek @Override 111705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public void onSubscriptionsChanged() { 112705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mHandler.obtainMessage(SUBSCRIPTION_CHANGED).sendToTarget(); 113705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 114705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek }; 115705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 116705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public EmergencyAffordanceService(Context context) { 117705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek super(context); 118705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mContext = context; 119705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek int[] numbers = context.getResources().getIntArray( 120705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek com.android.internal.R.array.config_emergency_mcc_codes); 121705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mEmergencyCallMccNumbers = new ArrayList<>(numbers.length); 122705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek for (int i = 0; i < numbers.length; i++) { 123705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mEmergencyCallMccNumbers.add(numbers[i]); 124705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 125705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 126705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 127705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void updateEmergencyAffordanceNeeded() { 128705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek synchronized (mLock) { 129bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek mEmergencyAffordanceNeeded = mVoiceCapable && (mSimNeedsEmergencyAffordance || 130bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek mNetworkNeedsEmergencyAffordance); 131705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek Settings.Global.putInt(mContext.getContentResolver(), 132705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek Settings.Global.EMERGENCY_AFFORDANCE_NEEDED, 133705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mEmergencyAffordanceNeeded ? 1 : 0); 134705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (mEmergencyAffordanceNeeded) { 135705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek stopScanning(); 136705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 137705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 138705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 139705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 140705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void stopScanning() { 141705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek synchronized (mLock) { 142705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); 143705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mScansCompleted = 0; 144705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 145705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 146705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 147705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean isEmergencyAffordanceNeeded() { 148705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek synchronized (mLock) { 149705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return mEmergencyAffordanceNeeded; 150705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 151705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 152705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 153705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek @Override 154705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public void onStart() { 155705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 156705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 157705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek @Override 158705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public void onBootPhase(int phase) { 159705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 160705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mTelephonyManager = mContext.getSystemService(TelephonyManager.class); 161bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek mVoiceCapable = mTelephonyManager.isVoiceCapable(); 162bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek if (!mVoiceCapable) { 163bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek updateEmergencyAffordanceNeeded(); 164bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek return; 165bd740cd56ac93e0e9fe6881cee927f7dbdd06620Selim Cinek } 166705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mSubscriptionManager = SubscriptionManager.from(mContext); 167705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek HandlerThread thread = new HandlerThread(TAG); 168705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek thread.start(); 169705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mHandler = new MyHandler(thread.getLooper()); 170705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mHandler.obtainMessage(INITIALIZE_STATE).sendToTarget(); 171705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek startScanning(); 172705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED); 173705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mContext.registerReceiver(mAirplaneModeReceiver, filter); 174705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionChangedListener); 175705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 176705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 177705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 178705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void startScanning() { 179705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CELL_INFO 180705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek | PhoneStateListener.LISTEN_CELL_LOCATION); 181705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 182705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 183705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek /** Handler to do the heavier work on */ 184705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private class MyHandler extends Handler { 185705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 186705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public MyHandler(Looper l) { 187705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek super(l); 188705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 189705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 190705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek @Override 191705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek public void handleMessage(Message msg) { 192705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek switch (msg.what) { 193705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek case INITIALIZE_STATE: 194705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek handleInitializeState(); 195705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek break; 196705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek case CELL_INFO_STATE_CHANGED: 197705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek handleUpdateCellInfo(); 198705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek break; 199705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek case SUBSCRIPTION_CHANGED: 200705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek handleUpdateSimSubscriptionInfo(); 201705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek break; 202705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 203705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 204705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 205705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 206705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void handleInitializeState() { 207705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (handleUpdateSimSubscriptionInfo()) { 208705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return; 209705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 210705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (handleUpdateCellInfo()) { 211705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return; 212705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 213705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek updateEmergencyAffordanceNeeded(); 214705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 215705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 216705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean handleUpdateSimSubscriptionInfo() { 217705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek boolean neededBefore = simNeededAffordanceBefore(); 218705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek boolean neededNow = neededBefore; 219705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek List<SubscriptionInfo> activeSubscriptionInfoList = 220705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mSubscriptionManager.getActiveSubscriptionInfoList(); 221705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (activeSubscriptionInfoList == null) { 2223d465761d7bc81a763827bf80ac054b67a931ab5Ruthwar Kumar Ambeer setSimNeedsEmergencyAffordance(neededNow); 223705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return neededNow; 224705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 225705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek for (SubscriptionInfo info : activeSubscriptionInfoList) { 226705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek int mcc = info.getMcc(); 227705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (mccRequiresEmergencyAffordance(mcc)) { 228705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek neededNow = true; 229705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek break; 230705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } else if (mcc != 0 && mcc != Integer.MAX_VALUE){ 231705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek // a Sim with a different mcc code was found 232705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek neededNow = false; 233705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 234705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek String simOperator = mTelephonyManager.getSimOperator(info.getSubscriptionId()); 235705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mcc = 0; 236705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (simOperator != null && simOperator.length() >= 3) { 237705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mcc = Integer.parseInt(simOperator.substring(0, 3)); 238705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 239705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (mcc != 0) { 240705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (mccRequiresEmergencyAffordance(mcc)) { 241705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek neededNow = true; 242705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek break; 243705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } else { 244705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek // a Sim with a different mcc code was found 245705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek neededNow = false; 246705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 247705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 248705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 249e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek setSimNeedsEmergencyAffordance(neededNow); 250705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return neededNow; 251705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 252705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 253705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void setSimNeedsEmergencyAffordance(boolean simNeedsEmergencyAffordance) { 254e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek if (simNeededAffordanceBefore() != simNeedsEmergencyAffordance) { 255e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek Settings.Global.putInt(mContext.getContentResolver(), 256e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek EMERGENCY_SIM_INSERTED_SETTING, 257e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek simNeedsEmergencyAffordance ? 1 : 0); 258e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek } 259e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek if (simNeedsEmergencyAffordance != mSimNeedsEmergencyAffordance) { 260e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek mSimNeedsEmergencyAffordance = simNeedsEmergencyAffordance; 261e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek updateEmergencyAffordanceNeeded(); 262e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek } 263705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 264705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 265705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean simNeededAffordanceBefore() { 266705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return Settings.Global.getInt(mContext.getContentResolver(), 267e0358de1e4ba56f0de74e93e9402b258aa489159Selim Cinek EMERGENCY_SIM_INSERTED_SETTING, 0) != 0; 268705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 269705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 270705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean handleUpdateCellInfo() { 271705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek List<CellInfo> cellInfos = mTelephonyManager.getAllCellInfo(); 272705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (cellInfos == null) { 273705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return false; 274705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 275705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek boolean stopScanningAfterScan = false; 276705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek for (CellInfo cellInfo : cellInfos) { 277705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek int mcc = 0; 278705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (cellInfo instanceof CellInfoGsm) { 279705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mcc = ((CellInfoGsm) cellInfo).getCellIdentity().getMcc(); 280705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } else if (cellInfo instanceof CellInfoLte) { 281705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mcc = ((CellInfoLte) cellInfo).getCellIdentity().getMcc(); 282705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } else if (cellInfo instanceof CellInfoWcdma) { 283705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mcc = ((CellInfoWcdma) cellInfo).getCellIdentity().getMcc(); 284705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 285705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (mccRequiresEmergencyAffordance(mcc)) { 286705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek setNetworkNeedsEmergencyAffordance(true); 287705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return true; 288705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } else if (mcc != 0 && mcc != Integer.MAX_VALUE) { 289705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek // we found an mcc that isn't in the list, abort 290705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek stopScanningAfterScan = true; 291705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 292705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 293705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (stopScanningAfterScan) { 294705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek stopScanning(); 295705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } else { 296705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek onCellScanFinishedUnsuccessful(); 297705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 298705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek setNetworkNeedsEmergencyAffordance(false); 299705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return false; 300705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 301705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 302705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void setNetworkNeedsEmergencyAffordance(boolean needsAffordance) { 303705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek synchronized (mLock) { 304705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mNetworkNeedsEmergencyAffordance = needsAffordance; 305705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek updateEmergencyAffordanceNeeded(); 306705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 307705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 308705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 309705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private void onCellScanFinishedUnsuccessful() { 310705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek synchronized (mLock) { 311705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek mScansCompleted++; 312705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek if (mScansCompleted >= NUM_SCANS_UNTIL_ABORT) { 313705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek stopScanning(); 314705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 315705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 316705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 317705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek 318705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek private boolean mccRequiresEmergencyAffordance(int mcc) { 319705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek return mEmergencyCallMccNumbers.contains(mcc); 320705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek } 321705442fa7dcbf1bf92595fdaca6cc888810931d8Selim Cinek} 322