PhoneSubInfo.java revision 2351b17aba5350004fc76707f3b3d2859ce773c8
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 */ 16package com.android.internal.telephony; 17 18import java.io.FileDescriptor; 19import java.io.PrintWriter; 20 21import android.content.Context; 22import android.content.pm.PackageManager; 23import android.os.Binder; 24import android.os.RemoteException; 25import android.telephony.PhoneNumberUtils; 26import android.telephony.Rlog; 27 28import com.android.internal.telephony.uicc.IsimRecords; 29import com.android.internal.telephony.uicc.UiccCard; 30import com.android.internal.telephony.uicc.UiccCardApplication; 31 32public class PhoneSubInfo { 33 static final String LOG_TAG = "PhoneSubInfo"; 34 private static final boolean DBG = true; 35 private static final boolean VDBG = false; // STOPSHIP if true 36 37 private Phone mPhone; 38 private Context mContext; 39 private static final String READ_PHONE_STATE = 40 android.Manifest.permission.READ_PHONE_STATE; 41 // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE 42 private static final String CALL_PRIVILEGED = 43 android.Manifest.permission.CALL_PRIVILEGED; 44 private static final String READ_PRIVILEGED_PHONE_STATE = 45 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; 46 47 public PhoneSubInfo(Phone phone) { 48 mPhone = phone; 49 mContext = phone.getContext(); 50 } 51 52 public void dispose() { 53 } 54 55 @Override 56 protected void finalize() { 57 try { 58 super.finalize(); 59 } catch (Throwable throwable) { 60 loge("Error while finalizing:", throwable); 61 } 62 if (DBG) log("PhoneSubInfo finalized"); 63 } 64 65 /** 66 * Retrieves the unique device ID, e.g., IMEI for GSM phones and MEID for CDMA phones. 67 */ 68 public String getDeviceId() { 69 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 70 return mPhone.getDeviceId(); 71 } 72 73 /** 74 * Retrieves the IMEI. 75 */ 76 public String getImei() { 77 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 78 return mPhone.getImei(); 79 } 80 81 /** 82 * Retrieves the NAI. 83 */ 84 public String getNai() { 85 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 86 return mPhone.getNai(); 87 } 88 89 /** 90 * Retrieves the software version number for the device, e.g., IMEI/SV 91 * for GSM phones. 92 */ 93 public String getDeviceSvn() { 94 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 95 return mPhone.getDeviceSvn(); 96 } 97 98 /** 99 * Retrieves the unique subscriber ID, e.g., IMSI for GSM phones. 100 */ 101 public String getSubscriberId() { 102 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 103 return mPhone.getSubscriberId(); 104 } 105 106 /** 107 * Retrieves the Group Identifier Level1 for GSM phones. 108 */ 109 public String getGroupIdLevel1() { 110 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 111 return mPhone.getGroupIdLevel1(); 112 } 113 114 /** 115 * Retrieves the serial number of the ICC, if applicable. 116 */ 117 public String getIccSerialNumber() { 118 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 119 return mPhone.getIccSerialNumber(); 120 } 121 122 /** 123 * Retrieves the phone number string for line 1. 124 */ 125 public String getLine1Number() { 126 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 127 return mPhone.getLine1Number(); 128 } 129 130 /** 131 * Retrieves the alpha identifier for line 1. 132 */ 133 public String getLine1AlphaTag() { 134 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 135 return mPhone.getLine1AlphaTag(); 136 } 137 138 /** 139 * Retrieves the MSISDN string. 140 */ 141 public String getMsisdn() { 142 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 143 return mPhone.getMsisdn(); 144 } 145 146 /** 147 * Retrieves the voice mail number. 148 */ 149 public String getVoiceMailNumber() { 150 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 151 String number = PhoneNumberUtils.extractNetworkPortion(mPhone.getVoiceMailNumber()); 152 if (VDBG) log("VM: PhoneSubInfo.getVoiceMailNUmber: " + number); 153 return number; 154 } 155 156 /** 157 * Retrieves the complete voice mail number. 158 * 159 * @hide 160 */ 161 public String getCompleteVoiceMailNumber() { 162 mContext.enforceCallingOrSelfPermission(CALL_PRIVILEGED, 163 "Requires CALL_PRIVILEGED"); 164 String number = mPhone.getVoiceMailNumber(); 165 if (VDBG) log("VM: PhoneSubInfo.getCompleteVoiceMailNUmber: " + number); 166 return number; 167 } 168 169 /** 170 * Retrieves the alpha identifier associated with the voice mail number. 171 */ 172 public String getVoiceMailAlphaTag() { 173 mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); 174 return mPhone.getVoiceMailAlphaTag(); 175 } 176 177 /** 178 * Returns the IMS private user identity (IMPI) that was loaded from the ISIM. 179 * @return the IMPI, or null if not present or not loaded 180 */ 181 public String getIsimImpi() { 182 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, 183 "Requires READ_PRIVILEGED_PHONE_STATE"); 184 IsimRecords isim = mPhone.getIsimRecords(); 185 if (isim != null) { 186 return isim.getIsimImpi(); 187 } else { 188 return null; 189 } 190 } 191 192 /** 193 * Returns the IMS home network domain name that was loaded from the ISIM. 194 * @return the IMS domain name, or null if not present or not loaded 195 */ 196 public String getIsimDomain() { 197 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, 198 "Requires READ_PRIVILEGED_PHONE_STATE"); 199 IsimRecords isim = mPhone.getIsimRecords(); 200 if (isim != null) { 201 return isim.getIsimDomain(); 202 } else { 203 return null; 204 } 205 } 206 207 /** 208 * Returns the IMS public user identities (IMPU) that were loaded from the ISIM. 209 * @return an array of IMPU strings, with one IMPU per string, or null if 210 * not present or not loaded 211 */ 212 public String[] getIsimImpu() { 213 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, 214 "Requires READ_PRIVILEGED_PHONE_STATE"); 215 IsimRecords isim = mPhone.getIsimRecords(); 216 if (isim != null) { 217 return isim.getIsimImpu(); 218 } else { 219 return null; 220 } 221 } 222 223 /** 224 * Returns the IMS Service Table (IST) that was loaded from the ISIM. 225 * @return IMS Service Table or null if not present or not loaded 226 */ 227 public String getIsimIst(){ 228 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, 229 "Requires READ_PRIVILEGED_PHONE_STATE"); 230 IsimRecords isim = mPhone.getIsimRecords(); 231 if (isim != null) { 232 return isim.getIsimIst(); 233 } else { 234 return null; 235 } 236 } 237 238 /** 239 * Returns the IMS Proxy Call Session Control Function(PCSCF) that were loaded from the ISIM. 240 * @return an array of PCSCF strings with one PCSCF per string, or null if 241 * not present or not loaded 242 */ 243 public String[] getIsimPcscf() { 244 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, 245 "Requires READ_PRIVILEGED_PHONE_STATE"); 246 IsimRecords isim = mPhone.getIsimRecords(); 247 if (isim != null) { 248 return isim.getIsimPcscf(); 249 } else { 250 return null; 251 } 252 } 253 254 /** 255 * Returns the response of ISIM Authetification through RIL. 256 * Returns null if the Authentification hasn't been successed or isn't present iphonesubinfo. 257 * @return the response of ISIM Authetification, or null if not available 258 */ 259 public String getIsimChallengeResponse(String nonce){ 260 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, 261 "Requires READ_PRIVILEGED_PHONE_STATE"); 262 IsimRecords isim = mPhone.getIsimRecords(); 263 if (isim != null) { 264 return isim.getIsimChallengeResponse(nonce); 265 } else { 266 return null; 267 } 268 } 269 270 /** 271 * Returns the response of the SIM application on the UICC to authentication 272 * challenge/response algorithm. The data string and challenge response are 273 * Base64 encoded Strings. 274 * Can support EAP-SIM, EAP-AKA with results encoded per 3GPP TS 31.102. 275 * 276 * @param appType ICC application family (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) 277 * @param data authentication challenge data 278 * @return challenge response 279 */ 280 public String getIccSimChallengeResponse(long subId, int appType, String data) { 281 // FIXME: use subId!! 282 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, 283 "Requires READ_PRIVILEGED_PHONE_STATE"); 284 285 UiccCard uiccCard = mPhone.getUiccCard(); 286 if (uiccCard == null) { 287 Rlog.e(LOG_TAG, "getIccSimChallengeResponse() UiccCard is null"); 288 return null; 289 } 290 291 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); 292 if (uiccApp == null) { 293 Rlog.e(LOG_TAG, "getIccSimChallengeResponse() no app with specified type -- " + 294 appType); 295 return null; 296 } else { 297 Rlog.e(LOG_TAG, "getIccSimChallengeResponse() found app " + uiccApp.getAid() 298 + "specified type -- " + appType); 299 } 300 301 int authContext = uiccApp.getAuthContext(); 302 303 if (data.length() < 32) { 304 /* must use EAP_SIM context */ 305 Rlog.e(LOG_TAG, "data is too small to use EAP_AKA, using EAP_SIM instead"); 306 authContext = UiccCardApplication.AUTH_CONTEXT_EAP_SIM; 307 } 308 309 if(authContext == UiccCardApplication.AUTH_CONTEXT_UNDEFINED) { 310 Rlog.e(LOG_TAG, "getIccSimChallengeResponse() authContext undefined for app type " + 311 appType); 312 return null; 313 } 314 315 return uiccApp.getIccRecords().getIccSimChallengeResponse(authContext, data); 316 } 317 318 private void log(String s) { 319 Rlog.d(LOG_TAG, s); 320 } 321 322 private void loge(String s, Throwable e) { 323 Rlog.e(LOG_TAG, s, e); 324 } 325 326 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 327 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 328 != PackageManager.PERMISSION_GRANTED) { 329 pw.println("Permission Denial: can't dump PhoneSubInfo from from pid=" 330 + Binder.getCallingPid() 331 + ", uid=" + Binder.getCallingUid()); 332 return; 333 } 334 335 pw.println("Phone Subscriber Info:"); 336 pw.println(" Phone Type = " + mPhone.getPhoneName()); 337 pw.println(" Device ID = " + mPhone.getDeviceId()); 338 } 339} 340