CDMALTEPhone.java revision 0e4abef0d7e978d4c3dea5199f451a1c69158d03
1/* 2 * Copyright (C) 2011 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 17package com.android.internal.telephony.cdma; 18 19import android.content.ContentValues; 20import android.content.Context; 21import android.content.SharedPreferences; 22import android.database.SQLException; 23import android.net.Uri; 24import android.os.AsyncResult; 25import android.os.Message; 26import android.preference.PreferenceManager; 27import android.provider.Telephony; 28import android.telephony.Rlog; 29 30import com.android.internal.telephony.CommandsInterface; 31import com.android.internal.telephony.OperatorInfo; 32import com.android.internal.telephony.PhoneConstants; 33import com.android.internal.telephony.PhoneNotifier; 34import com.android.internal.telephony.PhoneProxy; 35import com.android.internal.telephony.SMSDispatcher; 36import com.android.internal.telephony.gsm.GsmSMSDispatcher; 37import com.android.internal.telephony.gsm.SmsMessage; 38import com.android.internal.telephony.uicc.IsimRecords; 39import com.android.internal.telephony.uicc.IsimUiccRecords; 40import com.android.internal.telephony.uicc.SIMRecords; 41import com.android.internal.telephony.uicc.UiccCardApplication; 42import com.android.internal.telephony.uicc.UiccController; 43 44import java.io.FileDescriptor; 45import java.io.PrintWriter; 46 47public class CDMALTEPhone extends CDMAPhone { 48 static final String LOG_LTE_TAG = "CDMALTEPhone"; 49 private static final boolean DBG = true; 50 51 /** Secondary SMSDispatcher for 3GPP format messages. */ 52 SMSDispatcher m3gppSMS; 53 54 /** CdmaLtePhone in addition to RuimRecords available from 55 * PhoneBase needs access to SIMRecords and IsimUiccRecords 56 */ 57 private SIMRecords mSimRecords; 58 private IsimUiccRecords mIsimUiccRecords; 59 60 /** 61 * Small container class used to hold information relevant to 62 * the carrier selection process. operatorNumeric can be "" 63 * if we are looking for automatic selection. operatorAlphaLong is the 64 * corresponding operator name. 65 */ 66 private static class NetworkSelectMessage { 67 public Message message; 68 public String operatorNumeric; 69 public String operatorAlphaLong; 70 } 71 72 // Constructors 73 public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) { 74 super(context, ci, notifier, false); 75 m3gppSMS = new GsmSMSDispatcher(this, mSmsStorageMonitor, mSmsUsageMonitor); 76 } 77 78 @Override 79 public void handleMessage (Message msg) { 80 AsyncResult ar; 81 switch (msg.what) { 82 // handle the select network completion callbacks. 83 case EVENT_SET_NETWORK_MANUAL_COMPLETE: 84 handleSetSelectNetwork((AsyncResult) msg.obj); 85 break; 86 case EVENT_NEW_ICC_SMS: 87 ar = (AsyncResult)msg.obj; 88 m3gppSMS.dispatchMessage((SmsMessage)ar.result); 89 break; 90 default: 91 super.handleMessage(msg); 92 } 93 } 94 95 @Override 96 protected void initSstIcc() { 97 mSST = new CdmaLteServiceStateTracker(this); 98 } 99 100 @Override 101 public void dispose() { 102 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 103 super.dispose(); 104 m3gppSMS.dispose(); 105 } 106 } 107 108 @Override 109 public void removeReferences() { 110 super.removeReferences(); 111 m3gppSMS = null; 112 } 113 114 @Override 115 public PhoneConstants.DataState getDataConnectionState(String apnType) { 116 PhoneConstants.DataState ret = PhoneConstants.DataState.DISCONNECTED; 117 118 if (mSST == null) { 119 // Radio Technology Change is ongoing, dispose() and 120 // removeReferences() have already been called 121 122 ret = PhoneConstants.DataState.DISCONNECTED; 123 } else if (mDataConnectionTracker.isApnTypeEnabled(apnType) == false) { 124 ret = PhoneConstants.DataState.DISCONNECTED; 125 } else { 126 switch (mDataConnectionTracker.getState(apnType)) { 127 case FAILED: 128 case IDLE: 129 ret = PhoneConstants.DataState.DISCONNECTED; 130 break; 131 132 case CONNECTED: 133 case DISCONNECTING: 134 if (mCT.mState != PhoneConstants.State.IDLE && 135 !mSST.isConcurrentVoiceAndDataAllowed()) { 136 ret = PhoneConstants.DataState.SUSPENDED; 137 } else { 138 ret = PhoneConstants.DataState.CONNECTED; 139 } 140 break; 141 142 case CONNECTING: 143 case SCANNING: 144 ret = PhoneConstants.DataState.CONNECTING; 145 break; 146 } 147 } 148 149 log("getDataConnectionState apnType=" + apnType + " ret=" + ret); 150 return ret; 151 } 152 153 @Override 154 public void 155 selectNetworkManually(OperatorInfo network, 156 Message response) { 157 // wrap the response message in our own message along with 158 // the operator's id. 159 NetworkSelectMessage nsm = new NetworkSelectMessage(); 160 nsm.message = response; 161 nsm.operatorNumeric = network.getOperatorNumeric(); 162 nsm.operatorAlphaLong = network.getOperatorAlphaLong(); 163 164 // get the message 165 Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); 166 167 mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg); 168 } 169 170 /** 171 * Used to track the settings upon completion of the network change. 172 */ 173 private void handleSetSelectNetwork(AsyncResult ar) { 174 // look for our wrapper within the asyncresult, skip the rest if it 175 // is null. 176 if (!(ar.userObj instanceof NetworkSelectMessage)) { 177 loge("unexpected result from user object."); 178 return; 179 } 180 181 NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj; 182 183 // found the object, now we send off the message we had originally 184 // attached to the request. 185 if (nsm.message != null) { 186 if (DBG) log("sending original message to recipient"); 187 AsyncResult.forMessage(nsm.message, ar.result, ar.exception); 188 nsm.message.sendToTarget(); 189 } 190 191 // open the shared preferences editor, and write the value. 192 // nsm.operatorNumeric is "" if we're in automatic.selection. 193 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 194 SharedPreferences.Editor editor = sp.edit(); 195 editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric); 196 editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong); 197 198 // commit and log the result. 199 if (! editor.commit()) { 200 loge("failed to commit network selection preference"); 201 } 202 203 } 204 205 @Override 206 public boolean updateCurrentCarrierInProvider() { 207 if (mSimRecords != null) { 208 try { 209 Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); 210 ContentValues map = new ContentValues(); 211 String operatorNumeric = mSimRecords.getOperatorNumeric(); 212 map.put(Telephony.Carriers.NUMERIC, operatorNumeric); 213 if (DBG) log("updateCurrentCarrierInProvider from UICC: numeric=" + 214 operatorNumeric); 215 mContext.getContentResolver().insert(uri, map); 216 return true; 217 } catch (SQLException e) { 218 loge("Can't store current operator ret false", e); 219 } 220 } else { 221 if (DBG) log("updateCurrentCarrierInProvider mIccRecords == null ret false"); 222 } 223 return false; 224 } 225 226 // return IMSI from USIM as subscriber ID. 227 @Override 228 public String getSubscriberId() { 229 return (mSimRecords != null) ? mSimRecords.getIMSI() : ""; 230 } 231 232 // return GID1 from USIM 233 @Override 234 public String getGroupIdLevel1() { 235 return (mSimRecords != null) ? mSimRecords.getGid1() : ""; 236 } 237 238 @Override 239 public String getImei() { 240 return mImei; 241 } 242 243 @Override 244 public String getDeviceSvn() { 245 return mImeiSv; 246 } 247 248 @Override 249 public IsimRecords getIsimRecords() { 250 return mIsimUiccRecords; 251 } 252 253 @Override 254 public String getMsisdn() { 255 return (mSimRecords != null) ? mSimRecords.getMsisdnNumber() : null; 256 } 257 258 @Override 259 public void getAvailableNetworks(Message response) { 260 mCi.getAvailableNetworks(response); 261 } 262 263 @Override 264 public void requestIsimAuthentication(String nonce, Message result) { 265 mCi.requestIsimAuthentication(nonce, result); 266 } 267 268 @Override 269 protected void onUpdateIccAvailability() { 270 if (mUiccController == null ) { 271 return; 272 } 273 274 // Update IsimRecords 275 UiccCardApplication newUiccApplication = 276 mUiccController.getUiccCardApplication(UiccController.APP_FAM_IMS); 277 IsimUiccRecords newIsimUiccRecords = null; 278 279 if (newUiccApplication != null) { 280 newIsimUiccRecords = (IsimUiccRecords)newUiccApplication.getIccRecords(); 281 } 282 mIsimUiccRecords = newIsimUiccRecords; 283 284 // Update UsimRecords 285 newUiccApplication = mUiccController.getUiccCardApplication(UiccController.APP_FAM_3GPP); 286 SIMRecords newSimRecords = null; 287 if (newUiccApplication != null) { 288 newSimRecords = (SIMRecords)newUiccApplication.getIccRecords(); 289 } 290 if (mSimRecords != newSimRecords) { 291 if (mSimRecords != null) { 292 log("Removing stale SIMRecords object."); 293 mSimRecords.unregisterForNewSms(this); 294 mSimRecords = null; 295 } 296 if (newSimRecords != null) { 297 log("New SIMRecords found"); 298 mSimRecords = newSimRecords; 299 mSimRecords.registerForNewSms(this, EVENT_NEW_ICC_SMS, null); 300 } 301 } 302 303 super.onUpdateIccAvailability(); 304 } 305 306 @Override 307 protected void log(String s) { 308 Rlog.d(LOG_LTE_TAG, s); 309 } 310 311 protected void loge(String s) { 312 Rlog.e(LOG_LTE_TAG, s); 313 } 314 315 protected void loge(String s, Throwable e) { 316 Rlog.e(LOG_LTE_TAG, s, e); 317} 318 319 @Override 320 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 321 pw.println("CDMALTEPhone extends:"); 322 super.dump(fd, pw, args); 323 pw.println(" m3gppSMS=" + m3gppSMS); 324 } 325} 326