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