Home | History | Annotate | Download | only in telephony
      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