Home | History | Annotate | Download | only in cdma
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 
     18 package com.android.internal.telephony.cdma;
     19 
     20 import android.content.Context;
     21 import android.os.AsyncResult;
     22 import android.os.Handler;
     23 import android.os.Message;
     24 import android.util.Log;
     25 
     26 import com.android.internal.telephony.IccConstants;
     27 import com.android.internal.telephony.IccSmsInterfaceManager;
     28 import com.android.internal.telephony.IccUtils;
     29 import com.android.internal.telephony.PhoneProxy;
     30 import com.android.internal.telephony.SMSDispatcher;
     31 import com.android.internal.telephony.SmsRawData;
     32 
     33 import java.util.ArrayList;
     34 import java.util.Arrays;
     35 import java.util.List;
     36 
     37 import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
     38 
     39 /**
     40  * RuimSmsInterfaceManager to provide an inter-process communication to
     41  * access Sms in Ruim.
     42  */
     43 public class RuimSmsInterfaceManager extends IccSmsInterfaceManager {
     44     static final String LOG_TAG = "CDMA";
     45     static final boolean DBG = true;
     46 
     47     private final Object mLock = new Object();
     48     private boolean mSuccess;
     49     private List<SmsRawData> mSms;
     50 
     51     private static final int EVENT_LOAD_DONE = 1;
     52     private static final int EVENT_UPDATE_DONE = 2;
     53 
     54     Handler mHandler = new Handler() {
     55         @Override
     56         public void handleMessage(Message msg) {
     57             AsyncResult ar;
     58 
     59             switch (msg.what) {
     60                 case EVENT_UPDATE_DONE:
     61                     ar = (AsyncResult) msg.obj;
     62                     synchronized (mLock) {
     63                         mSuccess = (ar.exception == null);
     64                         mLock.notifyAll();
     65                     }
     66                     break;
     67                 case EVENT_LOAD_DONE:
     68                     ar = (AsyncResult)msg.obj;
     69                     synchronized (mLock) {
     70                         if (ar.exception == null) {
     71                             mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
     72                         } else {
     73                             if(DBG) log("Cannot load Sms records");
     74                             if (mSms != null)
     75                                 mSms.clear();
     76                         }
     77                         mLock.notifyAll();
     78                     }
     79                     break;
     80             }
     81         }
     82     };
     83 
     84     public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) {
     85         super(phone);
     86         mDispatcher = dispatcher;
     87     }
     88 
     89     public void dispose() {
     90     }
     91 
     92     protected void finalize() {
     93         try {
     94             super.finalize();
     95         } catch (Throwable throwable) {
     96             Log.e(LOG_TAG, "Error while finalizing:", throwable);
     97         }
     98         if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized");
     99     }
    100 
    101     /**
    102      * Update the specified message on the RUIM.
    103      *
    104      * @param index record index of message to update
    105      * @param status new message status (STATUS_ON_ICC_READ,
    106      *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
    107      *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
    108      * @param pdu the raw PDU to store
    109      * @return success or not
    110      *
    111      */
    112     public boolean
    113     updateMessageOnIccEf(int index, int status, byte[] pdu) {
    114         if (DBG) log("updateMessageOnIccEf: index=" + index +
    115                 " status=" + status + " ==> " +
    116                 "("+ pdu + ")");
    117         enforceReceiveAndSend("Updating message on RUIM");
    118         synchronized(mLock) {
    119             mSuccess = false;
    120             Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
    121 
    122             if (status == STATUS_ON_ICC_FREE) {
    123                 // Special case FREE: call deleteSmsOnRuim instead of
    124                 // manipulating the RUIM record
    125                 mPhone.mCM.deleteSmsOnRuim(index, response);
    126             } else {
    127                 byte[] record = makeSmsRecordData(status, pdu);
    128                 mPhone.getIccFileHandler().updateEFLinearFixed(
    129                         IccConstants.EF_SMS, index, record, null, response);
    130             }
    131             try {
    132                 mLock.wait();
    133             } catch (InterruptedException e) {
    134                 log("interrupted while trying to update by index");
    135             }
    136         }
    137         return mSuccess;
    138     }
    139 
    140     /**
    141      * Copy a raw SMS PDU to the RUIM.
    142      *
    143      * @param pdu the raw PDU to store
    144      * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
    145      *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
    146      * @return success or not
    147      *
    148      */
    149     public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
    150         //NOTE smsc not used in RUIM
    151         if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
    152                 "pdu=("+ Arrays.toString(pdu) + ")");
    153         enforceReceiveAndSend("Copying message to RUIM");
    154         synchronized(mLock) {
    155             mSuccess = false;
    156             Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
    157 
    158             mPhone.mCM.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu),
    159                     response);
    160 
    161             try {
    162                 mLock.wait();
    163             } catch (InterruptedException e) {
    164                 log("interrupted while trying to update by index");
    165             }
    166         }
    167         return mSuccess;
    168     }
    169 
    170     /**
    171      * Retrieves all messages currently stored on RUIM.
    172      */
    173     public List<SmsRawData> getAllMessagesFromIccEf() {
    174         if (DBG) log("getAllMessagesFromEF");
    175 
    176         Context context = mPhone.getContext();
    177 
    178         context.enforceCallingPermission(
    179                 "android.permission.RECEIVE_SMS",
    180                 "Reading messages from RUIM");
    181         synchronized(mLock) {
    182             Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
    183             mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
    184 
    185             try {
    186                 mLock.wait();
    187             } catch (InterruptedException e) {
    188                 log("interrupted while trying to load from the RUIM");
    189             }
    190         }
    191         return mSms;
    192     }
    193 
    194     public boolean enableCellBroadcast(int messageIdentifier) {
    195         // Not implemented
    196         Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
    197         return false;
    198     }
    199 
    200     public boolean disableCellBroadcast(int messageIdentifier) {
    201         // Not implemented
    202         Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
    203         return false;
    204     }
    205 
    206     public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
    207         // Not implemented
    208         Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
    209         return false;
    210     }
    211 
    212     public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
    213         // Not implemented
    214         Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
    215         return false;
    216     }
    217 
    218     protected void log(String msg) {
    219         Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg);
    220     }
    221 }
    222 
    223