RuimSmsInterfaceManager.java revision ab79ee4adcbc6eb9fb9c509766753f65d3857739
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.SMSDispatcher;
31import com.android.internal.telephony.SmsRawData;
32
33import java.util.ArrayList;
34import java.util.Arrays;
35import java.util.List;
36
37import 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 */
43public 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  = (List<SmsRawData>)
72                                    buildValidRawData((ArrayList<byte[]>) ar.result);
73                        } else {
74                            if(DBG) log("Cannot load Sms records");
75                            if (mSms != null)
76                                mSms.clear();
77                        }
78                        mLock.notifyAll();
79                    }
80                    break;
81            }
82        }
83    };
84
85    public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) {
86        super(phone);
87        mDispatcher = dispatcher;
88    }
89
90    public void dispose() {
91    }
92
93    protected void finalize() {
94        try {
95            super.finalize();
96        } catch (Throwable throwable) {
97            Log.e(LOG_TAG, "Error while finalizing:", throwable);
98        }
99        if(DBG) Log.d(LOG_TAG, "RuimSmsInterfaceManager finalized");
100    }
101
102    /**
103     * Update the specified message on the RUIM.
104     *
105     * @param index record index of message to update
106     * @param status new message status (STATUS_ON_ICC_READ,
107     *                  STATUS_ON_ICC_UNREAD, STATUS_ON_ICC_SENT,
108     *                  STATUS_ON_ICC_UNSENT, STATUS_ON_ICC_FREE)
109     * @param pdu the raw PDU to store
110     * @return success or not
111     *
112     */
113    public boolean
114    updateMessageOnIccEf(int index, int status, byte[] pdu) {
115        if (DBG) log("updateMessageOnIccEf: index=" + index +
116                " status=" + status + " ==> " +
117                "("+ pdu + ")");
118        enforceReceiveAndSend("Updating message on RUIM");
119        synchronized(mLock) {
120            mSuccess = false;
121            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
122
123            if (status == STATUS_ON_ICC_FREE) {
124                // Special case FREE: call deleteSmsOnRuim instead of
125                // manipulating the RUIM record
126                mPhone.mCM.deleteSmsOnRuim(index, response);
127            } else {
128                byte[] record = makeSmsRecordData(status, pdu);
129                mPhone.getIccFileHandler().updateEFLinearFixed(
130                        IccConstants.EF_SMS, index, record, null, response);
131            }
132            try {
133                mLock.wait();
134            } catch (InterruptedException e) {
135                log("interrupted while trying to update by index");
136            }
137        }
138        return mSuccess;
139    }
140
141    /**
142     * Copy a raw SMS PDU to the RUIM.
143     *
144     * @param pdu the raw PDU to store
145     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
146     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
147     * @return success or not
148     *
149     */
150    public boolean copyMessageToIccEf(int status, byte[] pdu, byte[] smsc) {
151        //NOTE smsc not used in RUIM
152        if (DBG) log("copyMessageToIccEf: status=" + status + " ==> " +
153                "pdu=("+ Arrays.toString(pdu) + ")");
154        enforceReceiveAndSend("Copying message to RUIM");
155        synchronized(mLock) {
156            mSuccess = false;
157            Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE);
158
159            mPhone.mCM.writeSmsToRuim(status, IccUtils.bytesToHexString(pdu),
160                    response);
161
162            try {
163                mLock.wait();
164            } catch (InterruptedException e) {
165                log("interrupted while trying to update by index");
166            }
167        }
168        return mSuccess;
169    }
170
171    /**
172     * Retrieves all messages currently stored on RUIM.
173     */
174    public List<SmsRawData> getAllMessagesFromIccEf() {
175        if (DBG) log("getAllMessagesFromEF");
176
177        Context context = mPhone.getContext();
178
179        context.enforceCallingPermission(
180                "android.permission.RECEIVE_SMS",
181                "Reading messages from RUIM");
182        synchronized(mLock) {
183            Message response = mHandler.obtainMessage(EVENT_LOAD_DONE);
184            mPhone.getIccFileHandler().loadEFLinearFixedAll(IccConstants.EF_SMS, response);
185
186            try {
187                mLock.wait();
188            } catch (InterruptedException e) {
189                log("interrupted while trying to load from the RUIM");
190            }
191        }
192        return mSms;
193    }
194
195    public boolean enableCellBroadcast(int messageIdentifier) {
196        // Not implemented
197        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
198        return false;
199    }
200
201    public boolean disableCellBroadcast(int messageIdentifier) {
202        // Not implemented
203        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
204        return false;
205    }
206
207    public boolean enableCellBroadcastRange(int startMessageId, int endMessageId) {
208        // Not implemented
209        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
210        return false;
211    }
212
213    public boolean disableCellBroadcastRange(int startMessageId, int endMessageId) {
214        // Not implemented
215        Log.e(LOG_TAG, "Error! Not implemented for CDMA.");
216        return false;
217    }
218
219    protected void log(String msg) {
220        Log.d(LOG_TAG, "[RuimSmsInterfaceManager] " + msg);
221    }
222}
223
224