blob: 2028ca4a78a890a2b00984ff4faf06e87b4897a8 [file] [log] [blame]
/*
** Copyright 2007, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
package com.android.internal.telephony.gsm;
import android.content.Context;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.IccSmsInterfaceManager;
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.SmsRawData;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static android.telephony.SmsManager.STATUS_ON_ICC_FREE;
/**
* SimSmsInterfaceManager to provide an inter-process communication to
* access Sms in Sim.
*/
public class SimSmsInterfaceManager extends IccSmsInterfaceManager {
static final String LOG_TAG = "GSM";
static final boolean DBG = true;
private final Object mLock = new Object();
private boolean mSuccess;
private List<SmsRawData> mSms;
private static final int EVENT_LOAD_DONE = 1;
private static final int EVENT_UPDATE_DONE = 2;
Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_UPDATE_DONE:
ar = (AsyncResult) msg.obj;
synchronized (mLock) {
mSuccess = (ar.exception == null);
mLock.notifyAll();
}
break;
case EVENT_LOAD_DONE:
ar = (AsyncResult)msg.obj;
synchronized (mLock) {
if (ar.exception == null) {
mSms = buildValidRawData((ArrayList<byte[]>) ar.result);
} else {
if(DBG) log("Cannot load Sms records");
if (mSms != null)
mSms.clear();
}
mLock.notifyAll();
}
break;
}
}
};
public SimSmsInterfaceManager(GSMPhone phone) {
super(phone);
mDispatcher = new GsmSMSDispatcher(phone);
}
public void dispose() {
}
protected void finalize() {
try {
super.finalize();
} catch (Throwable throwable) {
Log.e(LOG_TAG, "Error while finalizing:", throwable);
}
if(DBG) Log.d(LOG_TAG, "SimSmsInterfaceManager finalized");
}
/**
* Update the specified message on the SIM.
*
* @param index record index of message to update
* @param status new message status (STATUS_ON_ICC_READ,
* STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
* STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
* @param pdu the raw PDU to store
* @return success or not
*
*/
public boolean
updateMessageOnIccEf(int index, int status, byte[] pdu) {
if (DBG) log("updateMessageOnIccEf: index=" + index +
" status=" + status + " ==> " +
"("+ Arrays.toString(pdu) + ")");
enforceReceiveAndSend("Updating message on SIM");
synchronized(mLock) {
mSuccess = false;
Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
if (status == STATUS_ON_ICC_FREE) {
// Special case FREE: call deleteSmsOnSim instead of
// manipulating the SIM record
mPhone.mCM.deleteSmsOnSim(index, response);
} else {
byte[] record = makeSmsRecordData(status, pdu);
mPhone.getIccFileHandler().updateEFLinearFixed(
IccConstants.EF_SMS,
index, record, null, response);
}
try {
mLock.wait();
} catch (InterruptedException e) {
log("interrupted while trying to update by index");
}
}
return mSuccess;
}
/**
* Copy a raw SMS PDU to the SIM.
*
* @param pdu the raw PDU to store
* @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
* STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
* @return success or not
*
*/
public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
"pdu=("+ Arrays.toString(pdu) +
"), smsm=(" + Arrays.toString(smsc) +")");
enforceReceiveAndSend("Copying message to SIM");
synchronized(mLock) {
mSuccess = false;
Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
mPhone.mCM.writeSmsToSim(status, IccUtils.bytesToHexString(smsc),
IccUtils.bytesToHexString(pdu), response);
try {
mLock.wait();
} catch (InterruptedException e) {
log("interrupted while trying to update by index");
}
}
return mSuccess;
}
/**
* Retrieves all messages currently stored on ICC.
*
* @return list of SmsRawData of all sms on ICC
*/
public List<SmsRawData> getAllMessagesFromIccEf() {
if (DBG) log("getAllMessagesFromEF");
Context context = mPhone.getContext();
context.enforceCallingPermission(
"android.permission.RECEIVE_SMS",
"Reading messages from SIM");
synchronized(mLock) {
Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
try {
mLock.wait();
} catch (InterruptedException e) {
log("interrupted while trying to load from the SIM");
}
}
return mSms;
}
protected void log(String msg) {
Log.d(LOG_TAG, "[SimSmsInterfaceManager] " + msg);
}
}