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.app.PendingIntent;
22import android.net.Uri;
23import android.os.RemoteException;
24import android.os.ServiceManager;
25import android.telephony.Rlog;
26import android.telephony.SubscriptionManager;
27
28import com.android.internal.telephony.ISms;
29import com.android.internal.telephony.Phone;
30import com.android.internal.telephony.SmsRawData;
31
32import java.util.ArrayList;
33import java.util.List;
34
35/**
36 * UiccSmsController to provide an inter-process communication to
37 * access Sms in Icc.
38 */
39public class UiccSmsController extends ISms.Stub {
40    static final String LOG_TAG = "RIL_UiccSmsController";
41
42    protected Phone[] mPhone;
43
44    protected UiccSmsController(Phone[] phone){
45        mPhone = phone;
46
47        if (ServiceManager.getService("isms") == null) {
48            ServiceManager.addService("isms", this);
49        }
50    }
51
52    public boolean
53    updateMessageOnIccEf(String callingPackage, int index, int status, byte[] pdu)
54            throws android.os.RemoteException {
55        return  updateMessageOnIccEfForSubscriber(getPreferredSmsSubscription(), callingPackage,
56                index, status, pdu);
57    }
58
59    public boolean
60    updateMessageOnIccEfForSubscriber(long subId, String callingPackage, int index, int status,
61                byte[] pdu) throws android.os.RemoteException {
62        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
63        if (iccSmsIntMgr != null) {
64            return iccSmsIntMgr.updateMessageOnIccEf(callingPackage, index, status, pdu);
65        } else {
66            Rlog.e(LOG_TAG,"updateMessageOnIccEf iccSmsIntMgr is null" +
67                          " for Subscription: " + subId);
68            return false;
69        }
70    }
71
72    public boolean copyMessageToIccEf(String callingPackage, int status, byte[] pdu, byte[] smsc)
73            throws android.os.RemoteException {
74        return copyMessageToIccEfForSubscriber(getPreferredSmsSubscription(), callingPackage, status,
75                pdu, smsc);
76    }
77
78    public boolean copyMessageToIccEfForSubscriber(long subId, String callingPackage, int status,
79            byte[] pdu, byte[] smsc) throws android.os.RemoteException {
80        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
81        if (iccSmsIntMgr != null) {
82            return iccSmsIntMgr.copyMessageToIccEf(callingPackage, status, pdu, smsc);
83        } else {
84            Rlog.e(LOG_TAG,"copyMessageToIccEf iccSmsIntMgr is null" +
85                          " for Subscription: " + subId);
86            return false;
87        }
88    }
89
90    public List<SmsRawData> getAllMessagesFromIccEf(String callingPackage)
91            throws android.os.RemoteException {
92        return getAllMessagesFromIccEfForSubscriber(getPreferredSmsSubscription(), callingPackage);
93    }
94
95    public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(long subId, String callingPackage)
96                throws android.os.RemoteException {
97        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
98        if (iccSmsIntMgr != null) {
99            return iccSmsIntMgr.getAllMessagesFromIccEf(callingPackage);
100        } else {
101            Rlog.e(LOG_TAG,"getAllMessagesFromIccEf iccSmsIntMgr is" +
102                          " null for Subscription: " + subId);
103            return null;
104        }
105    }
106
107    public void sendData(String callingPackage, String destAddr, String scAddr, int destPort,
108            byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
109         sendDataForSubscriber(getPreferredSmsSubscription(), callingPackage, destAddr, scAddr,
110                 destPort, data, sentIntent, deliveryIntent);
111    }
112
113    public void sendDataForSubscriber(long subId, String callingPackage, String destAddr,
114            String scAddr, int destPort, byte[] data, PendingIntent sentIntent,
115            PendingIntent deliveryIntent) {
116        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
117        if (iccSmsIntMgr != null) {
118            iccSmsIntMgr.sendData(callingPackage, destAddr, scAddr, destPort, data,
119                    sentIntent, deliveryIntent);
120        } else {
121            Rlog.e(LOG_TAG,"sendText iccSmsIntMgr is null for" +
122                          " Subscription: " + subId);
123        }
124    }
125
126    public void sendText(String callingPackage, String destAddr, String scAddr,
127            String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
128        sendTextForSubscriber(getPreferredSmsSubscription(), callingPackage, destAddr, scAddr,
129            text, sentIntent, deliveryIntent);
130    }
131
132    public void sendTextForSubscriber(long subId, String callingPackage, String destAddr,
133            String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
134        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
135        if (iccSmsIntMgr != null) {
136            iccSmsIntMgr.sendText(callingPackage, destAddr, scAddr, text, sentIntent,
137                    deliveryIntent);
138        } else {
139            Rlog.e(LOG_TAG,"sendText iccSmsIntMgr is null for" +
140                          " Subscription: " + subId);
141        }
142    }
143
144    public void sendMultipartText(String callingPackage, String destAddr, String scAddr,
145            List<String> parts, List<PendingIntent> sentIntents,
146            List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
147         sendMultipartTextForSubscriber(getPreferredSmsSubscription(), callingPackage, destAddr,
148                 scAddr, parts, sentIntents, deliveryIntents);
149    }
150
151    public void sendMultipartTextForSubscriber(long subId, String callingPackage, String destAddr,
152            String scAddr, List<String> parts, List<PendingIntent> sentIntents,
153            List<PendingIntent> deliveryIntents)
154            throws android.os.RemoteException {
155        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
156        if (iccSmsIntMgr != null ) {
157            iccSmsIntMgr.sendMultipartText(callingPackage, destAddr, scAddr, parts, sentIntents,
158                    deliveryIntents);
159        } else {
160            Rlog.e(LOG_TAG,"sendMultipartText iccSmsIntMgr is null for" +
161                          " Subscription: " + subId);
162        }
163    }
164
165    public boolean enableCellBroadcast(int messageIdentifier) throws android.os.RemoteException {
166        return enableCellBroadcastForSubscriber(getPreferredSmsSubscription(), messageIdentifier);
167    }
168
169    public boolean enableCellBroadcastForSubscriber(long subId, int messageIdentifier)
170                throws android.os.RemoteException {
171        return enableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier);
172    }
173
174    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId)
175            throws android.os.RemoteException {
176        return enableCellBroadcastRangeForSubscriber(getPreferredSmsSubscription(), startMessageId,
177                endMessageId);
178    }
179
180    public boolean enableCellBroadcastRangeForSubscriber(long subId, int startMessageId,
181            int endMessageId) throws android.os.RemoteException {
182        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
183        if (iccSmsIntMgr != null ) {
184            return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId);
185        } else {
186            Rlog.e(LOG_TAG,"enableCellBroadcast iccSmsIntMgr is null for" +
187                          " Subscription: " + subId);
188        }
189        return false;
190    }
191
192    public boolean disableCellBroadcast(int messageIdentifier) throws android.os.RemoteException {
193        return disableCellBroadcastForSubscriber(getPreferredSmsSubscription(), messageIdentifier);
194    }
195
196    public boolean disableCellBroadcastForSubscriber(long subId, int messageIdentifier)
197                throws android.os.RemoteException {
198        return disableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier);
199    }
200
201    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId)
202            throws android.os.RemoteException {
203        return disableCellBroadcastRangeForSubscriber(getPreferredSmsSubscription(), startMessageId,
204                endMessageId);
205    }
206
207    public boolean disableCellBroadcastRangeForSubscriber(long subId, int startMessageId,
208            int endMessageId) throws android.os.RemoteException {
209        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
210        if (iccSmsIntMgr != null ) {
211            return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId);
212        } else {
213            Rlog.e(LOG_TAG,"disableCellBroadcast iccSmsIntMgr is null for" +
214                          " Subscription:"+subId);
215        }
216       return false;
217    }
218
219    public int getPremiumSmsPermission(String packageName) {
220        return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName);
221    }
222
223    @Override
224    public int getPremiumSmsPermissionForSubscriber(long subId, String packageName) {
225        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
226        if (iccSmsIntMgr != null ) {
227            return iccSmsIntMgr.getPremiumSmsPermission(packageName);
228        } else {
229            Rlog.e(LOG_TAG, "getPremiumSmsPermission iccSmsIntMgr is null");
230        }
231        //TODO Rakesh
232        return 0;
233    }
234
235    public void setPremiumSmsPermission(String packageName, int permission) {
236         setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName, permission);
237    }
238
239    @Override
240    public void setPremiumSmsPermissionForSubscriber(long subId, String packageName, int permission) {
241        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
242        if (iccSmsIntMgr != null ) {
243            iccSmsIntMgr.setPremiumSmsPermission(packageName, permission);
244        } else {
245            Rlog.e(LOG_TAG, "setPremiumSmsPermission iccSmsIntMgr is null");
246        }
247    }
248
249    public boolean isImsSmsSupported() {
250        return isImsSmsSupportedForSubscriber(getPreferredSmsSubscription());
251    }
252
253    @Override
254    public boolean isImsSmsSupportedForSubscriber(long subId) {
255        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
256        if (iccSmsIntMgr != null ) {
257            return iccSmsIntMgr.isImsSmsSupported();
258        } else {
259            Rlog.e(LOG_TAG, "isImsSmsSupported iccSmsIntMgr is null");
260        }
261        return false;
262    }
263
264    public String getImsSmsFormat() {
265        return getImsSmsFormatForSubscriber(getPreferredSmsSubscription());
266    }
267
268    @Override
269    public String getImsSmsFormatForSubscriber(long subId) {
270       IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
271        if (iccSmsIntMgr != null ) {
272            return iccSmsIntMgr.getImsSmsFormat();
273        } else {
274            Rlog.e(LOG_TAG, "getImsSmsFormat iccSmsIntMgr is null");
275        }
276        return null;
277    }
278
279    @Override
280    public void updateSmsSendStatus(int messageRef, boolean success) {
281        getIccSmsInterfaceManager(SubscriptionManager.getDefaultSmsSubId())
282            .updateSmsSendStatus(messageRef, success);
283    }
284
285    @Override
286    public void injectSmsPdu(byte[] pdu, String format, PendingIntent receivedIntent) {
287        injectSmsPdu(SubscriptionManager.getDefaultSmsSubId(), pdu, format, receivedIntent);
288    }
289
290    // FIXME: Add injectSmsPdu to ISms.aidl
291    public void injectSmsPdu(long subId, byte[] pdu, String format, PendingIntent receivedIntent) {
292        getIccSmsInterfaceManager(subId).injectSmsPdu(pdu, format, receivedIntent);
293    }
294
295    /**
296     * get sms interface manager object based on subscription.
297     **/
298    private IccSmsInterfaceManager getIccSmsInterfaceManager(long subId) {
299        int phoneId = SubscriptionController.getInstance().getPhoneId(subId) ;
300        //Fixme: for multi-subscription case
301        if (!SubscriptionManager.isValidPhoneId(phoneId)
302                || phoneId == SubscriptionManager.DEFAULT_PHONE_ID) {
303            phoneId = 0;
304        }
305
306        try {
307            return (IccSmsInterfaceManager)
308                ((PhoneProxy)mPhone[(int)phoneId]).getIccSmsInterfaceManager();
309        } catch (NullPointerException e) {
310            Rlog.e(LOG_TAG, "Exception is :"+e.toString()+" For subscription :"+subId );
311            e.printStackTrace(); //This will print stact trace
312            return null;
313        } catch (ArrayIndexOutOfBoundsException e) {
314            Rlog.e(LOG_TAG, "Exception is :"+e.toString()+" For subscription :"+subId );
315            e.printStackTrace(); //This will print stack trace
316            return null;
317        }
318    }
319
320    /**
321       Gets User preferred SMS subscription */
322    public long getPreferredSmsSubscription() {
323        return  SubscriptionManager.getDefaultSmsSubId();
324    }
325
326    /**
327     * Get SMS prompt property,  enabled or not
328     **/
329    public boolean isSMSPromptEnabled() {
330        return PhoneFactory.isSMSPromptEnabled();
331    }
332
333    @Override
334    public void sendStoredText(long subId, String callingPkg, Uri messageUri, String scAddress,
335            PendingIntent sentIntent, PendingIntent deliveryIntent) throws RemoteException {
336        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
337        if (iccSmsIntMgr != null) {
338            iccSmsIntMgr.sendStoredText(callingPkg, messageUri, scAddress, sentIntent,
339                    deliveryIntent);
340        } else {
341            Rlog.e(LOG_TAG,"sendStoredText iccSmsIntMgr is null for subscription: " + subId);
342        }
343    }
344
345    @Override
346    public void sendStoredMultipartText(long subId, String callingPkg, Uri messageUri,
347            String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)
348            throws RemoteException {
349        IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId);
350        if (iccSmsIntMgr != null ) {
351            iccSmsIntMgr.sendStoredMultipartText(callingPkg, messageUri, scAddress, sentIntents,
352                    deliveryIntents);
353        } else {
354            Rlog.e(LOG_TAG,"sendStoredMultipartText iccSmsIntMgr is null for subscription: "
355                    + subId);
356        }
357    }
358
359}
360