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