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 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 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 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 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 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 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 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 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 145 public void sendTextForSubscriberWithSelfPermissions(int subId, String callingPackage, 146 String destAddr, String scAddr, String text, PendingIntent sentIntent, 147 PendingIntent deliveryIntent) { 148 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 149 if (iccSmsIntMgr != null) { 150 iccSmsIntMgr.sendTextWithSelfPermissions(callingPackage, destAddr, scAddr, text, 151 sentIntent, deliveryIntent); 152 } else { 153 Rlog.e(LOG_TAG,"sendText iccSmsIntMgr is null for" + 154 " Subscription: " + subId); 155 } 156 } 157 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 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 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 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 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 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 223 public int getPremiumSmsPermission(String packageName) { 224 return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName); 225 } 226 227 @Override 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 240 public void setPremiumSmsPermission(String packageName, int permission) { 241 setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName, permission); 242 } 243 244 @Override 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 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 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 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 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 **/ 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 ((PhoneProxy)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 355 public int getPreferredSmsSubscription() { 356 return SubscriptionController.getInstance().getDefaultSmsSubId(); 357 } 358 359 /** 360 * Get SMS prompt property, enabled or not 361 **/ 362 @Override 363 public boolean isSMSPromptEnabled() { 364 return PhoneFactory.isSMSPromptEnabled(); 365 } 366 367 @Override 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 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 /* 396 * @return true if the subId is active. 397 */ 398 private boolean isActiveSubId(int subId) { 399 return SubscriptionController.getInstance().isActiveSubId(subId); 400 } 401 402 private void sendErrorInPendingIntent(@Nullable PendingIntent intent, int errorCode) { 403 if (intent != null) { 404 try { 405 intent.send(errorCode); 406 } catch (PendingIntent.CanceledException ex) { 407 } 408 } 409 } 410 411 private void sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode) { 412 for (PendingIntent intent : intents) { 413 sendErrorInPendingIntent(intent, errorCode); 414 } 415 } 416 } 417