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 18package com.android.internal.telephony.cdma; 19 20import android.content.Context; 21import android.os.AsyncResult; 22import android.os.Handler; 23import android.os.Message; 24import android.util.Log; 25 26import com.android.internal.telephony.IccConstants; 27import com.android.internal.telephony.IccSmsInterfaceManager; 28import com.android.internal.telephony.IccUtils; 29import com.android.internal.telephony.PhoneProxy; 30import com.android.internal.telephony.SmsRawData; 31 32import java.util.ArrayList; 33import java.util.List; 34 35import static android.telephony.SmsManager.STATUS_ON_ICC_FREE; 36 37/** 38 * RuimSmsInterfaceManager to provide an inter-process communication to 39 * access Sms in Ruim. 40 */ 41public class RuimSmsInterfaceManager extends IccSmsInterfaceManager { 42 static final String LOG_TAG = "CDMA"; 43 static final boolean DBG = true; 44 45 private final Object mLock = new Object(); 46 private boolean mSuccess; 47 private List<SmsRawData> mSms; 48 49 private static final int EVENT_LOAD_DONE = 1; 50 private static final int EVENT_UPDATE_DONE = 2; 51 52 Handler mHandler = new Handler() { 53 @Override 54 public void handleMessage(Message msg) { 55 AsyncResult ar; 56 57 switch (msg.what) { 58 case EVENT_UPDATE_DONE: 59 ar = (AsyncResult) msg.obj; 60 synchronized (mLock) { 61 mSuccess = (ar.exception == null); 62 mLock.notifyAll(); 63 } 64 break; 65 case EVENT_LOAD_DONE: 66 ar = (AsyncResult)msg.obj; 67 synchronized (mLock) { 68 if (ar.exception == null) { 69 mSms = (List<SmsRawData>) 70 buildValidRawData((ArrayList<byte[]>) ar.result); 71 } else { 72 if(DBG) log("Cannot load Sms records"); 73 if (mSms != null) 74 mSms.clear(); 75 } 76 mLock.notifyAll(); 77 } 78 break; 79 } 80 } 81 }; 82 83 public RuimSmsInterfaceManager(CDMAPhone phone) { 84 super(phone); 85 mDispatcher = new CdmaSMSDispatcher(phone); 86 } 87 88 public void dispose() { 89 } 90 91 protected void finalize() { 92 if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized"); 93 } 94 95 /** 96 * Update the specified message on the RUIM. 97 * 98 * @param index record index of message to update 99 * @param status new message status (STATUS_ON_ICC_READ, 100 * STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT, 101 * STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE) 102 * @param pdu the raw PDU to store 103 * @return success or not 104 * 105 */ 106 public boolean 107 updateMessageOnIccEf(int index, int status, byte[] pdu) { 108 if (DBG) log("updateMessageOnIccEf: index=" + index + 109 " status=" + status + " ==> " + 110 "("+ pdu + ")"); 111 enforceReceiveAndSend("Updating message on RUIM"); 112 synchronized(mLock) { 113 mSuccess = false; 114 Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 115 116 if (status == STATUS_ON_ICC_FREE) { 117 // Special case FREE: call deleteSmsOnRuim instead of 118 // manipulating the RUIM record 119 mPhone.mCM.deleteSmsOnRuim(index, response); 120 } else { 121 byte[] record = makeSmsRecordData(status, pdu); 122 mPhone.getIccFileHandler().updateEFLinearFixed( 123 IccConstants.EF_SMS, index, record, null, response); 124 } 125 try { 126 mLock.wait(); 127 } catch (InterruptedException e) { 128 log("interrupted while trying to update by index"); 129 } 130 } 131 return mSuccess; 132 } 133 134 /** 135 * Copy a raw SMS PDU to the RUIM. 136 * 137 * @param pdu the raw PDU to store 138 * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD, 139 * STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT) 140 * @return success or not 141 * 142 */ 143 public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) { 144 //NOTE smsc not used in RUIM 145 if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " + 146 "pdu=("+ pdu + ")"); 147 enforceReceiveAndSend("Copying message to RUIM"); 148 synchronized(mLock) { 149 mSuccess = false; 150 Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); 151 152 mPhone.mCM.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu), 153 response); 154 155 try { 156 mLock.wait(); 157 } catch (InterruptedException e) { 158 log("interrupted while trying to update by index"); 159 } 160 } 161 return mSuccess; 162 } 163 164 /** 165 * Retrieves all messages currently stored on RUIM. 166 */ 167 public List<SmsRawData> getAllMessagesFromIccEf() { 168 if (DBG) log("getAllMessagesFromEF"); 169 170 Context context = mPhone.getContext(); 171 172 context.enforceCallingPermission( 173 "android.permission.RECEIVE_SMS", 174 "Reading messages from RUIM"); 175 synchronized(mLock) { 176 Message response = mHandler.obtainMessage(EVENT_LOAD_DONE); 177 mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response); 178 179 try { 180 mLock.wait(); 181 } catch (InterruptedException e) { 182 log("interrupted while trying to load from the RUIM"); 183 } 184 } 185 return mSms; 186 } 187 188 protected void log(String msg) { 189 Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg); 190 } 191} 192 193