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