1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.SharedPreferences;
24 import android.net.LinkProperties;
25 import android.net.NetworkCapabilities;
26 import android.net.wifi.WifiManager;
27 import android.os.AsyncResult;
28 import android.os.Build;
29 import android.os.Handler;
30 import android.os.Looper;
31 import android.os.Message;
32 import android.os.Registrant;
33 import android.os.RegistrantList;
34 import android.os.SystemProperties;
35 import android.preference.PreferenceManager;
36 import android.provider.Settings;
37 import android.telecom.VideoProfile;
38 import android.telephony.CellIdentityCdma;
39 import android.telephony.CellInfo;
40 import android.telephony.CellInfoCdma;
41 import android.telephony.DataConnectionRealTimeInfo;
42 import android.telephony.RadioAccessFamily;
43 import android.telephony.Rlog;
44 import android.telephony.ServiceState;
45 import android.telephony.SignalStrength;
46 import android.telephony.SubscriptionManager;
47 import android.telephony.VoLteServiceState;
48 import android.text.TextUtils;
49 
50 import com.android.ims.ImsManager;
51 import com.android.internal.R;
52 import com.android.internal.telephony.dataconnection.DcTrackerBase;
53 import com.android.internal.telephony.imsphone.ImsPhone;
54 import com.android.internal.telephony.RadioCapability;
55 import com.android.internal.telephony.test.SimulatedRadioControl;
56 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
57 import com.android.internal.telephony.uicc.IccFileHandler;
58 import com.android.internal.telephony.uicc.IccRecords;
59 import com.android.internal.telephony.uicc.IsimRecords;
60 import com.android.internal.telephony.uicc.UiccCard;
61 import com.android.internal.telephony.uicc.UiccCardApplication;
62 import com.android.internal.telephony.uicc.UiccController;
63 import com.android.internal.telephony.uicc.UsimServiceTable;
64 
65 import java.io.FileDescriptor;
66 import java.io.PrintWriter;
67 import java.util.ArrayList;
68 import java.util.HashSet;
69 import java.util.List;
70 import java.util.Locale;
71 import java.util.Set;
72 import java.util.concurrent.atomic.AtomicReference;
73 
74 /**
75  * (<em>Not for SDK use</em>)
76  * A base implementation for the com.android.internal.telephony.Phone interface.
77  *
78  * Note that implementations of Phone.java are expected to be used
79  * from a single application thread. This should be the same thread that
80  * originally called PhoneFactory to obtain the interface.
81  *
82  *  {@hide}
83  *
84  */
85 
86 public abstract class PhoneBase extends Handler implements Phone {
87     private static final String LOG_TAG = "PhoneBase";
88 
89     private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
90         @Override
91         public void onReceive(Context context, Intent intent) {
92             Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction());
93             if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) {
94                 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID,
95                         SubscriptionManager.INVALID_PHONE_INDEX);
96                 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId);
97                 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX ||
98                         extraPhoneId != getPhoneId()) {
99                     return;
100                 }
101             }
102 
103             if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
104                 mImsServiceReady = true;
105                 updateImsPhone();
106             } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
107                 mImsServiceReady = false;
108                 updateImsPhone();
109             }
110         }
111     };
112 
113     // Key used to read and write the saved network selection numeric value
114     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
115     // Key used to read and write the saved network selection operator name
116     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
117 
118 
119     // Key used to read/write "disable data connection on boot" pref (used for testing)
120     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
121 
122     /* Event Constants */
123     protected static final int EVENT_RADIO_AVAILABLE             = 1;
124     /** Supplementary Service Notification received. */
125     protected static final int EVENT_SSN                         = 2;
126     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
127     protected static final int EVENT_MMI_DONE                    = 4;
128     protected static final int EVENT_RADIO_ON                    = 5;
129     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
130     protected static final int EVENT_USSD                        = 7;
131     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
132     protected static final int EVENT_GET_IMEI_DONE               = 9;
133     protected static final int EVENT_GET_IMEISV_DONE             = 10;
134     protected static final int EVENT_GET_SIM_STATUS_DONE         = 11;
135     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
136     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
137     protected static final int EVENT_CALL_RING                   = 14;
138     protected static final int EVENT_CALL_RING_CONTINUE          = 15;
139 
140     // Used to intercept the carrier selection calls so that
141     // we can save the values.
142     protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE    = 16;
143     protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17;
144     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
145     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
146     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
147     // Events for CDMA support
148     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
149     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
150     protected static final int EVENT_NV_READY                       = 23;
151     protected static final int EVENT_SET_ENHANCED_VP                = 24;
152     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
153     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
154     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
155     // other
156     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
157     protected static final int EVENT_ICC_RECORD_EVENTS              = 29;
158     protected static final int EVENT_ICC_CHANGED                    = 30;
159     // Single Radio Voice Call Continuity
160     protected static final int EVENT_SRVCC_STATE_CHANGED            = 31;
161     protected static final int EVENT_INITIATE_SILENT_REDIAL         = 32;
162     protected static final int EVENT_RADIO_NOT_AVAILABLE            = 33;
163     protected static final int EVENT_UNSOL_OEM_HOOK_RAW             = 34;
164     protected static final int EVENT_GET_RADIO_CAPABILITY           = 35;
165     protected static final int EVENT_SS                             = 36;
166     protected static final int EVENT_LAST                           = EVENT_SS;
167 
168     // For shared prefs.
169     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
170     private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_";
171     private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_";
172     private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_";
173 
174     // Key used to read/write current CLIR setting
175     public static final String CLIR_KEY = "clir_key";
176 
177     // Key used for storing voice mail count
178     public static final String VM_COUNT = "vm_count_key";
179     // Key used to read/write the ID for storing the voice mail
180     public static final String VM_ID = "vm_id_key";
181 
182     // Key used to read/write "disable DNS server check" pref (used for testing)
183     public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
184 
185     /**
186      * Small container class used to hold information relevant to
187      * the carrier selection process. operatorNumeric can be ""
188      * if we are looking for automatic selection. operatorAlphaLong is the
189      * corresponding operator name.
190      */
191     protected static class NetworkSelectMessage {
192         public Message message;
193         public String operatorNumeric;
194         public String operatorAlphaLong;
195     }
196 
197     /* Instance Variables */
198     public CommandsInterface mCi;
199     private int mVmCount = 0;
200     boolean mDnsCheckDisabled;
201     public DcTrackerBase mDcTracker;
202     boolean mDoesRilSendMultipleCallRing;
203     int mCallRingContinueToken;
204     int mCallRingDelay;
205     public boolean mIsTheCurrentActivePhone = true;
206     boolean mIsVoiceCapable = true;
207     protected UiccController mUiccController = null;
208     public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
209     public SmsStorageMonitor mSmsStorageMonitor;
210     public SmsUsageMonitor mSmsUsageMonitor;
211     protected AtomicReference<UiccCardApplication> mUiccApplication =
212             new AtomicReference<UiccCardApplication>();
213 
214     private TelephonyTester mTelephonyTester;
215     private final String mName;
216     private final String mActionDetached;
217     private final String mActionAttached;
218 
219     protected int mPhoneId;
220 
221     private final Object mImsLock = new Object();
222     private boolean mImsServiceReady = false;
223     protected ImsPhone mImsPhone = null;
224 
225     protected int mRadioAccessFamily = RadioAccessFamily.RAF_UNKNOWN;
226 
227     @Override
getPhoneName()228     public String getPhoneName() {
229         return mName;
230     }
231 
getNai()232     public String getNai(){
233          return null;
234     }
235 
236     /**
237      * Return the ActionDetached string. When this action is received by components
238      * they are to simulate detaching from the network.
239      *
240      * @return com.android.internal.telephony.{mName}.action_detached
241      *          {mName} is GSM, CDMA ...
242      */
getActionDetached()243     public String getActionDetached() {
244         return mActionDetached;
245     }
246 
247     /**
248      * Return the ActionAttached string. When this action is received by components
249      * they are to simulate attaching to the network.
250      *
251      * @return com.android.internal.telephony.{mName}.action_detached
252      *          {mName} is GSM, CDMA ...
253      */
getActionAttached()254     public String getActionAttached() {
255         return mActionAttached;
256     }
257 
258     /**
259      * Set a system property, unless we're in unit test mode
260      */
261     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
setSystemProperty(String property, String value)262     public void setSystemProperty(String property, String value) {
263         if(getUnitTestMode()) {
264             return;
265         }
266         SystemProperties.set(property, value);
267     }
268 
269     /**
270      * Set a system property, unless we're in unit test mode
271      */
272     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
getSystemProperty(String property, String defValue)273     public String getSystemProperty(String property, String defValue) {
274         if(getUnitTestMode()) {
275             return null;
276         }
277         return SystemProperties.get(property, defValue);
278     }
279 
280 
281     protected final RegistrantList mPreciseCallStateRegistrants
282             = new RegistrantList();
283 
284     protected final RegistrantList mHandoverRegistrants
285              = new RegistrantList();
286 
287     protected final RegistrantList mNewRingingConnectionRegistrants
288             = new RegistrantList();
289 
290     protected final RegistrantList mIncomingRingRegistrants
291             = new RegistrantList();
292 
293     protected final RegistrantList mDisconnectRegistrants
294             = new RegistrantList();
295 
296     protected final RegistrantList mServiceStateRegistrants
297             = new RegistrantList();
298 
299     protected final RegistrantList mMmiCompleteRegistrants
300             = new RegistrantList();
301 
302     protected final RegistrantList mMmiRegistrants
303             = new RegistrantList();
304 
305     protected final RegistrantList mUnknownConnectionRegistrants
306             = new RegistrantList();
307 
308     protected final RegistrantList mSuppServiceFailedRegistrants
309             = new RegistrantList();
310 
311     protected final RegistrantList mRadioOffOrNotAvailableRegistrants
312             = new RegistrantList();
313 
314     protected final RegistrantList mSimRecordsLoadedRegistrants
315             = new RegistrantList();
316 
317     protected Looper mLooper; /* to insure registrants are in correct thread*/
318 
319     protected final Context mContext;
320 
321     /**
322      * PhoneNotifier is an abstraction for all system-wide
323      * state change notification. DefaultPhoneNotifier is
324      * used here unless running we're inside a unit test.
325      */
326     protected PhoneNotifier mNotifier;
327 
328     protected SimulatedRadioControl mSimulatedRadioControl;
329 
330     boolean mUnitTestMode;
331 
332     /**
333      * Constructs a PhoneBase in normal (non-unit test) mode.
334      *
335      * @param notifier An instance of DefaultPhoneNotifier,
336      * @param context Context object from hosting application
337      * unless unit testing.
338      * @param ci the CommandsInterface
339      */
PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci)340     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci) {
341         this(name, notifier, context, ci, false);
342     }
343 
344     /**
345      * Constructs a PhoneBase in normal (non-unit test) mode.
346      *
347      * @param notifier An instance of DefaultPhoneNotifier,
348      * @param context Context object from hosting application
349      * unless unit testing.
350      * @param ci is CommandsInterface
351      * @param unitTestMode when true, prevents notifications
352      * of state change events
353      */
PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode)354     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
355             boolean unitTestMode) {
356         this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX);
357     }
358 
359     /**
360      * Constructs a PhoneBase in normal (non-unit test) mode.
361      *
362      * @param notifier An instance of DefaultPhoneNotifier,
363      * @param context Context object from hosting application
364      * unless unit testing.
365      * @param ci is CommandsInterface
366      * @param unitTestMode when true, prevents notifications
367      * of state change events
368      * @param subscription is current phone subscription
369      */
PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode, int phoneId)370     protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
371             boolean unitTestMode, int phoneId) {
372         mPhoneId = phoneId;
373         mName = name;
374         mNotifier = notifier;
375         mContext = context;
376         mLooper = Looper.myLooper();
377         mCi = ci;
378         mActionDetached = this.getClass().getPackage().getName() + ".action_detached";
379         mActionAttached = this.getClass().getPackage().getName() + ".action_attached";
380 
381         if (Build.IS_DEBUGGABLE) {
382             mTelephonyTester = new TelephonyTester(this);
383         }
384 
385         setUnitTestMode(unitTestMode);
386 
387         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
388         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
389         mCi.setOnCallRing(this, EVENT_CALL_RING, null);
390 
391         /* "Voice capable" means that this device supports circuit-switched
392         * (i.e. voice) phone calls over the telephony network, and is allowed
393         * to display the in-call UI while a cellular voice call is active.
394         * This will be false on "data only" devices which can't make voice
395         * calls and don't support any in-call UI.
396         */
397         mIsVoiceCapable = mContext.getResources().getBoolean(
398                 com.android.internal.R.bool.config_voice_capable);
399 
400         /**
401          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
402          *  to be generated locally. Ideally all ring tones should be loops
403          * and this wouldn't be necessary. But to minimize changes to upper
404          * layers it is requested that it be generated by lower layers.
405          *
406          * By default old phones won't have the property set but do generate
407          * the RIL_UNSOL_CALL_RING so the default if there is no property is
408          * true.
409          */
410         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
411                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
412         Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
413 
414         mCallRingDelay = SystemProperties.getInt(
415                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
416         Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
417 
418         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) return;
419 
420         setPropertiesByCarrier();
421 
422         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
423         mSmsStorageMonitor = new SmsStorageMonitor(this);
424         mSmsUsageMonitor = new SmsUsageMonitor(context);
425         mUiccController = UiccController.getInstance();
426         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
427 
428         // Monitor IMS service
429         IntentFilter filter = new IntentFilter();
430         filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
431         filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
432         mContext.registerReceiver(mImsIntentReceiver, filter);
433 
434         mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
435         mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null);
436     }
437 
438     @Override
dispose()439     public void dispose() {
440         synchronized(PhoneProxy.lockForRadioTechnologyChange) {
441             mContext.unregisterReceiver(mImsIntentReceiver);
442             mCi.unSetOnCallRing(this);
443             // Must cleanup all connectionS and needs to use sendMessage!
444             mDcTracker.cleanUpAllConnections(null);
445             mIsTheCurrentActivePhone = false;
446             // Dispose the SMS usage and storage monitors
447             mSmsStorageMonitor.dispose();
448             mSmsUsageMonitor.dispose();
449             mUiccController.unregisterForIccChanged(this);
450             mCi.unregisterForSrvccStateChanged(this);
451             mCi.unSetOnUnsolOemHookRaw(this);
452 
453             if (mTelephonyTester != null) {
454                 mTelephonyTester.dispose();
455             }
456 
457             ImsPhone imsPhone = mImsPhone;
458             if (imsPhone != null) {
459                 imsPhone.unregisterForSilentRedial(this);
460                 imsPhone.dispose();
461             }
462         }
463     }
464 
465     @Override
removeReferences()466     public void removeReferences() {
467         mSmsStorageMonitor = null;
468         mSmsUsageMonitor = null;
469         mIccRecords.set(null);
470         mUiccApplication.set(null);
471         mDcTracker = null;
472         mUiccController = null;
473 
474         ImsPhone imsPhone = mImsPhone;
475         if (imsPhone != null) {
476             imsPhone.removeReferences();
477             mImsPhone = null;
478         }
479     }
480 
481     /**
482      * When overridden the derived class needs to call
483      * super.handleMessage(msg) so this method has a
484      * a chance to process the message.
485      *
486      * @param msg
487      */
488     @Override
handleMessage(Message msg)489     public void handleMessage(Message msg) {
490         AsyncResult ar;
491 
492         // messages to be handled whether or not the phone is being destroyed
493         // should only include messages which are being re-directed and do not use
494         // resources of the phone being destroyed
495         // Note: make sure to add code in GSMPhone/CDMAPhone to re-direct here before
496         // they check if phone destroyed.
497         switch (msg.what) {
498             // handle the select network completion callbacks.
499             case EVENT_SET_NETWORK_MANUAL_COMPLETE:
500             case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
501                 handleSetSelectNetwork((AsyncResult) msg.obj);
502                 return;
503         }
504 
505         if (!mIsTheCurrentActivePhone) {
506             Rlog.e(LOG_TAG, "Received message " + msg +
507                     "[" + msg.what + "] while being destroyed. Ignoring.");
508             return;
509         }
510         switch(msg.what) {
511             case EVENT_CALL_RING:
512                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
513                 ar = (AsyncResult)msg.obj;
514                 if (ar.exception == null) {
515                     PhoneConstants.State state = getState();
516                     if ((!mDoesRilSendMultipleCallRing)
517                             && ((state == PhoneConstants.State.RINGING) ||
518                                     (state == PhoneConstants.State.IDLE))) {
519                         mCallRingContinueToken += 1;
520                         sendIncomingCallRingNotification(mCallRingContinueToken);
521                     } else {
522                         notifyIncomingRing();
523                     }
524                 }
525                 break;
526 
527             case EVENT_CALL_RING_CONTINUE:
528                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState());
529                 if (getState() == PhoneConstants.State.RINGING) {
530                     sendIncomingCallRingNotification(msg.arg1);
531                 }
532                 break;
533 
534             case EVENT_ICC_CHANGED:
535                 onUpdateIccAvailability();
536                 break;
537 
538             case EVENT_INITIATE_SILENT_REDIAL:
539                 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
540                 ar = (AsyncResult) msg.obj;
541                 if ((ar.exception == null) && (ar.result != null)) {
542                     String dialString = (String) ar.result;
543                     if (TextUtils.isEmpty(dialString)) return;
544                     try {
545                         dialInternal(dialString, null, VideoProfile.VideoState.AUDIO_ONLY);
546                     } catch (CallStateException e) {
547                         Rlog.e(LOG_TAG, "silent redial failed: " + e);
548                     }
549                 }
550                 break;
551 
552             case EVENT_SRVCC_STATE_CHANGED:
553                 ar = (AsyncResult)msg.obj;
554                 if (ar.exception == null) {
555                     handleSrvccStateChanged((int[]) ar.result);
556                 } else {
557                     Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception);
558                 }
559                 break;
560 
561             case EVENT_UNSOL_OEM_HOOK_RAW:
562                 ar = (AsyncResult)msg.obj;
563                 if (ar.exception == null) {
564                     byte[] data = (byte[])ar.result;
565                     Rlog.d(LOG_TAG, "EVENT_UNSOL_OEM_HOOK_RAW data="
566                             + IccUtils.bytesToHexString(data));
567                     mNotifier.notifyOemHookRawEventForSubscriber(getSubId(), data);
568                 } else {
569                     Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception);
570                 }
571                 break;
572 
573             case EVENT_GET_RADIO_CAPABILITY:
574                 ar = (AsyncResult) msg.obj;
575                 RadioCapability rc = (RadioCapability) ar.result;
576                 if (ar.exception != null) {
577                     Rlog.d(LOG_TAG, "get phone radio capability fail,"
578                             + "no need to change mRadioAccessFamily");
579                 } else {
580                     mRadioAccessFamily = rc.getRadioAccessFamily();
581                 }
582                 Rlog.d(LOG_TAG, "EVENT_GET_RADIO_CAPABILITY :"
583                         + "phone RAF : " + mRadioAccessFamily);
584                 break;
585 
586             default:
587                 throw new RuntimeException("unexpected event not handled");
588         }
589     }
590 
handleSrvccStateChanged(int[] ret)591     private void handleSrvccStateChanged(int[] ret) {
592         Rlog.d(LOG_TAG, "handleSrvccStateChanged");
593 
594         ArrayList<Connection> conn = null;
595         ImsPhone imsPhone = mImsPhone;
596         Call.SrvccState srvccState = Call.SrvccState.NONE;
597         if (ret != null && ret.length != 0) {
598             int state = ret[0];
599             switch(state) {
600                 case VoLteServiceState.HANDOVER_STARTED:
601                     srvccState = Call.SrvccState.STARTED;
602                     if (imsPhone != null) {
603                         conn = imsPhone.getHandoverConnection();
604                         migrateFrom(imsPhone);
605                     } else {
606                         Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null");
607                     }
608                     break;
609                 case VoLteServiceState.HANDOVER_COMPLETED:
610                     srvccState = Call.SrvccState.COMPLETED;
611                     if (imsPhone != null) {
612                         imsPhone.notifySrvccState(srvccState);
613                     } else {
614                         Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null");
615                     }
616                     break;
617                 case VoLteServiceState.HANDOVER_FAILED:
618                 case VoLteServiceState.HANDOVER_CANCELED:
619                     srvccState = Call.SrvccState.FAILED;
620                     break;
621 
622                 default:
623                     //ignore invalid state
624                     return;
625             }
626 
627             getCallTracker().notifySrvccState(srvccState, conn);
628 
629             VoLteServiceState lteState = new VoLteServiceState(state);
630             notifyVoLteServiceStateChanged(lteState);
631         }
632     }
633 
634     // Inherited documentation suffices.
635     @Override
getContext()636     public Context getContext() {
637         return mContext;
638     }
639 
640     // Will be called when icc changed
onUpdateIccAvailability()641     protected abstract void onUpdateIccAvailability();
642 
643     /**
644      * Disables the DNS check (i.e., allows "0.0.0.0").
645      * Useful for lab testing environment.
646      * @param b true disables the check, false enables.
647      */
648     @Override
disableDnsCheck(boolean b)649     public void disableDnsCheck(boolean b) {
650         mDnsCheckDisabled = b;
651         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
652         SharedPreferences.Editor editor = sp.edit();
653         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
654         editor.apply();
655     }
656 
657     /**
658      * Returns true if the DNS check is currently disabled.
659      */
660     @Override
isDnsCheckDisabled()661     public boolean isDnsCheckDisabled() {
662         return mDnsCheckDisabled;
663     }
664 
665     // Inherited documentation suffices.
666     @Override
registerForPreciseCallStateChanged(Handler h, int what, Object obj)667     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
668         checkCorrectThread(h);
669 
670         mPreciseCallStateRegistrants.addUnique(h, what, obj);
671     }
672 
673     // Inherited documentation suffices.
674     @Override
unregisterForPreciseCallStateChanged(Handler h)675     public void unregisterForPreciseCallStateChanged(Handler h) {
676         mPreciseCallStateRegistrants.remove(h);
677     }
678 
679     /**
680      * Subclasses of Phone probably want to replace this with a
681      * version scoped to their packages
682      */
notifyPreciseCallStateChangedP()683     protected void notifyPreciseCallStateChangedP() {
684         AsyncResult ar = new AsyncResult(null, this, null);
685         mPreciseCallStateRegistrants.notifyRegistrants(ar);
686 
687         mNotifier.notifyPreciseCallState(this);
688     }
689 
690     @Override
registerForHandoverStateChanged(Handler h, int what, Object obj)691     public void registerForHandoverStateChanged(Handler h, int what, Object obj) {
692         checkCorrectThread(h);
693         mHandoverRegistrants.addUnique(h, what, obj);
694     }
695 
696     @Override
unregisterForHandoverStateChanged(Handler h)697     public void unregisterForHandoverStateChanged(Handler h) {
698         mHandoverRegistrants.remove(h);
699     }
700 
701     /**
702      * Subclasses of Phone probably want to replace this with a
703      * version scoped to their packages
704      */
notifyHandoverStateChanged(Connection cn)705     public void notifyHandoverStateChanged(Connection cn) {
706        AsyncResult ar = new AsyncResult(null, cn, null);
707        mHandoverRegistrants.notifyRegistrants(ar);
708     }
709 
migrateFrom(PhoneBase from)710     public void migrateFrom(PhoneBase from) {
711         migrate(mHandoverRegistrants, from.mHandoverRegistrants);
712         migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
713         migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
714         migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
715         migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
716         migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
717         migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
718         migrate(mMmiRegistrants, from.mMmiRegistrants);
719         migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
720         migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
721     }
722 
migrate(RegistrantList to, RegistrantList from)723     public void migrate(RegistrantList to, RegistrantList from) {
724         from.removeCleared();
725         for (int i = 0, n = from.size(); i < n; i++) {
726             to.add((Registrant) from.get(i));
727         }
728     }
729 
730     // Inherited documentation suffices.
731     @Override
registerForUnknownConnection(Handler h, int what, Object obj)732     public void registerForUnknownConnection(Handler h, int what, Object obj) {
733         checkCorrectThread(h);
734 
735         mUnknownConnectionRegistrants.addUnique(h, what, obj);
736     }
737 
738     // Inherited documentation suffices.
739     @Override
unregisterForUnknownConnection(Handler h)740     public void unregisterForUnknownConnection(Handler h) {
741         mUnknownConnectionRegistrants.remove(h);
742     }
743 
744     // Inherited documentation suffices.
745     @Override
registerForNewRingingConnection( Handler h, int what, Object obj)746     public void registerForNewRingingConnection(
747             Handler h, int what, Object obj) {
748         checkCorrectThread(h);
749 
750         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
751     }
752 
753     // Inherited documentation suffices.
754     @Override
unregisterForNewRingingConnection(Handler h)755     public void unregisterForNewRingingConnection(Handler h) {
756         mNewRingingConnectionRegistrants.remove(h);
757     }
758 
759     // Inherited documentation suffices.
760     @Override
registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)761     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
762         mCi.registerForInCallVoicePrivacyOn(h, what, obj);
763     }
764 
765     // Inherited documentation suffices.
766     @Override
unregisterForInCallVoicePrivacyOn(Handler h)767     public void unregisterForInCallVoicePrivacyOn(Handler h){
768         mCi.unregisterForInCallVoicePrivacyOn(h);
769     }
770 
771     // Inherited documentation suffices.
772     @Override
registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)773     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
774         mCi.registerForInCallVoicePrivacyOff(h, what, obj);
775     }
776 
777     // Inherited documentation suffices.
778     @Override
unregisterForInCallVoicePrivacyOff(Handler h)779     public void unregisterForInCallVoicePrivacyOff(Handler h){
780         mCi.unregisterForInCallVoicePrivacyOff(h);
781     }
782 
783     // Inherited documentation suffices.
784     @Override
registerForIncomingRing( Handler h, int what, Object obj)785     public void registerForIncomingRing(
786             Handler h, int what, Object obj) {
787         checkCorrectThread(h);
788 
789         mIncomingRingRegistrants.addUnique(h, what, obj);
790     }
791 
792     // Inherited documentation suffices.
793     @Override
unregisterForIncomingRing(Handler h)794     public void unregisterForIncomingRing(Handler h) {
795         mIncomingRingRegistrants.remove(h);
796     }
797 
798     // Inherited documentation suffices.
799     @Override
registerForDisconnect(Handler h, int what, Object obj)800     public void registerForDisconnect(Handler h, int what, Object obj) {
801         checkCorrectThread(h);
802 
803         mDisconnectRegistrants.addUnique(h, what, obj);
804     }
805 
806     // Inherited documentation suffices.
807     @Override
unregisterForDisconnect(Handler h)808     public void unregisterForDisconnect(Handler h) {
809         mDisconnectRegistrants.remove(h);
810     }
811 
812     // Inherited documentation suffices.
813     @Override
registerForSuppServiceFailed(Handler h, int what, Object obj)814     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
815         checkCorrectThread(h);
816 
817         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
818     }
819 
820     // Inherited documentation suffices.
821     @Override
unregisterForSuppServiceFailed(Handler h)822     public void unregisterForSuppServiceFailed(Handler h) {
823         mSuppServiceFailedRegistrants.remove(h);
824     }
825 
826     // Inherited documentation suffices.
827     @Override
registerForMmiInitiate(Handler h, int what, Object obj)828     public void registerForMmiInitiate(Handler h, int what, Object obj) {
829         checkCorrectThread(h);
830 
831         mMmiRegistrants.addUnique(h, what, obj);
832     }
833 
834     // Inherited documentation suffices.
835     @Override
unregisterForMmiInitiate(Handler h)836     public void unregisterForMmiInitiate(Handler h) {
837         mMmiRegistrants.remove(h);
838     }
839 
840     // Inherited documentation suffices.
841     @Override
registerForMmiComplete(Handler h, int what, Object obj)842     public void registerForMmiComplete(Handler h, int what, Object obj) {
843         checkCorrectThread(h);
844 
845         mMmiCompleteRegistrants.addUnique(h, what, obj);
846     }
847 
848     // Inherited documentation suffices.
849     @Override
unregisterForMmiComplete(Handler h)850     public void unregisterForMmiComplete(Handler h) {
851         checkCorrectThread(h);
852 
853         mMmiCompleteRegistrants.remove(h);
854     }
855 
registerForSimRecordsLoaded(Handler h, int what, Object obj)856     public void registerForSimRecordsLoaded(Handler h, int what, Object obj) {
857         logUnexpectedCdmaMethodCall("registerForSimRecordsLoaded");
858     }
859 
unregisterForSimRecordsLoaded(Handler h)860     public void unregisterForSimRecordsLoaded(Handler h) {
861         logUnexpectedCdmaMethodCall("unregisterForSimRecordsLoaded");
862     }
863 
864     @Override
registerForTtyModeReceived(Handler h, int what, Object obj)865     public void registerForTtyModeReceived(Handler h, int what, Object obj) {
866     }
867 
868     @Override
unregisterForTtyModeReceived(Handler h)869     public void unregisterForTtyModeReceived(Handler h) {
870     }
871 
872     @Override
setNetworkSelectionModeAutomatic(Message response)873     public void setNetworkSelectionModeAutomatic(Message response) {
874         // wrap the response message in our own message along with
875         // an empty string (to indicate automatic selection) for the
876         // operator's id.
877         NetworkSelectMessage nsm = new NetworkSelectMessage();
878         nsm.message = response;
879         nsm.operatorNumeric = "";
880         nsm.operatorAlphaLong = "";
881 
882         Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
883         mCi.setNetworkSelectionModeAutomatic(msg);
884 
885         updateSavedNetworkOperator(nsm);
886     }
887 
888     @Override
getNetworkSelectionMode(Message message)889     public void getNetworkSelectionMode(Message message) {
890         mCi.getNetworkSelectionMode(message);
891     }
892 
893     @Override
selectNetworkManually(OperatorInfo network, Message response)894     public void selectNetworkManually(OperatorInfo network, Message response) {
895         // wrap the response message in our own message along with
896         // the operator's id.
897         NetworkSelectMessage nsm = new NetworkSelectMessage();
898         nsm.message = response;
899         nsm.operatorNumeric = network.getOperatorNumeric();
900         nsm.operatorAlphaLong = network.getOperatorAlphaLong();
901 
902         Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
903         mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
904 
905         updateSavedNetworkOperator(nsm);
906     }
907 
updateSavedNetworkOperator(NetworkSelectMessage nsm)908     private void updateSavedNetworkOperator(NetworkSelectMessage nsm) {
909         int subId = getSubId();
910         if (SubscriptionManager.isValidSubscriptionId(subId)) {
911             // open the shared preferences editor, and write the value.
912             // nsm.operatorNumeric is "" if we're in automatic.selection.
913             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
914             SharedPreferences.Editor editor = sp.edit();
915             editor.putString(NETWORK_SELECTION_KEY + subId, nsm.operatorNumeric);
916             editor.putString(NETWORK_SELECTION_NAME_KEY + subId, nsm.operatorAlphaLong);
917 
918             // commit and log the result.
919             if (!editor.commit()) {
920                 Rlog.e(LOG_TAG, "failed to commit network selection preference");
921             }
922         } else {
923             Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " +
924                     subId);
925         }
926     }
927 
928     /**
929      * Used to track the settings upon completion of the network change.
930      */
handleSetSelectNetwork(AsyncResult ar)931     private void handleSetSelectNetwork(AsyncResult ar) {
932         // look for our wrapper within the asyncresult, skip the rest if it
933         // is null.
934         if (!(ar.userObj instanceof NetworkSelectMessage)) {
935             Rlog.e(LOG_TAG, "unexpected result from user object.");
936             return;
937         }
938 
939         NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
940 
941         // found the object, now we send off the message we had originally
942         // attached to the request.
943         if (nsm.message != null) {
944             AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
945             nsm.message.sendToTarget();
946         }
947     }
948 
949     /**
950      * Method to retrieve the saved operator id from the Shared Preferences
951      */
getSavedNetworkSelection()952     private String getSavedNetworkSelection() {
953         // open the shared preferences and search with our key.
954         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
955         return sp.getString(NETWORK_SELECTION_KEY + getSubId(), "");
956     }
957 
958     /**
959      * Method to restore the previously saved operator id, or reset to
960      * automatic selection, all depending upon the value in the shared
961      * preferences.
962      */
restoreSavedNetworkSelection(Message response)963     public void restoreSavedNetworkSelection(Message response) {
964         // retrieve the operator id
965         String networkSelection = getSavedNetworkSelection();
966 
967         // set to auto if the id is empty, otherwise select the network.
968         if (TextUtils.isEmpty(networkSelection)) {
969             mCi.setNetworkSelectionModeAutomatic(response);
970         } else {
971             mCi.setNetworkSelectionModeManual(networkSelection, response);
972         }
973     }
974 
975     // Inherited documentation suffices.
976     @Override
setUnitTestMode(boolean f)977     public void setUnitTestMode(boolean f) {
978         mUnitTestMode = f;
979     }
980 
981     // Inherited documentation suffices.
982     @Override
getUnitTestMode()983     public boolean getUnitTestMode() {
984         return mUnitTestMode;
985     }
986 
987     /**
988      * To be invoked when a voice call Connection disconnects.
989      *
990      * Subclasses of Phone probably want to replace this with a
991      * version scoped to their packages
992      */
notifyDisconnectP(Connection cn)993     protected void notifyDisconnectP(Connection cn) {
994         AsyncResult ar = new AsyncResult(null, cn, null);
995         mDisconnectRegistrants.notifyRegistrants(ar);
996     }
997 
998     // Inherited documentation suffices.
999     @Override
registerForServiceStateChanged( Handler h, int what, Object obj)1000     public void registerForServiceStateChanged(
1001             Handler h, int what, Object obj) {
1002         checkCorrectThread(h);
1003 
1004         mServiceStateRegistrants.add(h, what, obj);
1005     }
1006 
1007     // Inherited documentation suffices.
1008     @Override
unregisterForServiceStateChanged(Handler h)1009     public void unregisterForServiceStateChanged(Handler h) {
1010         mServiceStateRegistrants.remove(h);
1011     }
1012 
1013     // Inherited documentation suffices.
1014     @Override
registerForRingbackTone(Handler h, int what, Object obj)1015     public void registerForRingbackTone(Handler h, int what, Object obj) {
1016         mCi.registerForRingbackTone(h, what, obj);
1017     }
1018 
1019     // Inherited documentation suffices.
1020     @Override
unregisterForRingbackTone(Handler h)1021     public void unregisterForRingbackTone(Handler h) {
1022         mCi.unregisterForRingbackTone(h);
1023     }
1024 
1025     // Inherited documentation suffices.
1026     @Override
registerForOnHoldTone(Handler h, int what, Object obj)1027     public void registerForOnHoldTone(Handler h, int what, Object obj) {
1028     }
1029 
1030     // Inherited documentation suffices.
1031     @Override
unregisterForOnHoldTone(Handler h)1032     public void unregisterForOnHoldTone(Handler h) {
1033     }
1034 
1035     // Inherited documentation suffices.
1036     @Override
registerForResendIncallMute(Handler h, int what, Object obj)1037     public void registerForResendIncallMute(Handler h, int what, Object obj) {
1038         mCi.registerForResendIncallMute(h, what, obj);
1039     }
1040 
1041     // Inherited documentation suffices.
1042     @Override
unregisterForResendIncallMute(Handler h)1043     public void unregisterForResendIncallMute(Handler h) {
1044         mCi.unregisterForResendIncallMute(h);
1045     }
1046 
1047     @Override
setEchoSuppressionEnabled()1048     public void setEchoSuppressionEnabled() {
1049         // no need for regular phone
1050     }
1051 
1052     /**
1053      * Subclasses of Phone probably want to replace this with a
1054      * version scoped to their packages
1055      */
notifyServiceStateChangedP(ServiceState ss)1056     protected void notifyServiceStateChangedP(ServiceState ss) {
1057         AsyncResult ar = new AsyncResult(null, ss, null);
1058         mServiceStateRegistrants.notifyRegistrants(ar);
1059 
1060         mNotifier.notifyServiceState(this);
1061     }
1062 
1063     // Inherited documentation suffices.
1064     @Override
getSimulatedRadioControl()1065     public SimulatedRadioControl getSimulatedRadioControl() {
1066         return mSimulatedRadioControl;
1067     }
1068 
1069     /**
1070      * Verifies the current thread is the same as the thread originally
1071      * used in the initialization of this instance. Throws RuntimeException
1072      * if not.
1073      *
1074      * @exception RuntimeException if the current thread is not
1075      * the thread that originally obtained this PhoneBase instance.
1076      */
checkCorrectThread(Handler h)1077     private void checkCorrectThread(Handler h) {
1078         if (h.getLooper() != mLooper) {
1079             throw new RuntimeException(
1080                     "com.android.internal.telephony.Phone must be used from within one thread");
1081         }
1082     }
1083 
1084     /**
1085      * Set the properties by matching the carrier string in
1086      * a string-array resource
1087      */
setPropertiesByCarrier()1088     private void setPropertiesByCarrier() {
1089         String carrier = SystemProperties.get("ro.carrier");
1090 
1091         if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
1092             return;
1093         }
1094 
1095         CharSequence[] carrierLocales = mContext.
1096                 getResources().getTextArray(R.array.carrier_properties);
1097 
1098         for (int i = 0; i < carrierLocales.length; i+=3) {
1099             String c = carrierLocales[i].toString();
1100             if (carrier.equals(c)) {
1101                 final Locale l = Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-'));
1102                 final String country = l.getCountry();
1103                 MccTable.setSystemLocale(mContext, l.getLanguage(), country);
1104 
1105                 if (!country.isEmpty()) {
1106                     try {
1107                         Settings.Global.getInt(mContext.getContentResolver(),
1108                                 Settings.Global.WIFI_COUNTRY_CODE);
1109                     } catch (Settings.SettingNotFoundException e) {
1110                         // note this is not persisting
1111                         WifiManager wM = (WifiManager)
1112                                 mContext.getSystemService(Context.WIFI_SERVICE);
1113                         wM.setCountryCode(country, false);
1114                     }
1115                 }
1116                 return;
1117             }
1118         }
1119     }
1120 
1121     /**
1122      * Get state
1123      */
1124     @Override
getState()1125     public abstract PhoneConstants.State getState();
1126 
1127     /**
1128      * Retrieves the IccFileHandler of the Phone instance
1129      */
getIccFileHandler()1130     public IccFileHandler getIccFileHandler(){
1131         UiccCardApplication uiccApplication = mUiccApplication.get();
1132         IccFileHandler fh;
1133 
1134         if (uiccApplication == null) {
1135             Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null");
1136             fh = null;
1137         } else {
1138             fh = uiccApplication.getIccFileHandler();
1139         }
1140 
1141         Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh);
1142         return fh;
1143     }
1144 
1145     /*
1146      * Retrieves the Handler of the Phone instance
1147      */
getHandler()1148     public Handler getHandler() {
1149         return this;
1150     }
1151 
1152     @Override
updatePhoneObject(int voiceRadioTech)1153     public void updatePhoneObject(int voiceRadioTech) {
1154         // Only the PhoneProxy can update the phone object.
1155         PhoneFactory.getDefaultPhone().updatePhoneObject(voiceRadioTech);
1156     }
1157 
1158     /**
1159     * Retrieves the ServiceStateTracker of the phone instance.
1160     */
getServiceStateTracker()1161     public ServiceStateTracker getServiceStateTracker() {
1162         return null;
1163     }
1164 
1165     /**
1166     * Get call tracker
1167     */
getCallTracker()1168     public CallTracker getCallTracker() {
1169         return null;
1170     }
1171 
getCurrentUiccAppType()1172     public AppType getCurrentUiccAppType() {
1173         UiccCardApplication currentApp = mUiccApplication.get();
1174         if (currentApp != null) {
1175             return currentApp.getType();
1176         }
1177         return AppType.APPTYPE_UNKNOWN;
1178     }
1179 
1180     @Override
getIccCard()1181     public IccCard getIccCard() {
1182         return null;
1183         //throw new Exception("getIccCard Shouldn't be called from PhoneBase");
1184     }
1185 
1186     @Override
getIccSerialNumber()1187     public String getIccSerialNumber() {
1188         IccRecords r = mIccRecords.get();
1189         return (r != null) ? r.getIccId() : null;
1190     }
1191 
1192     @Override
getIccRecordsLoaded()1193     public boolean getIccRecordsLoaded() {
1194         IccRecords r = mIccRecords.get();
1195         return (r != null) ? r.getRecordsLoaded() : false;
1196     }
1197 
1198     /**
1199      * @return all available cell information or null if none.
1200      */
1201     @Override
getAllCellInfo()1202     public List<CellInfo> getAllCellInfo() {
1203         List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo();
1204         return privatizeCellInfoList(cellInfoList);
1205     }
1206 
1207     /**
1208      * Clear CDMA base station lat/long values if location setting is disabled.
1209      * @param cellInfoList the original cell info list from the RIL
1210      * @return the original list with CDMA lat/long cleared if necessary
1211      */
privatizeCellInfoList(List<CellInfo> cellInfoList)1212     private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) {
1213         int mode = Settings.Secure.getInt(getContext().getContentResolver(),
1214                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
1215         if (mode == Settings.Secure.LOCATION_MODE_OFF) {
1216             ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size());
1217             // clear lat/lon values for location privacy
1218             for (CellInfo c : cellInfoList) {
1219                 if (c instanceof CellInfoCdma) {
1220                     CellInfoCdma cellInfoCdma = (CellInfoCdma) c;
1221                     CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity();
1222                     CellIdentityCdma maskedCellIdentity = new CellIdentityCdma(
1223                             cellIdentity.getNetworkId(),
1224                             cellIdentity.getSystemId(),
1225                             cellIdentity.getBasestationId(),
1226                             Integer.MAX_VALUE, Integer.MAX_VALUE);
1227                     CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma);
1228                     privateCellInfoCdma.setCellIdentity(maskedCellIdentity);
1229                     privateCellInfoList.add(privateCellInfoCdma);
1230                 } else {
1231                     privateCellInfoList.add(c);
1232                 }
1233             }
1234             cellInfoList = privateCellInfoList;
1235         }
1236         return cellInfoList;
1237     }
1238 
1239     /**
1240      * {@inheritDoc}
1241      */
1242     @Override
setCellInfoListRate(int rateInMillis)1243     public void setCellInfoListRate(int rateInMillis) {
1244         mCi.setCellInfoListRate(rateInMillis, null);
1245     }
1246 
1247     @Override
1248     /** @return true if there are messages waiting, false otherwise. */
getMessageWaitingIndicator()1249     public boolean getMessageWaitingIndicator() {
1250         return mVmCount != 0;
1251     }
1252 
1253     @Override
getCallForwardingIndicator()1254     public boolean getCallForwardingIndicator() {
1255         IccRecords r = mIccRecords.get();
1256         return (r != null) ? r.getVoiceCallForwardingFlag() : false;
1257     }
1258 
1259     /**
1260      *  Query the status of the CDMA roaming preference
1261      */
1262     @Override
queryCdmaRoamingPreference(Message response)1263     public void queryCdmaRoamingPreference(Message response) {
1264         mCi.queryCdmaRoamingPreference(response);
1265     }
1266 
1267     /**
1268      * Get the signal strength
1269      */
1270     @Override
getSignalStrength()1271     public SignalStrength getSignalStrength() {
1272         ServiceStateTracker sst = getServiceStateTracker();
1273         if (sst == null) {
1274             return new SignalStrength();
1275         } else {
1276             return sst.getSignalStrength();
1277         }
1278     }
1279 
1280     /**
1281      *  Set the status of the CDMA roaming preference
1282      */
1283     @Override
setCdmaRoamingPreference(int cdmaRoamingType, Message response)1284     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
1285         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
1286     }
1287 
1288     /**
1289      *  Set the status of the CDMA subscription mode
1290      */
1291     @Override
setCdmaSubscription(int cdmaSubscriptionType, Message response)1292     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
1293         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
1294     }
1295 
1296     /**
1297      *  Set the preferred Network Type: Global, CDMA only or GSM/UMTS only
1298      */
1299     @Override
setPreferredNetworkType(int networkType, Message response)1300     public void setPreferredNetworkType(int networkType, Message response) {
1301         mCi.setPreferredNetworkType(networkType, response);
1302     }
1303 
1304     @Override
getPreferredNetworkType(Message response)1305     public void getPreferredNetworkType(Message response) {
1306         mCi.getPreferredNetworkType(response);
1307     }
1308 
1309     @Override
getSmscAddress(Message result)1310     public void getSmscAddress(Message result) {
1311         mCi.getSmscAddress(result);
1312     }
1313 
1314     @Override
setSmscAddress(String address, Message result)1315     public void setSmscAddress(String address, Message result) {
1316         mCi.setSmscAddress(address, result);
1317     }
1318 
1319     @Override
setTTYMode(int ttyMode, Message onComplete)1320     public void setTTYMode(int ttyMode, Message onComplete) {
1321         mCi.setTTYMode(ttyMode, onComplete);
1322     }
1323 
1324     @Override
setUiTTYMode(int uiTtyMode, Message onComplete)1325     public void setUiTTYMode(int uiTtyMode, Message onComplete) {
1326         Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call");
1327     }
1328 
1329     @Override
queryTTYMode(Message onComplete)1330     public void queryTTYMode(Message onComplete) {
1331         mCi.queryTTYMode(onComplete);
1332     }
1333 
1334     @Override
enableEnhancedVoicePrivacy(boolean enable, Message onComplete)1335     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
1336         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1337         logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy");
1338     }
1339 
1340     @Override
getEnhancedVoicePrivacy(Message onComplete)1341     public void getEnhancedVoicePrivacy(Message onComplete) {
1342         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1343         logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy");
1344     }
1345 
1346     @Override
setBandMode(int bandMode, Message response)1347     public void setBandMode(int bandMode, Message response) {
1348         mCi.setBandMode(bandMode, response);
1349     }
1350 
1351     @Override
queryAvailableBandMode(Message response)1352     public void queryAvailableBandMode(Message response) {
1353         mCi.queryAvailableBandMode(response);
1354     }
1355 
1356     @Override
invokeOemRilRequestRaw(byte[] data, Message response)1357     public void invokeOemRilRequestRaw(byte[] data, Message response) {
1358         mCi.invokeOemRilRequestRaw(data, response);
1359     }
1360 
1361     @Override
invokeOemRilRequestStrings(String[] strings, Message response)1362     public void invokeOemRilRequestStrings(String[] strings, Message response) {
1363         mCi.invokeOemRilRequestStrings(strings, response);
1364     }
1365 
1366     @Override
nvReadItem(int itemID, Message response)1367     public void nvReadItem(int itemID, Message response) {
1368         mCi.nvReadItem(itemID, response);
1369     }
1370 
1371     @Override
nvWriteItem(int itemID, String itemValue, Message response)1372     public void nvWriteItem(int itemID, String itemValue, Message response) {
1373         mCi.nvWriteItem(itemID, itemValue, response);
1374     }
1375 
1376     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)1377     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
1378         mCi.nvWriteCdmaPrl(preferredRoamingList, response);
1379     }
1380 
1381     @Override
nvResetConfig(int resetType, Message response)1382     public void nvResetConfig(int resetType, Message response) {
1383         mCi.nvResetConfig(resetType, response);
1384     }
1385 
1386     @Override
notifyDataActivity()1387     public void notifyDataActivity() {
1388         mNotifier.notifyDataActivity(this);
1389     }
1390 
notifyMessageWaitingIndicator()1391     public void notifyMessageWaitingIndicator() {
1392         // Do not notify voice mail waiting if device doesn't support voice
1393         if (!mIsVoiceCapable)
1394             return;
1395 
1396         // This function is added to send the notification to DefaultPhoneNotifier.
1397         mNotifier.notifyMessageWaitingChanged(this);
1398     }
1399 
notifyDataConnection(String reason, String apnType, PhoneConstants.DataState state)1400     public void notifyDataConnection(String reason, String apnType,
1401             PhoneConstants.DataState state) {
1402         mNotifier.notifyDataConnection(this, reason, apnType, state);
1403     }
1404 
notifyDataConnection(String reason, String apnType)1405     public void notifyDataConnection(String reason, String apnType) {
1406         mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
1407     }
1408 
notifyDataConnection(String reason)1409     public void notifyDataConnection(String reason) {
1410         String types[] = getActiveApnTypes();
1411         for (String apnType : types) {
1412             mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
1413         }
1414     }
1415 
notifyOtaspChanged(int otaspMode)1416     public void notifyOtaspChanged(int otaspMode) {
1417         mNotifier.notifyOtaspChanged(this, otaspMode);
1418     }
1419 
notifySignalStrength()1420     public void notifySignalStrength() {
1421         mNotifier.notifySignalStrength(this);
1422     }
1423 
notifyCellInfo(List<CellInfo> cellInfo)1424     public void notifyCellInfo(List<CellInfo> cellInfo) {
1425         mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo));
1426     }
1427 
notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo)1428     public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) {
1429         mNotifier.notifyDataConnectionRealTimeInfo(this, dcRtInfo);
1430     }
1431 
notifyVoLteServiceStateChanged(VoLteServiceState lteState)1432     public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) {
1433         mNotifier.notifyVoLteServiceStateChanged(this, lteState);
1434     }
1435 
1436     /**
1437      * @return true if a mobile originating emergency call is active
1438      */
isInEmergencyCall()1439     public boolean isInEmergencyCall() {
1440         return false;
1441     }
1442 
1443     /**
1444      * @return true if we are in the emergency call back mode. This is a period where
1445      * the phone should be using as little power as possible and be ready to receive an
1446      * incoming call from the emergency operator.
1447      */
isInEcm()1448     public boolean isInEcm() {
1449         return false;
1450     }
1451 
1452     @Override
getPhoneType()1453     public abstract int getPhoneType();
1454 
1455     /** @hide */
1456     /** @return number of voicemails */
1457     @Override
getVoiceMessageCount()1458     public int getVoiceMessageCount(){
1459         return mVmCount;
1460     }
1461 
1462     /** sets the voice mail count of the phone and notifies listeners. */
setVoiceMessageCount(int countWaiting)1463     public void setVoiceMessageCount(int countWaiting) {
1464         mVmCount = countWaiting;
1465         // notify listeners of voice mail
1466         notifyMessageWaitingIndicator();
1467     }
1468 
1469     /** gets the voice mail count from preferences */
getStoredVoiceMessageCount()1470     protected int getStoredVoiceMessageCount() {
1471         int countVoiceMessages = 0;
1472         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1473         String subscriberId = sp.getString(VM_ID, null);
1474         String currentSubscriberId = getSubscriberId();
1475 
1476         Rlog.d(LOG_TAG, "Voicemail count retrieval for subscriberId = " + subscriberId +
1477                 " current subscriberId = " + currentSubscriberId);
1478 
1479         if ((subscriberId != null) && (currentSubscriberId != null)
1480                 && (currentSubscriberId.equals(subscriberId))) {
1481             // get voice mail count from preferences
1482             countVoiceMessages = sp.getInt(VM_COUNT, 0);
1483             Rlog.d(LOG_TAG, "Voice Mail Count from preference = " + countVoiceMessages);
1484         }
1485         return countVoiceMessages;
1486     }
1487 
1488     /**
1489      * Returns the CDMA ERI icon index to display
1490      */
1491     @Override
getCdmaEriIconIndex()1492     public int getCdmaEriIconIndex() {
1493         logUnexpectedCdmaMethodCall("getCdmaEriIconIndex");
1494         return -1;
1495     }
1496 
1497     /**
1498      * Returns the CDMA ERI icon mode,
1499      * 0 - ON
1500      * 1 - FLASHING
1501      */
1502     @Override
getCdmaEriIconMode()1503     public int getCdmaEriIconMode() {
1504         logUnexpectedCdmaMethodCall("getCdmaEriIconMode");
1505         return -1;
1506     }
1507 
1508     /**
1509      * Returns the CDMA ERI text,
1510      */
1511     @Override
getCdmaEriText()1512     public String getCdmaEriText() {
1513         logUnexpectedCdmaMethodCall("getCdmaEriText");
1514         return "GSM nw, no ERI";
1515     }
1516 
1517     @Override
getCdmaMin()1518     public String getCdmaMin() {
1519         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1520         logUnexpectedCdmaMethodCall("getCdmaMin");
1521         return null;
1522     }
1523 
1524     @Override
isMinInfoReady()1525     public boolean isMinInfoReady() {
1526         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1527         logUnexpectedCdmaMethodCall("isMinInfoReady");
1528         return false;
1529     }
1530 
1531     @Override
getCdmaPrlVersion()1532     public String getCdmaPrlVersion(){
1533         //  This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1534         logUnexpectedCdmaMethodCall("getCdmaPrlVersion");
1535         return null;
1536     }
1537 
1538     @Override
sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)1539     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
1540         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1541         logUnexpectedCdmaMethodCall("sendBurstDtmf");
1542     }
1543 
1544     @Override
exitEmergencyCallbackMode()1545     public void exitEmergencyCallbackMode() {
1546         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1547         logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode");
1548     }
1549 
1550     @Override
registerForCdmaOtaStatusChange(Handler h, int what, Object obj)1551     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
1552         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1553         logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange");
1554     }
1555 
1556     @Override
unregisterForCdmaOtaStatusChange(Handler h)1557     public void unregisterForCdmaOtaStatusChange(Handler h) {
1558         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1559         logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange");
1560     }
1561 
1562     @Override
registerForSubscriptionInfoReady(Handler h, int what, Object obj)1563     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
1564         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1565         logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady");
1566     }
1567 
1568     @Override
unregisterForSubscriptionInfoReady(Handler h)1569     public void unregisterForSubscriptionInfoReady(Handler h) {
1570         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1571         logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady");
1572     }
1573 
1574     /**
1575      * Returns true if OTA Service Provisioning needs to be performed.
1576      * If not overridden return false.
1577      */
1578     @Override
needsOtaServiceProvisioning()1579     public boolean needsOtaServiceProvisioning() {
1580         return false;
1581     }
1582 
1583     /**
1584      * Return true if number is an OTASP number.
1585      * If not overridden return false.
1586      */
1587     @Override
isOtaSpNumber(String dialStr)1588     public  boolean isOtaSpNumber(String dialStr) {
1589         return false;
1590     }
1591 
1592     @Override
registerForCallWaiting(Handler h, int what, Object obj)1593     public void registerForCallWaiting(Handler h, int what, Object obj){
1594         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1595         logUnexpectedCdmaMethodCall("registerForCallWaiting");
1596     }
1597 
1598     @Override
unregisterForCallWaiting(Handler h)1599     public void unregisterForCallWaiting(Handler h){
1600         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1601         logUnexpectedCdmaMethodCall("unregisterForCallWaiting");
1602     }
1603 
1604     @Override
registerForEcmTimerReset(Handler h, int what, Object obj)1605     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
1606         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1607         logUnexpectedCdmaMethodCall("registerForEcmTimerReset");
1608     }
1609 
1610     @Override
unregisterForEcmTimerReset(Handler h)1611     public void unregisterForEcmTimerReset(Handler h) {
1612         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1613         logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset");
1614     }
1615 
1616     @Override
registerForSignalInfo(Handler h, int what, Object obj)1617     public void registerForSignalInfo(Handler h, int what, Object obj) {
1618         mCi.registerForSignalInfo(h, what, obj);
1619     }
1620 
1621     @Override
unregisterForSignalInfo(Handler h)1622     public void unregisterForSignalInfo(Handler h) {
1623         mCi.unregisterForSignalInfo(h);
1624     }
1625 
1626     @Override
registerForDisplayInfo(Handler h, int what, Object obj)1627     public void registerForDisplayInfo(Handler h, int what, Object obj) {
1628         mCi.registerForDisplayInfo(h, what, obj);
1629     }
1630 
1631      @Override
unregisterForDisplayInfo(Handler h)1632     public void unregisterForDisplayInfo(Handler h) {
1633          mCi.unregisterForDisplayInfo(h);
1634      }
1635 
1636     @Override
registerForNumberInfo(Handler h, int what, Object obj)1637     public void registerForNumberInfo(Handler h, int what, Object obj) {
1638         mCi.registerForNumberInfo(h, what, obj);
1639     }
1640 
1641     @Override
unregisterForNumberInfo(Handler h)1642     public void unregisterForNumberInfo(Handler h) {
1643         mCi.unregisterForNumberInfo(h);
1644     }
1645 
1646     @Override
registerForRedirectedNumberInfo(Handler h, int what, Object obj)1647     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
1648         mCi.registerForRedirectedNumberInfo(h, what, obj);
1649     }
1650 
1651     @Override
unregisterForRedirectedNumberInfo(Handler h)1652     public void unregisterForRedirectedNumberInfo(Handler h) {
1653         mCi.unregisterForRedirectedNumberInfo(h);
1654     }
1655 
1656     @Override
registerForLineControlInfo(Handler h, int what, Object obj)1657     public void registerForLineControlInfo(Handler h, int what, Object obj) {
1658         mCi.registerForLineControlInfo( h, what, obj);
1659     }
1660 
1661     @Override
unregisterForLineControlInfo(Handler h)1662     public void unregisterForLineControlInfo(Handler h) {
1663         mCi.unregisterForLineControlInfo(h);
1664     }
1665 
1666     @Override
registerFoT53ClirlInfo(Handler h, int what, Object obj)1667     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
1668         mCi.registerFoT53ClirlInfo(h, what, obj);
1669     }
1670 
1671     @Override
unregisterForT53ClirInfo(Handler h)1672     public void unregisterForT53ClirInfo(Handler h) {
1673         mCi.unregisterForT53ClirInfo(h);
1674     }
1675 
1676     @Override
registerForT53AudioControlInfo(Handler h, int what, Object obj)1677     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
1678         mCi.registerForT53AudioControlInfo( h, what, obj);
1679     }
1680 
1681     @Override
unregisterForT53AudioControlInfo(Handler h)1682     public void unregisterForT53AudioControlInfo(Handler h) {
1683         mCi.unregisterForT53AudioControlInfo(h);
1684     }
1685 
1686      @Override
setOnEcbModeExitResponse(Handler h, int what, Object obj)1687     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
1688          // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1689          logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse");
1690      }
1691 
1692      @Override
unsetOnEcbModeExitResponse(Handler h)1693     public void unsetOnEcbModeExitResponse(Handler h){
1694         // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
1695          logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse");
1696      }
1697 
1698     @Override
registerForRadioOffOrNotAvailable(Handler h, int what, Object obj)1699     public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) {
1700         mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj);
1701     }
1702 
1703     @Override
unregisterForRadioOffOrNotAvailable(Handler h)1704     public void unregisterForRadioOffOrNotAvailable(Handler h) {
1705         mRadioOffOrNotAvailableRegistrants.remove(h);
1706     }
1707 
1708     @Override
getActiveApnTypes()1709     public String[] getActiveApnTypes() {
1710         return mDcTracker.getActiveApnTypes();
1711     }
1712 
1713     @Override
hasMatchedTetherApnSetting()1714     public boolean hasMatchedTetherApnSetting() {
1715         return mDcTracker.hasMatchedTetherApnSetting();
1716     }
1717 
1718     @Override
getActiveApnHost(String apnType)1719     public String getActiveApnHost(String apnType) {
1720         return mDcTracker.getActiveApnString(apnType);
1721     }
1722 
1723     @Override
getLinkProperties(String apnType)1724     public LinkProperties getLinkProperties(String apnType) {
1725         return mDcTracker.getLinkProperties(apnType);
1726     }
1727 
1728     @Override
getNetworkCapabilities(String apnType)1729     public NetworkCapabilities getNetworkCapabilities(String apnType) {
1730         return mDcTracker.getNetworkCapabilities(apnType);
1731     }
1732 
1733     @Override
isDataConnectivityPossible()1734     public boolean isDataConnectivityPossible() {
1735         return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT);
1736     }
1737 
1738     @Override
isDataConnectivityPossible(String apnType)1739     public boolean isDataConnectivityPossible(String apnType) {
1740         return ((mDcTracker != null) &&
1741                 (mDcTracker.isDataPossible(apnType)));
1742     }
1743 
1744     /**
1745      * Notify registrants of a new ringing Connection.
1746      * Subclasses of Phone probably want to replace this with a
1747      * version scoped to their packages
1748      */
notifyNewRingingConnectionP(Connection cn)1749     public void notifyNewRingingConnectionP(Connection cn) {
1750         if (!mIsVoiceCapable)
1751             return;
1752         AsyncResult ar = new AsyncResult(null, cn, null);
1753         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
1754     }
1755 
1756     /**
1757      * Notify registrants of a RING event.
1758      */
notifyIncomingRing()1759     private void notifyIncomingRing() {
1760         if (!mIsVoiceCapable)
1761             return;
1762         AsyncResult ar = new AsyncResult(null, this, null);
1763         mIncomingRingRegistrants.notifyRegistrants(ar);
1764     }
1765 
1766     /**
1767      * Send the incoming call Ring notification if conditions are right.
1768      */
sendIncomingCallRingNotification(int token)1769     private void sendIncomingCallRingNotification(int token) {
1770         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
1771                 (token == mCallRingContinueToken)) {
1772             Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
1773             notifyIncomingRing();
1774             sendMessageDelayed(
1775                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
1776         } else {
1777             Rlog.d(LOG_TAG, "Ignoring ring notification request,"
1778                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
1779                     + " token=" + token
1780                     + " mCallRingContinueToken=" + mCallRingContinueToken
1781                     + " mIsVoiceCapable=" + mIsVoiceCapable);
1782         }
1783     }
1784 
1785     @Override
isCspPlmnEnabled()1786     public boolean isCspPlmnEnabled() {
1787         // This function should be overridden by the class GSMPhone.
1788         // Not implemented in CDMAPhone.
1789         logUnexpectedGsmMethodCall("isCspPlmnEnabled");
1790         return false;
1791     }
1792 
1793     @Override
getIsimRecords()1794     public IsimRecords getIsimRecords() {
1795         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
1796         return null;
1797     }
1798 
1799     @Override
getMsisdn()1800     public String getMsisdn() {
1801         logUnexpectedGsmMethodCall("getMsisdn");
1802         return null;
1803     }
1804 
1805     /**
1806      * Common error logger method for unexpected calls to CDMA-only methods.
1807      */
logUnexpectedCdmaMethodCall(String name)1808     private static void logUnexpectedCdmaMethodCall(String name)
1809     {
1810         Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
1811                 "called, CDMAPhone inactive.");
1812     }
1813 
1814     @Override
getDataConnectionState()1815     public PhoneConstants.DataState getDataConnectionState() {
1816         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
1817     }
1818 
1819     /**
1820      * Common error logger method for unexpected calls to GSM/WCDMA-only methods.
1821      */
logUnexpectedGsmMethodCall(String name)1822     private static void logUnexpectedGsmMethodCall(String name) {
1823         Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " +
1824                 "called, GSMPhone inactive.");
1825     }
1826 
1827     // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone.
notifyCallForwardingIndicator()1828     public void notifyCallForwardingIndicator() {
1829         // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone.
1830         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
1831     }
1832 
notifyDataConnectionFailed(String reason, String apnType)1833     public void notifyDataConnectionFailed(String reason, String apnType) {
1834         mNotifier.notifyDataConnectionFailed(this, reason, apnType);
1835     }
1836 
notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause)1837     public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
1838             String failCause) {
1839         mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause);
1840     }
1841 
1842     /**
1843      * {@inheritDoc}
1844      */
1845     @Override
getLteOnCdmaMode()1846     public int getLteOnCdmaMode() {
1847         return mCi.getLteOnCdmaMode();
1848     }
1849 
setVoiceMessageWaiting(int line, int countWaiting)1850     public void setVoiceMessageWaiting(int line, int countWaiting) {
1851         // This function should be overridden by class GSMPhone and CDMAPhone.
1852         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone.");
1853     }
1854 
1855     /**
1856      * Gets the USIM service table from the UICC, if present and available.
1857      * @return an interface to the UsimServiceTable record, or null if not available
1858      */
1859     @Override
getUsimServiceTable()1860     public UsimServiceTable getUsimServiceTable() {
1861         IccRecords r = mIccRecords.get();
1862         return (r != null) ? r.getUsimServiceTable() : null;
1863     }
1864 
1865     /**
1866      * Gets the Uicc card corresponding to this phone.
1867      * @return the UiccCard object corresponding to the phone ID.
1868      */
1869     @Override
getUiccCard()1870     public UiccCard getUiccCard() {
1871         return mUiccController.getUiccCard(mPhoneId);
1872     }
1873 
1874     /**
1875      * Get P-CSCF address from PCO after data connection is established or modified.
1876      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
1877      */
1878     @Override
getPcscfAddress(String apnType)1879     public String[] getPcscfAddress(String apnType) {
1880         return mDcTracker.getPcscfAddress(apnType);
1881     }
1882 
1883     /**
1884      * Set IMS registration state
1885      */
1886     @Override
setImsRegistrationState(boolean registered)1887     public void setImsRegistrationState(boolean registered) {
1888         mDcTracker.setImsRegistrationState(registered);
1889     }
1890 
1891     /**
1892      * Return an instance of a IMS phone
1893      */
1894     @Override
getImsPhone()1895     public Phone getImsPhone() {
1896         return mImsPhone;
1897     }
1898 
1899     @Override
relinquishOwnershipOfImsPhone()1900     public ImsPhone relinquishOwnershipOfImsPhone() {
1901         synchronized (mImsLock) {
1902             if (mImsPhone == null)
1903                 return null;
1904 
1905             ImsPhone imsPhone = mImsPhone;
1906             mImsPhone = null;
1907 
1908             CallManager.getInstance().unregisterPhone(imsPhone);
1909             imsPhone.unregisterForSilentRedial(this);
1910 
1911             return imsPhone;
1912         }
1913     }
1914 
1915     @Override
acquireOwnershipOfImsPhone(ImsPhone imsPhone)1916     public void acquireOwnershipOfImsPhone(ImsPhone imsPhone) {
1917         synchronized (mImsLock) {
1918             if (imsPhone == null)
1919                 return;
1920 
1921             if (mImsPhone != null) {
1922                 Rlog.e(LOG_TAG, "acquireOwnershipOfImsPhone: non-null mImsPhone." +
1923                         " Shouldn't happen - but disposing");
1924                 mImsPhone.dispose();
1925                 // Potential GC issue if someone keeps a reference to ImsPhone.
1926                 // However: this change will make sure that such a reference does
1927                 // not access functions through NULL pointer.
1928                 //mImsPhone.removeReferences();
1929             }
1930 
1931             mImsPhone = imsPhone;
1932 
1933             mImsServiceReady = true;
1934             mImsPhone.updateParentPhone(this);
1935             CallManager.getInstance().registerPhone(mImsPhone);
1936             mImsPhone.registerForSilentRedial(
1937                     this, EVENT_INITIATE_SILENT_REDIAL, null);
1938         }
1939     }
1940 
updateImsPhone()1941     protected void updateImsPhone() {
1942         synchronized (mImsLock) {
1943             Rlog.d(LOG_TAG, "updateImsPhone"
1944                     + " mImsServiceReady=" + mImsServiceReady);
1945 
1946             if (mImsServiceReady && (mImsPhone == null)) {
1947                 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
1948                 CallManager.getInstance().registerPhone(mImsPhone);
1949                 mImsPhone.registerForSilentRedial(
1950                         this, EVENT_INITIATE_SILENT_REDIAL, null);
1951             } else if (!mImsServiceReady && (mImsPhone != null)) {
1952                 CallManager.getInstance().unregisterPhone(mImsPhone);
1953                 mImsPhone.unregisterForSilentRedial(this);
1954 
1955                 mImsPhone.dispose();
1956                 // Potential GC issue if someone keeps a reference to ImsPhone.
1957                 // However: this change will make sure that such a reference does
1958                 // not access functions through NULL pointer.
1959                 //mImsPhone.removeReferences();
1960                 mImsPhone = null;
1961             }
1962         }
1963     }
1964 
1965     /**
1966      * Dials a number.
1967      *
1968      * @param dialString The number to dial.
1969      * @param uusInfo The UUSInfo.
1970      * @param videoState The video state for the call.
1971      * @return The Connection.
1972      * @throws CallStateException
1973      */
dialInternal(String dialString, UUSInfo uusInfo, int videoState)1974     protected Connection dialInternal(String dialString, UUSInfo uusInfo, int videoState)
1975             throws CallStateException {
1976         // dialInternal shall be overriden by GSMPhone and CDMAPhone
1977         return null;
1978     }
1979 
1980     /**
1981      * Returns the subscription id.
1982      */
getSubId()1983     public int getSubId() {
1984         return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId);
1985     }
1986 
1987     /**
1988      * Returns the phone id.
1989      */
getPhoneId()1990     public int getPhoneId() {
1991         return mPhoneId;
1992     }
1993 
1994     /**
1995      * Return the service state of mImsPhone if it is STATE_IN_SERVICE
1996      * otherwise return the current voice service state
1997      */
1998     @Override
getVoicePhoneServiceState()1999     public int getVoicePhoneServiceState() {
2000         ImsPhone imsPhone = mImsPhone;
2001         if (imsPhone != null
2002                 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
2003             return ServiceState.STATE_IN_SERVICE;
2004         }
2005         return getServiceState().getState();
2006     }
2007 
2008     @Override
setOperatorBrandOverride(String brand)2009     public boolean setOperatorBrandOverride(String brand) {
2010         return false;
2011     }
2012 
2013     @Override
setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)2014     public boolean setRoamingOverride(List<String> gsmRoamingList,
2015             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
2016             List<String> cdmaNonRoamingList) {
2017         String iccId = getIccSerialNumber();
2018         if (TextUtils.isEmpty(iccId)) {
2019             return false;
2020         }
2021 
2022         setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2023         setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2024         setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2025         setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2026 
2027         // Refresh.
2028         ServiceStateTracker tracker = getServiceStateTracker();
2029         if (tracker != null) {
2030             tracker.pollState();
2031         }
2032         return true;
2033     }
2034 
setRoamingOverrideHelper(List<String> list, String prefix, String iccId)2035     private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) {
2036         SharedPreferences.Editor spEditor =
2037                 PreferenceManager.getDefaultSharedPreferences(mContext).edit();
2038         String key = prefix + iccId;
2039         if (list == null || list.isEmpty()) {
2040             spEditor.remove(key).commit();
2041         } else {
2042             spEditor.putStringSet(key, new HashSet<String>(list)).commit();
2043         }
2044     }
2045 
isMccMncMarkedAsRoaming(String mccMnc)2046     public boolean isMccMncMarkedAsRoaming(String mccMnc) {
2047         return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
2048     }
2049 
isMccMncMarkedAsNonRoaming(String mccMnc)2050     public boolean isMccMncMarkedAsNonRoaming(String mccMnc) {
2051         return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
2052     }
2053 
isSidMarkedAsRoaming(int SID)2054     public boolean isSidMarkedAsRoaming(int SID) {
2055         return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX,
2056                 Integer.toString(SID));
2057     }
2058 
isSidMarkedAsNonRoaming(int SID)2059     public boolean isSidMarkedAsNonRoaming(int SID) {
2060         return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX,
2061                 Integer.toString(SID));
2062     }
2063 
2064     /**
2065      * Get IMS Registration Status
2066      */
2067     @Override
isImsRegistered()2068     public boolean isImsRegistered() {
2069         ImsPhone imsPhone = mImsPhone;
2070         boolean isImsRegistered = false;
2071         if (imsPhone != null) {
2072             isImsRegistered = imsPhone.isImsRegistered();
2073         } else {
2074             ServiceStateTracker sst = getServiceStateTracker();
2075             if (sst != null) {
2076                 isImsRegistered = sst.isImsRegistered();
2077             }
2078         }
2079         Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered);
2080         return isImsRegistered;
2081     }
2082 
getRoamingOverrideHelper(String prefix, String key)2083     private boolean getRoamingOverrideHelper(String prefix, String key) {
2084         String iccId = getIccSerialNumber();
2085         if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) {
2086             return false;
2087         }
2088 
2089         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2090         Set<String> value = sp.getStringSet(prefix + iccId, null);
2091         if (value == null) {
2092             return false;
2093         }
2094         return value.contains(key);
2095     }
2096 
2097     @Override
isRadioAvailable()2098     public boolean isRadioAvailable() {
2099         return mCi.getRadioState().isAvailable();
2100     }
2101 
2102     @Override
shutdownRadio()2103     public void shutdownRadio() {
2104         getServiceStateTracker().requestShutdown();
2105     }
2106 
2107     @Override
setRadioCapability(RadioCapability rc, Message response)2108     public void setRadioCapability(RadioCapability rc, Message response) {
2109         mCi.setRadioCapability(rc, response);
2110     }
2111 
2112     @Override
getRadioAccessFamily()2113     public int getRadioAccessFamily() {
2114         return mRadioAccessFamily;
2115     }
2116 
2117     @Override
getSupportedRadioAccessFamily()2118     public int getSupportedRadioAccessFamily() {
2119         return mCi.getSupportedRadioAccessFamily();
2120     }
2121 
2122     @Override
registerForRadioCapabilityChanged(Handler h, int what, Object obj)2123     public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) {
2124         mCi.registerForRadioCapabilityChanged(h, what, obj);
2125     }
2126 
2127     @Override
unregisterForRadioCapabilityChanged(Handler h)2128     public void unregisterForRadioCapabilityChanged(Handler h) {
2129         mCi.unregisterForRadioCapabilityChanged(this);
2130     }
2131 
dump(FileDescriptor fd, PrintWriter pw, String[] args)2132     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2133         pw.println("PhoneBase: subId=" + getSubId());
2134         pw.println(" mPhoneId=" + mPhoneId);
2135         pw.println(" mCi=" + mCi);
2136         pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
2137         pw.println(" mDcTracker=" + mDcTracker);
2138         pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
2139         pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
2140         pw.println(" mCallRingDelay=" + mCallRingDelay);
2141         pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone);
2142         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
2143         pw.println(" mIccRecords=" + mIccRecords.get());
2144         pw.println(" mUiccApplication=" + mUiccApplication.get());
2145         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
2146         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
2147         pw.flush();
2148         pw.println(" mLooper=" + mLooper);
2149         pw.println(" mContext=" + mContext);
2150         pw.println(" mNotifier=" + mNotifier);
2151         pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
2152         pw.println(" mUnitTestMode=" + mUnitTestMode);
2153         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
2154         pw.println(" getUnitTestMode()=" + getUnitTestMode());
2155         pw.println(" getState()=" + getState());
2156         pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
2157         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
2158         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
2159         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
2160         pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
2161         pw.flush();
2162         pw.println(" isInEcm()=" + isInEcm());
2163         pw.println(" getPhoneName()=" + getPhoneName());
2164         pw.println(" getPhoneType()=" + getPhoneType());
2165         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
2166         pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
2167         pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
2168         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
2169         pw.flush();
2170         pw.println("++++++++++++++++++++++++++++++++");
2171 
2172         try {
2173             mDcTracker.dump(fd, pw, args);
2174         } catch (Exception e) {
2175             e.printStackTrace();
2176         }
2177         pw.flush();
2178         pw.println("++++++++++++++++++++++++++++++++");
2179 
2180         try {
2181             getServiceStateTracker().dump(fd, pw, args);
2182         } catch (Exception e) {
2183             e.printStackTrace();
2184         }
2185         pw.flush();
2186         pw.println("++++++++++++++++++++++++++++++++");
2187 
2188         try {
2189             getCallTracker().dump(fd, pw, args);
2190         } catch (Exception e) {
2191             e.printStackTrace();
2192         }
2193         pw.flush();
2194         pw.println("++++++++++++++++++++++++++++++++");
2195 
2196         try {
2197             ((RIL)mCi).dump(fd, pw, args);
2198         } catch (Exception e) {
2199             e.printStackTrace();
2200         }
2201         pw.flush();
2202         pw.println("++++++++++++++++++++++++++++++++");
2203     }
2204 }
2205