1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. 4 * Not a Contribution. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package com.android.internal.telephony; 20 21 import android.annotation.Nullable; 22 import android.app.ActivityThread; 23 import android.app.PendingIntent; 24 import android.content.Context; 25 import android.net.Uri; 26 import android.os.Binder; 27 import android.os.RemoteException; 28 import android.os.ServiceManager; 29 import android.provider.Telephony.Sms.Intents; 30 import android.telephony.Rlog; 31 import android.telephony.SmsManager; 32 import android.telephony.SubscriptionInfo; 33 import android.telephony.SubscriptionManager; 34 import android.telephony.TelephonyManager; 35 36 import java.util.List; 37 38 /** 39 * UiccSmsController to provide an inter-process communication to 40 * access Sms in Icc. 41 */ 42 public class UiccSmsController extends ISms.Stub { 43 static final String LOG_TAG = "RIL_UiccSmsController"; 44 45 protected Phone[] mPhone; 46 UiccSmsController(Phone[] phone)47 protected UiccSmsController(Phone[] phone){ 48 mPhone = phone; 49 50 if (ServiceManager.getService("isms") == null) { 51 ServiceManager.addService("isms", this); 52 } 53 } 54 55 @Override 56 public boolean updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index, int status, byte[] pdu)57 updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index, int status, 58 byte[] pdu) throws android.os.RemoteException { 59 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 60 if (iccSmsIntMgr != null) { 61 return iccSmsIntMgr.updateMessageOnIccEf(callingPackage, index, status, pdu); 62 } else { 63 Rlog.e(LOG_TAG,"updateMessageOnIccEfForSubscriber iccSmsIntMgr is null" + 64 " for Subscription: " + subId); 65 return false; 66 } 67 } 68 69 @Override copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status, byte[] pdu, byte[] smsc)70 public boolean copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status, 71 byte[] pdu, byte[] smsc) throws android.os.RemoteException { 72 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 73 if (iccSmsIntMgr != null) { 74 return iccSmsIntMgr.copyMessageToIccEf(callingPackage, status, pdu, smsc); 75 } else { 76 Rlog.e(LOG_TAG,"copyMessageToIccEfForSubscriber iccSmsIntMgr is null" + 77 " for Subscription: " + subId); 78 return false; 79 } 80 } 81 82 @Override getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage)83 public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage) 84 throws android.os.RemoteException { 85 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 86 if (iccSmsIntMgr != null) { 87 return iccSmsIntMgr.getAllMessagesFromIccEf(callingPackage); 88 } else { 89 Rlog.e(LOG_TAG,"getAllMessagesFromIccEfForSubscriber iccSmsIntMgr is" + 90 " null for Subscription: " + subId); 91 return null; 92 } 93 } 94 95 @Override sendDataForSubscriber(int subId, String callingPackage, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)96 public void sendDataForSubscriber(int subId, String callingPackage, String destAddr, 97 String scAddr, int destPort, byte[] data, PendingIntent sentIntent, 98 PendingIntent deliveryIntent) { 99 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 100 if (iccSmsIntMgr != null) { 101 iccSmsIntMgr.sendData(callingPackage, destAddr, scAddr, destPort, data, 102 sentIntent, deliveryIntent); 103 } else { 104 Rlog.e(LOG_TAG,"sendDataForSubscriber iccSmsIntMgr is null for" + 105 " Subscription: " + subId); 106 // TODO: Use a more specific error code to replace RESULT_ERROR_GENERIC_FAILURE. 107 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 108 } 109 } 110 sendDataForSubscriberWithSelfPermissions(int subId, String callingPackage, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)111 public void sendDataForSubscriberWithSelfPermissions(int subId, String callingPackage, 112 String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, 113 PendingIntent deliveryIntent) { 114 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 115 if (iccSmsIntMgr != null) { 116 iccSmsIntMgr.sendDataWithSelfPermissions(callingPackage, destAddr, scAddr, destPort, data, 117 sentIntent, deliveryIntent); 118 } else { 119 Rlog.e(LOG_TAG,"sendText iccSmsIntMgr is null for" + 120 " Subscription: " + subId); 121 } 122 } 123 sendText(String callingPackage, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)124 public void sendText(String callingPackage, String destAddr, String scAddr, 125 String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { 126 sendTextForSubscriber(getPreferredSmsSubscription(), callingPackage, destAddr, scAddr, 127 text, sentIntent, deliveryIntent, true /* persistMessageForNonDefaultSmsApp*/); 128 } 129 130 @Override sendTextForSubscriber(int subId, String callingPackage, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp)131 public void sendTextForSubscriber(int subId, String callingPackage, String destAddr, 132 String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, 133 boolean persistMessageForNonDefaultSmsApp) { 134 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 135 if (iccSmsIntMgr != null) { 136 iccSmsIntMgr.sendText(callingPackage, destAddr, scAddr, text, sentIntent, 137 deliveryIntent, persistMessageForNonDefaultSmsApp); 138 } else { 139 Rlog.e(LOG_TAG,"sendTextForSubscriber iccSmsIntMgr is null for" + 140 " Subscription: " + subId); 141 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 142 } 143 } 144 sendTextForSubscriberWithSelfPermissions(int subId, String callingPackage, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage)145 public void sendTextForSubscriberWithSelfPermissions(int subId, String callingPackage, 146 String destAddr, String scAddr, String text, PendingIntent sentIntent, 147 PendingIntent deliveryIntent, boolean persistMessage) { 148 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 149 if (iccSmsIntMgr != null) { 150 iccSmsIntMgr.sendTextWithSelfPermissions(callingPackage, destAddr, scAddr, text, 151 sentIntent, deliveryIntent, persistMessage); 152 } else { 153 Rlog.e(LOG_TAG,"sendText iccSmsIntMgr is null for" + 154 " Subscription: " + subId); 155 } 156 } 157 sendMultipartText(String callingPackage, String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)158 public void sendMultipartText(String callingPackage, String destAddr, String scAddr, 159 List<String> parts, List<PendingIntent> sentIntents, 160 List<PendingIntent> deliveryIntents) throws android.os.RemoteException { 161 sendMultipartTextForSubscriber(getPreferredSmsSubscription(), callingPackage, destAddr, 162 scAddr, parts, sentIntents, deliveryIntents, 163 true /* persistMessageForNonDefaultSmsApp */); 164 } 165 166 @Override sendMultipartTextForSubscriber(int subId, String callingPackage, String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp)167 public void sendMultipartTextForSubscriber(int subId, String callingPackage, String destAddr, 168 String scAddr, List<String> parts, List<PendingIntent> sentIntents, 169 List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) 170 throws android.os.RemoteException { 171 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 172 if (iccSmsIntMgr != null ) { 173 iccSmsIntMgr.sendMultipartText(callingPackage, destAddr, scAddr, parts, sentIntents, 174 deliveryIntents, persistMessageForNonDefaultSmsApp); 175 } else { 176 Rlog.e(LOG_TAG,"sendMultipartTextForSubscriber iccSmsIntMgr is null for" + 177 " Subscription: " + subId); 178 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 179 } 180 } 181 182 @Override enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)183 public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) 184 throws android.os.RemoteException { 185 return enableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier, 186 ranType); 187 } 188 189 @Override enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)190 public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, 191 int endMessageId, int ranType) throws android.os.RemoteException { 192 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 193 if (iccSmsIntMgr != null ) { 194 return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId, ranType); 195 } else { 196 Rlog.e(LOG_TAG,"enableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for" + 197 " Subscription: " + subId); 198 } 199 return false; 200 } 201 202 @Override disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)203 public boolean disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) 204 throws android.os.RemoteException { 205 return disableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier, 206 ranType); 207 } 208 209 @Override disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)210 public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, 211 int endMessageId, int ranType) throws android.os.RemoteException { 212 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 213 if (iccSmsIntMgr != null ) { 214 return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId, ranType); 215 } else { 216 Rlog.e(LOG_TAG,"disableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for" + 217 " Subscription:"+subId); 218 } 219 return false; 220 } 221 222 @Override getPremiumSmsPermission(String packageName)223 public int getPremiumSmsPermission(String packageName) { 224 return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName); 225 } 226 227 @Override getPremiumSmsPermissionForSubscriber(int subId, String packageName)228 public int getPremiumSmsPermissionForSubscriber(int subId, String packageName) { 229 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 230 if (iccSmsIntMgr != null ) { 231 return iccSmsIntMgr.getPremiumSmsPermission(packageName); 232 } else { 233 Rlog.e(LOG_TAG, "getPremiumSmsPermissionForSubscriber iccSmsIntMgr is null"); 234 } 235 //TODO Rakesh 236 return 0; 237 } 238 239 @Override setPremiumSmsPermission(String packageName, int permission)240 public void setPremiumSmsPermission(String packageName, int permission) { 241 setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName, permission); 242 } 243 244 @Override setPremiumSmsPermissionForSubscriber(int subId, String packageName, int permission)245 public void setPremiumSmsPermissionForSubscriber(int subId, String packageName, int permission) { 246 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 247 if (iccSmsIntMgr != null ) { 248 iccSmsIntMgr.setPremiumSmsPermission(packageName, permission); 249 } else { 250 Rlog.e(LOG_TAG, "setPremiumSmsPermissionForSubscriber iccSmsIntMgr is null"); 251 } 252 } 253 254 @Override isImsSmsSupportedForSubscriber(int subId)255 public boolean isImsSmsSupportedForSubscriber(int subId) { 256 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 257 if (iccSmsIntMgr != null ) { 258 return iccSmsIntMgr.isImsSmsSupported(); 259 } else { 260 Rlog.e(LOG_TAG, "isImsSmsSupportedForSubscriber iccSmsIntMgr is null"); 261 } 262 return false; 263 } 264 265 @Override isSmsSimPickActivityNeeded(int subId)266 public boolean isSmsSimPickActivityNeeded(int subId) { 267 final Context context = ActivityThread.currentApplication().getApplicationContext(); 268 TelephonyManager telephonyManager = 269 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 270 List<SubscriptionInfo> subInfoList; 271 final long identity = Binder.clearCallingIdentity(); 272 try { 273 subInfoList = SubscriptionManager.from(context).getActiveSubscriptionInfoList(); 274 } finally { 275 Binder.restoreCallingIdentity(identity); 276 } 277 278 if (subInfoList != null) { 279 final int subInfoLength = subInfoList.size(); 280 281 for (int i = 0; i < subInfoLength; ++i) { 282 final SubscriptionInfo sir = subInfoList.get(i); 283 if (sir != null && sir.getSubscriptionId() == subId) { 284 // The subscription id is valid, sms sim pick activity not needed 285 return false; 286 } 287 } 288 289 // If reached here and multiple SIMs and subs present, sms sim pick activity is needed 290 if (subInfoLength > 0 && telephonyManager.getSimCount() > 1) { 291 return true; 292 } 293 } 294 295 return false; 296 } 297 298 @Override getImsSmsFormatForSubscriber(int subId)299 public String getImsSmsFormatForSubscriber(int subId) { 300 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 301 if (iccSmsIntMgr != null ) { 302 return iccSmsIntMgr.getImsSmsFormat(); 303 } else { 304 Rlog.e(LOG_TAG, "getImsSmsFormatForSubscriber iccSmsIntMgr is null"); 305 } 306 return null; 307 } 308 309 @Override injectSmsPduForSubscriber( int subId, byte[] pdu, String format, PendingIntent receivedIntent)310 public void injectSmsPduForSubscriber( 311 int subId, byte[] pdu, String format, PendingIntent receivedIntent) { 312 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 313 if (iccSmsIntMgr != null) { 314 iccSmsIntMgr.injectSmsPdu(pdu, format, receivedIntent); 315 } else { 316 Rlog.e(LOG_TAG, "injectSmsPduForSubscriber iccSmsIntMgr is null"); 317 // RESULT_SMS_GENERIC_ERROR is documented for injectSmsPdu 318 sendErrorInPendingIntent(receivedIntent, Intents.RESULT_SMS_GENERIC_ERROR); 319 } 320 } 321 322 /** 323 * get sms interface manager object based on subscription. 324 **/ getIccSmsInterfaceManager(int subId)325 private @Nullable IccSmsInterfaceManager getIccSmsInterfaceManager(int subId) { 326 if (!isActiveSubId(subId)) { 327 Rlog.e(LOG_TAG, "Subscription " + subId + " is inactive."); 328 return null; 329 } 330 331 int phoneId = SubscriptionController.getInstance().getPhoneId(subId) ; 332 //Fixme: for multi-subscription case 333 if (!SubscriptionManager.isValidPhoneId(phoneId) 334 || phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) { 335 phoneId = 0; 336 } 337 338 try { 339 return (IccSmsInterfaceManager) 340 ((Phone)mPhone[(int)phoneId]).getIccSmsInterfaceManager(); 341 } catch (NullPointerException e) { 342 Rlog.e(LOG_TAG, "Exception is :"+e.toString()+" For subscription :"+subId ); 343 e.printStackTrace(); 344 return null; 345 } catch (ArrayIndexOutOfBoundsException e) { 346 Rlog.e(LOG_TAG, "Exception is :"+e.toString()+" For subscription :"+subId ); 347 e.printStackTrace(); 348 return null; 349 } 350 } 351 352 /** 353 Gets User preferred SMS subscription */ 354 @Override getPreferredSmsSubscription()355 public int getPreferredSmsSubscription() { 356 return SubscriptionController.getInstance().getDefaultSmsSubId(); 357 } 358 359 /** 360 * Get SMS prompt property, enabled or not 361 **/ 362 @Override isSMSPromptEnabled()363 public boolean isSMSPromptEnabled() { 364 return PhoneFactory.isSMSPromptEnabled(); 365 } 366 367 @Override sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress, PendingIntent sentIntent, PendingIntent deliveryIntent)368 public void sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress, 369 PendingIntent sentIntent, PendingIntent deliveryIntent) throws RemoteException { 370 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 371 if (iccSmsIntMgr != null) { 372 iccSmsIntMgr.sendStoredText(callingPkg, messageUri, scAddress, sentIntent, 373 deliveryIntent); 374 } else { 375 Rlog.e(LOG_TAG,"sendStoredText iccSmsIntMgr is null for subscription: " + subId); 376 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 377 } 378 } 379 380 @Override sendStoredMultipartText(int subId, String callingPkg, Uri messageUri, String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)381 public void sendStoredMultipartText(int subId, String callingPkg, Uri messageUri, 382 String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) 383 throws RemoteException { 384 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 385 if (iccSmsIntMgr != null ) { 386 iccSmsIntMgr.sendStoredMultipartText(callingPkg, messageUri, scAddress, sentIntents, 387 deliveryIntents); 388 } else { 389 Rlog.e(LOG_TAG,"sendStoredMultipartText iccSmsIntMgr is null for subscription: " 390 + subId); 391 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 392 } 393 } 394 395 @Override createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent)396 public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) { 397 if (!isActiveSubId(subId)) { 398 Rlog.e(LOG_TAG, "Subscription " + subId + " is inactive."); 399 return null; 400 } 401 402 int phoneId = SubscriptionController.getInstance().getPhoneId(subId); 403 //Fixme: for multi-subscription case 404 if (!SubscriptionManager.isValidPhoneId(phoneId) 405 || phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) { 406 phoneId = 0; 407 } 408 if (phoneId < 0 || phoneId >= mPhone.length || mPhone[phoneId] == null) { 409 Rlog.e(LOG_TAG, "phoneId " + phoneId + " points to an invalid phone"); 410 return null; 411 } 412 AppSmsManager appSmsManager = mPhone[phoneId].getAppSmsManager(); 413 return appSmsManager.createAppSpecificSmsToken(callingPkg, intent); 414 } 415 416 /* 417 * @return true if the subId is active. 418 */ isActiveSubId(int subId)419 private boolean isActiveSubId(int subId) { 420 return SubscriptionController.getInstance().isActiveSubId(subId); 421 } 422 sendErrorInPendingIntent(@ullable PendingIntent intent, int errorCode)423 private void sendErrorInPendingIntent(@Nullable PendingIntent intent, int errorCode) { 424 if (intent != null) { 425 try { 426 intent.send(errorCode); 427 } catch (PendingIntent.CanceledException ex) { 428 } 429 } 430 } 431 sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode)432 private void sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode) { 433 for (PendingIntent intent : intents) { 434 sendErrorInPendingIntent(intent, errorCode); 435 } 436 } 437 } 438