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