diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
commit | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /telephony/java/com | |
parent | 076357b8567458d4b6dfdcf839ef751634cd2bfb (diff) | |
download | frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'telephony/java/com')
115 files changed, 0 insertions, 34545 deletions
diff --git a/telephony/java/com/android/internal/telephony/ATParseEx.java b/telephony/java/com/android/internal/telephony/ATParseEx.java deleted file mode 100644 index c93b875..0000000 --- a/telephony/java/com/android/internal/telephony/ATParseEx.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class ATParseEx extends RuntimeException -{ - public - ATParseEx() - { - super(); - } - - public - ATParseEx(String s) - { - super(s); - } -} diff --git a/telephony/java/com/android/internal/telephony/ATResponseParser.java b/telephony/java/com/android/internal/telephony/ATResponseParser.java deleted file mode 100644 index 93ec455..0000000 --- a/telephony/java/com/android/internal/telephony/ATResponseParser.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class ATResponseParser -{ - /*************************** Instance Variables **************************/ - - private String line; - private int next = 0; - private int tokStart, tokEnd; - - /***************************** Class Methods *****************************/ - - public - ATResponseParser (String line) - { - this.line = line; - } - - public boolean - nextBoolean() - { - // "\s*(\d)(,|$)" - // \d is '0' or '1' - - nextTok(); - - if (tokEnd - tokStart > 1) { - throw new ATParseEx(); - } - char c = line.charAt(tokStart); - - if (c == '0') return false; - if (c == '1') return true; - throw new ATParseEx(); - } - - - /** positive int only */ - public int - nextInt() - { - // "\s*(\d+)(,|$)" - int ret = 0; - - nextTok(); - - for (int i = tokStart ; i < tokEnd ; i++) { - char c = line.charAt(i); - - // Yes, ASCII decimal digits only - if (c < '0' || c > '9') { - throw new ATParseEx(); - } - - ret *= 10; - ret += c - '0'; - } - - return ret; - } - - public String - nextString() - { - nextTok(); - - return line.substring(tokStart, tokEnd); - } - - public boolean - hasMore() - { - return next < line.length(); - } - - private void - nextTok() - { - int len = line.length(); - - if (next == 0) { - skipPrefix(); - } - - if (next >= len) { - throw new ATParseEx(); - } - - try { - // \s*("([^"]*)"|(.*)\s*)(,|$) - - char c = line.charAt(next++); - boolean hasQuote = false; - - c = skipWhiteSpace(c); - - if (c == '"') { - if (next >= len) { - throw new ATParseEx(); - } - c = line.charAt(next++); - tokStart = next - 1; - while (c != '"' && next < len) { - c = line.charAt(next++); - } - if (c != '"') { - throw new ATParseEx(); - } - tokEnd = next - 1; - if (next < len && line.charAt(next++) != ',') { - throw new ATParseEx(); - } - } else { - tokStart = next - 1; - tokEnd = tokStart; - while (c != ',') { - if (!Character.isWhitespace(c)) { - tokEnd = next; - } - if (next == len) { - break; - } - c = line.charAt(next++); - } - } - } catch (StringIndexOutOfBoundsException ex) { - throw new ATParseEx(); - } - } - - - /** Throws ATParseEx if whitespace extends to the end of string */ - private char - skipWhiteSpace (char c) - { - int len; - len = line.length(); - while (next < len && Character.isWhitespace(c)) { - c = line.charAt(next++); - } - - if (Character.isWhitespace(c)) { - throw new ATParseEx(); - } - return c; - } - - - private void - skipPrefix() - { - // consume "^[^:]:" - - next = 0; - int s = line.length(); - while (next < s){ - char c = line.charAt(next++); - - if (c == ':') { - return; - } - } - - throw new ATParseEx("missing prefix"); - } - -} diff --git a/telephony/java/com/android/internal/telephony/Call.java b/telephony/java/com/android/internal/telephony/Call.java deleted file mode 100644 index 82aeb25..0000000 --- a/telephony/java/com/android/internal/telephony/Call.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import java.util.List; -/** - * {@hide} - */ -public abstract class Call { - /* Enums */ - - public enum State { - IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED; - - public boolean isAlive() { - return !(this == IDLE || this == DISCONNECTED); - } - - public boolean isRinging() { - return this == INCOMING || this == WAITING; - } - - public boolean isDialing() { - return this == DIALING || this == ALERTING; - } - } - - /* Instance Methods */ - - /** Do not modify the List result!!! This list is not yours to keep - * It will change across event loop iterations top - */ - - public abstract List<Connection> getConnections(); - public abstract State getState(); - public abstract Phone getPhone(); - - /** - * hasConnection - * - * @param c a Connection object - * @return true if the call contains the connection object passed in - */ - public boolean hasConnection(Connection c) { - return c.getCall() == this; - } - - /** - * hasConnections - * @return true if the call contains one or more connections - */ - public boolean hasConnections() { - List connections = getConnections(); - - if (connections == null) { - return false; - } - - return connections.size() > 0; - } - - /** - * isIdle - * - * FIXME rename - * @return true if the call contains only disconnected connections (if any) - */ - public boolean isIdle() { - return !getState().isAlive(); - } - - /** - * Returns the Connection associated with this Call that was created - * first, or null if there are no Connections in this Call - */ - public Connection - getEarliestConnection() { - List l; - long time = Long.MAX_VALUE; - Connection c; - Connection earliest = null; - - l = getConnections(); - - if (l.size() == 0) { - return null; - } - - for (int i = 0, s = l.size() ; i < s ; i++) { - c = (Connection) l.get(i); - long t; - - t = c.getCreateTime(); - - if (t < time) { - earliest = c; - } - } - - return earliest; - } - - public long - getEarliestCreateTime() { - List l; - long time = Long.MAX_VALUE; - - l = getConnections(); - - if (l.size() == 0) { - return 0; - } - - for (int i = 0, s = l.size() ; i < s ; i++) { - Connection c = (Connection) l.get(i); - long t; - - t = c.getCreateTime(); - - time = t < time ? t : time; - } - - return time; - } - - public long - getEarliestConnectTime() { - List l; - long time = Long.MAX_VALUE; - - l = getConnections(); - - if (l.size() == 0) { - return 0; - } - - for (int i = 0, s = l.size() ; i < s ; i++) { - Connection c = (Connection) l.get(i); - long t; - - t = c.getConnectTime(); - - time = t < time ? t : time; - } - - return time; - } - - public abstract boolean isMultiparty(); - - public abstract void hangup() throws CallStateException; - - public boolean - isDialingOrAlerting() { - return getState().isDialing(); - } - - public boolean - isRinging() { - return getState().isRinging(); - } - -} diff --git a/telephony/java/com/android/internal/telephony/CallStateException.java b/telephony/java/com/android/internal/telephony/CallStateException.java deleted file mode 100644 index 6087124..0000000 --- a/telephony/java/com/android/internal/telephony/CallStateException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class CallStateException extends Exception -{ - public - CallStateException() - { - } - - public - CallStateException(String string) - { - super(string); - } -} diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java deleted file mode 100644 index 13b6e5c..0000000 --- a/telephony/java/com/android/internal/telephony/CallerInfo.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import android.content.Context; -import android.database.Cursor; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.provider.Contacts; -import android.provider.Contacts.People; -import android.provider.Contacts.Phones; -import android.text.TextUtils; -import android.telephony.TelephonyManager; -import android.telephony.PhoneNumberUtils; -import android.util.Config; -import android.util.Log; - -/** - * Looks up caller information for the given phone number. - * - * {@hide} - */ -public class CallerInfo { - private static final String TAG = "CallerInfo"; - - public static final String UNKNOWN_NUMBER = "-1"; - public static final String PRIVATE_NUMBER = "-2"; - - /** - * Please note that, any one of these member variables can be null, - * and any accesses to them should be prepared to handle such a case. - * - * Also, it is implied that phoneNumber is more often populated than - * name is, (think of calls being dialed/received using numbers where - * names are not known to the device), so phoneNumber should serve as - * a dependable fallback when name is unavailable. - * - * One other detail here is that this CallerInfo object reflects - * information found on a connection, it is an OUTPUT that serves - * mainly to display information to the user. In no way is this object - * used as input to make a connection, so we can choose to display - * whatever human-readable text makes sense to the user for a - * connection. This is especially relevant for the phone number field, - * since it is the one field that is most likely exposed to the user. - * - * As an example: - * 1. User dials "911" - * 2. Device recognizes that this is an emergency number - * 3. We use the "Emergency Number" string instead of "911" in the - * phoneNumber field. - * - * What we're really doing here is treating phoneNumber as an essential - * field here, NOT name. We're NOT always guaranteed to have a name - * for a connection, but the number should be displayable. - */ - public String name; - public String phoneNumber; - public String phoneLabel; - /* Split up the phoneLabel into number type and label name */ - public int numberType; - public String numberLabel; - - public int photoResource; - public long person_id; - public boolean needUpdate; - public Uri contactRefUri; - - // fields to hold individual contact preference data, - // including the send to voicemail flag and the ringtone - // uri reference. - public Uri contactRingtoneUri; - public boolean shouldSendToVoicemail; - - /** - * Drawable representing the caller image. This is essentially - * a cache for the image data tied into the connection / - * callerinfo object. The isCachedPhotoCurrent flag indicates - * if the image data needs to be reloaded. - */ - public Drawable cachedPhoto; - public boolean isCachedPhotoCurrent; - - // Don't keep checking VM if it's going to throw an exception for this proc. - private static boolean sSkipVmCheck = false; - - public CallerInfo() { - } - - /** - * getCallerInfo given a Cursor. - * @param context the context used to retrieve string constants - * @param contactRef the URI to attach to this CallerInfo object - * @param cursor the first object in the cursor is used to build the CallerInfo object. - * @return the CallerInfo which contains the caller id for the given - * number. The returned CallerInfo is null if no number is supplied. - */ - public static CallerInfo getCallerInfo(Context context, Uri contactRef, Cursor cursor) { - - CallerInfo info = new CallerInfo(); - info.photoResource = 0; - info.phoneLabel = null; - info.numberType = 0; - info.numberLabel = null; - info.cachedPhoto = null; - info.isCachedPhotoCurrent = false; - - if (Config.LOGV) Log.v(TAG, "construct callerInfo from cursor"); - - if (cursor != null) { - if (cursor.moveToFirst()) { - - int columnIndex; - - // Look for the name - columnIndex = cursor.getColumnIndex(People.NAME); - if (columnIndex != -1) { - info.name = cursor.getString(columnIndex); - } - - // Look for the number - columnIndex = cursor.getColumnIndex(Phones.NUMBER); - if (columnIndex != -1) { - info.phoneNumber = cursor.getString(columnIndex); - } - - // Look for the label/type combo - columnIndex = cursor.getColumnIndex(Phones.LABEL); - if (columnIndex != -1) { - int typeColumnIndex = cursor.getColumnIndex(Phones.TYPE); - if (typeColumnIndex != -1) { - info.numberType = cursor.getInt(typeColumnIndex); - info.numberLabel = cursor.getString(columnIndex); - info.phoneLabel = Contacts.Phones.getDisplayLabel(context, - info.numberType, info.numberLabel) - .toString(); - } - } - - // Look for the person ID - columnIndex = cursor.getColumnIndex(Phones.PERSON_ID); - if (columnIndex != -1) { - info.person_id = cursor.getLong(columnIndex); - } else { - columnIndex = cursor.getColumnIndex(People._ID); - if (columnIndex != -1) { - info.person_id = cursor.getLong(columnIndex); - } - } - - // look for the custom ringtone, create from the string stored - // in the database. - columnIndex = cursor.getColumnIndex(People.CUSTOM_RINGTONE); - if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { - info.contactRingtoneUri = Uri.parse(cursor.getString(columnIndex)); - } else { - info.contactRingtoneUri = null; - } - - // look for the send to voicemail flag, set it to true only - // under certain circumstances. - columnIndex = cursor.getColumnIndex(People.SEND_TO_VOICEMAIL); - info.shouldSendToVoicemail = (columnIndex != -1) && - ((cursor.getInt(columnIndex)) == 1); - } - cursor.close(); - } - - info.needUpdate = false; - info.name = normalize(info.name); - info.contactRefUri = contactRef; - - return info; - } - - /** - * getCallerInfo given a URI, look up in the call-log database - * for the uri unique key. - * @param context the context used to get the ContentResolver - * @param contactRef the URI used to lookup caller id - * @return the CallerInfo which contains the caller id for the given - * number. The returned CallerInfo is null if no number is supplied. - */ - public static CallerInfo getCallerInfo(Context context, Uri contactRef) { - - return getCallerInfo(context, contactRef, - context.getContentResolver().query(contactRef, null, null, null, null)); - } - - /** - * getCallerInfo given a phone number, look up in the call-log database - * for the matching caller id info. - * @param context the context used to get the ContentResolver - * @param number the phone number used to lookup caller id - * @return the CallerInfo which contains the caller id for the given - * number. The returned CallerInfo is null if no number is supplied. If - * a matching number is not found, then a generic caller info is returned, - * with all relevant fields empty or null. - */ - public static CallerInfo getCallerInfo(Context context, String number) { - if (TextUtils.isEmpty(number)) { - return null; - } else { - // Change the callerInfo number ONLY if it is an emergency number - // or if it is the voicemail number. If it is either, take a - // shortcut and skip the query. - if (PhoneNumberUtils.isEmergencyNumber(number)) { - CallerInfo ci = new CallerInfo(); - - // Note we're setting the phone number here (refer to javadoc - // comments at the top of CallerInfo class). - ci.phoneNumber = context.getString( - com.android.internal.R.string.emergency_call_dialog_number_for_display); - return ci; - } else { - try { - if (!sSkipVmCheck && PhoneNumberUtils.compare(number, - TelephonyManager.getDefault().getVoiceMailNumber())) { - CallerInfo ci = new CallerInfo(); - - // Note we're setting the phone number here (refer to javadoc - // comments at the top of CallerInfo class). - ci.phoneNumber = TelephonyManager.getDefault().getVoiceMailAlphaTag(); - // TODO: FIND ANOTHER ICON - //info.photoResource = android.R.drawable.badge_voicemail; - return ci; - } - } catch (SecurityException ex) { - // Don't crash if this process doesn't have permission to - // retrieve VM number. It's still allowed to look up caller info. - // But don't try it again. - sSkipVmCheck = true; - } - } - } - - Uri contactUri = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, - Uri.encode(number)); - - CallerInfo info = getCallerInfo(context, contactUri); - - // if no query results were returned with a viable number, - // fill in the original number value we used to query with. - if (TextUtils.isEmpty(info.phoneNumber)) { - info.phoneNumber = number; - } - - return info; - } - - /** - * getCallerId: a convenience method to get the caller id for a given - * number. - * - * @param context the context used to get the ContentResolver. - * @param number a phone number. - * @return if the number belongs to a contact, the contact's name is - * returned; otherwise, the number itself is returned. - * - * TODO NOTE: This MAY need to refer to the Asynchronous Query API - * [startQuery()], instead of getCallerInfo, but since it looks like - * it is only being used by the provider calls in the messaging app: - * 1. android.provider.Telephony.Mms.getDisplayAddress() - * 2. android.provider.Telephony.Sms.getDisplayAddress() - * We may not need to make the change. - */ - public static String getCallerId(Context context, String number) { - CallerInfo info = getCallerInfo(context, number); - String callerID = null; - - if (info != null) { - String name = info.name; - - if (!TextUtils.isEmpty(name)) { - callerID = name; - } else { - callerID = number; - } - } - - return callerID; - } - - private static String normalize(String s) { - if (s == null || s.length() > 0) { - return s; - } else { - return null; - } - } -} - diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java deleted file mode 100644 index 145e5d8..0000000 --- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java +++ /dev/null @@ -1,393 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import android.content.AsyncQueryHandler; -import android.content.Context; -import android.database.Cursor; -import android.database.SQLException; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.provider.Contacts; -import android.telephony.PhoneNumberUtils; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.Log; - -/** - * ASYNCHRONOUS QUERY API - */ - -public class CallerInfoAsyncQuery { - - private static final boolean DBG = false; - private static final String LOG_TAG = "CallerInfoAsyncQuery"; - - private static final int EVENT_NEW_QUERY = 1; - private static final int EVENT_ADD_LISTENER = 2; - private static final int EVENT_END_OF_QUEUE = 3; - private static final int EVENT_EMERGENCY_NUMBER = 4; - private static final int EVENT_VOICEMAIL_NUMBER = 5; - - private CallerInfoAsyncQueryHandler mHandler; - - // Don't keep checking VM if it's going to throw an exception for this proc. - private static boolean sSkipVmCheck = false; - - /** - * Interface for a CallerInfoAsyncQueryHandler result return. - */ - public interface OnQueryCompleteListener { - /** - * Called when the query is complete. - */ - public void onQueryComplete(int token, Object cookie, CallerInfo ci); - } - - - /** - * Wrap the cookie from the WorkerArgs with additional information needed by our - * classes. - */ - private static final class CookieWrapper { - public OnQueryCompleteListener listener; - public Object cookie; - public int event; - public String number; - } - - - /** - * Simple exception used to communicate problems with the query pool. - */ - public static class QueryPoolException extends SQLException { - public QueryPoolException(String error) { - super(error); - } - } - - /** - * Our own implementation of the AsyncQueryHandler. - */ - private class CallerInfoAsyncQueryHandler extends AsyncQueryHandler { - - /** - * The information relevant to each CallerInfo query. Each query may have multiple - * listeners, so each AsyncCursorInfo is associated with 2 or more CookieWrapper - * objects in the queue (one with a new query event, and one with a end event, with - * 0 or more additional listeners in between). - */ - private Context mQueryContext; - private Uri mQueryUri; - private CallerInfo mCallerInfo; - - /** - * Our own query worker thread. - * - * This thread handles the messages enqueued in the looper. The normal sequence - * of events is that a new query shows up in the looper queue, followed by 0 or - * more add listener requests, and then an end request. Of course, these requests - * can be interlaced with requests from other tokens, but is irrelevant to this - * handler since the handler has no state. - * - * Note that we depend on the queue to keep things in order; in other words, the - * looper queue must be FIFO with respect to input from the synchronous startQuery - * calls and output to this handleMessage call. - * - * This use of the queue is required because CallerInfo objects may be accessed - * multiple times before the query is complete. All accesses (listeners) must be - * queued up and informed in order when the query is complete. - */ - protected class CallerInfoWorkerHandler extends WorkerHandler { - public CallerInfoWorkerHandler(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - WorkerArgs args = (WorkerArgs) msg.obj; - CookieWrapper cw = (CookieWrapper) args.cookie; - - if (cw == null) { - // Normally, this should never be the case for calls originating - // from within this code. - // However, if there is any code that this Handler calls (such as in - // super.handleMessage) that DOES place unexpected messages on the - // queue, then we need pass these messages on. - if (DBG) log("Unexpected command (CookieWrapper is null): " + msg.what + - " ignored by CallerInfoWorkerHandler, passing onto parent."); - - super.handleMessage(msg); - } else { - - if (DBG) log("Processing event: " + cw.event + " token (arg1): " + msg.arg1 + - " command: " + msg.what + " query URI: " + args.uri); - - switch (cw.event) { - case EVENT_NEW_QUERY: - //start the sql command. - super.handleMessage(msg); - break; - - // shortcuts to avoid query for recognized numbers. - case EVENT_EMERGENCY_NUMBER: - case EVENT_VOICEMAIL_NUMBER: - - case EVENT_ADD_LISTENER: - case EVENT_END_OF_QUEUE: - // query was already completed, so just send the reply. - // passing the original token value back to the caller - // on top of the event values in arg1. - Message reply = args.handler.obtainMessage(msg.what); - reply.obj = args; - reply.arg1 = msg.arg1; - - reply.sendToTarget(); - - break; - default: - } - } - } - } - - - /** - * Asynchronous query handler class for the contact / callerinfo object. - */ - private CallerInfoAsyncQueryHandler(Context context) { - super(context.getContentResolver()); - } - - @Override - protected Handler createHandler(Looper looper) { - return new CallerInfoWorkerHandler(looper); - } - - /** - * Overrides onQueryComplete from AsyncQueryHandler. - * - * This method takes into account the state of this class; we construct the CallerInfo - * object only once for each set of listeners. When the query thread has done its work - * and calls this method, we inform the remaining listeners in the queue, until we're - * out of listeners. Once we get the message indicating that we should expect no new - * listeners for this CallerInfo object, we release the AsyncCursorInfo back into the - * pool. - */ - @Override - protected void onQueryComplete(int token, Object cookie, Cursor cursor) { - if (DBG) log("query complete for token: " + token); - - //get the cookie and notify the listener. - CookieWrapper cw = (CookieWrapper) cookie; - if (cw == null) { - // Normally, this should never be the case for calls originating - // from within this code. - // However, if there is any code that calls this method, we should - // check the parameters to make sure they're viable. - if (DBG) log("Cookie is null, ignoring onQueryComplete() request."); - return; - } - - if (cw.event == EVENT_END_OF_QUEUE) { - release(); - return; - } - - // check the token and if needed, create the callerinfo object. - if (mCallerInfo == null) { - if ((mQueryContext == null) || (mQueryUri == null)) { - throw new QueryPoolException - ("Bad context or query uri, or CallerInfoAsyncQuery already released."); - } - - // adjust the callerInfo data as needed, and only if it was set from the - // initial query request. - // Change the callerInfo number ONLY if it is an emergency number or the - // voicemail number, and adjust other data (including photoResource) - // accordingly. - if (cw.event == EVENT_EMERGENCY_NUMBER) { - mCallerInfo = new CallerInfo(); - // Note we're setting the phone number here (refer to javadoc - // comments at the top of CallerInfo class). - mCallerInfo.phoneNumber = mQueryContext.getString(com.android.internal - .R.string.emergency_call_dialog_number_for_display); - mCallerInfo.photoResource = com.android.internal.R.drawable.picture_emergency; - - } else if (cw.event == EVENT_VOICEMAIL_NUMBER) { - mCallerInfo = new CallerInfo(); - try { - // Note we're setting the phone number here (refer to javadoc - // comments at the top of CallerInfo class). - mCallerInfo.phoneNumber = - TelephonyManager.getDefault().getVoiceMailAlphaTag(); - } catch (SecurityException ex) { - // Should never happen: if this process does not have - // permission to retrieve VM tag, it should not have - // permission to retrieve VM number and would not generate - // an EVENT_VOICEMAIL_NUMBER. But if it happens, don't crash. - } - } else { - mCallerInfo = CallerInfo.getCallerInfo(mQueryContext, mQueryUri, cursor); - // Use the number entered by the user for display. - if (!TextUtils.isEmpty(cw.number)) { - mCallerInfo.phoneNumber = PhoneNumberUtils.formatNumber(cw.number); - } - } - - if (DBG) log("constructing CallerInfo object for token: " + token); - - //notify that we can clean up the queue after this. - CookieWrapper endMarker = new CookieWrapper(); - endMarker.event = EVENT_END_OF_QUEUE; - startQuery (token, endMarker, null, null, null, null, null); - } - - //notify the listener that the query is complete. - if (cw.listener != null) { - if (DBG) log("notifying listener: " + cw.listener.getClass().toString() + - " for token: " + token); - cw.listener.onQueryComplete(token, cw.cookie, mCallerInfo); - } - } - } - - /** - * Private constructor for factory methods. - */ - private CallerInfoAsyncQuery() { - } - - - /** - * Factory method to start query with a Uri query spec - */ - public static CallerInfoAsyncQuery startQuery(int token, Context context, Uri contactRef, - OnQueryCompleteListener listener, Object cookie) { - - CallerInfoAsyncQuery c = new CallerInfoAsyncQuery(); - c.allocate(context, contactRef); - - if (DBG) log("starting query for URI: " + contactRef + " handler: " + c.toString()); - - //create cookieWrapper, start query - CookieWrapper cw = new CookieWrapper(); - cw.listener = listener; - cw.cookie = cookie; - cw.event = EVENT_NEW_QUERY; - - c.mHandler.startQuery (token, cw, contactRef, null, null, null, null); - - return c; - } - - /** - * Factory method to start query with a number - */ - public static CallerInfoAsyncQuery startQuery(int token, Context context, String number, - OnQueryCompleteListener listener, Object cookie) { - //contruct the URI object and start Query. - Uri contactRef = Uri.withAppendedPath(Contacts.Phones.CONTENT_FILTER_URL, number); - - CallerInfoAsyncQuery c = new CallerInfoAsyncQuery(); - c.allocate(context, contactRef); - - if (DBG) log("starting query for number: " + number + " handler: " + c.toString()); - - //create cookieWrapper, start query - CookieWrapper cw = new CookieWrapper(); - cw.listener = listener; - cw.cookie = cookie; - cw.number = number; - - // check to see if these are recognized numbers, and use shortcuts if we can. - if (PhoneNumberUtils.isEmergencyNumber(number)) { - cw.event = EVENT_EMERGENCY_NUMBER; - } else { - String vmNumber = null; - if (!sSkipVmCheck){ - try { - vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(); - } catch (SecurityException ex) { - // Don't crash if this process doesn't have permission to - // retrieve VM number. It's still allowed to look up caller info. - // But don't try it again. - sSkipVmCheck = true; - } - } - if (PhoneNumberUtils.compare(number, vmNumber)) { - cw.event = EVENT_VOICEMAIL_NUMBER; - } else { - cw.event = EVENT_NEW_QUERY; - } - } - - c.mHandler.startQuery (token, cw, contactRef, null, null, null, null); - - return c; - } - - /** - * Method to add listeners to a currently running query - */ - public void addQueryListener(int token, OnQueryCompleteListener listener, Object cookie) { - - if (DBG) log("adding listener to query: " + mHandler.mQueryUri + " handler: " + - mHandler.toString()); - - //create cookieWrapper, add query request to end of queue. - CookieWrapper cw = new CookieWrapper(); - cw.listener = listener; - cw.cookie = cookie; - cw.event = EVENT_ADD_LISTENER; - - mHandler.startQuery (token, cw, null, null, null, null, null); - } - - /** - * Method to create a new CallerInfoAsyncQueryHandler object, ensuring correct - * state of context and uri. - */ - private void allocate (Context context, Uri contactRef) { - if ((context == null) || (contactRef == null)){ - throw new QueryPoolException("Bad context or query uri."); - } - mHandler = new CallerInfoAsyncQueryHandler(context); - mHandler.mQueryContext = context; - mHandler.mQueryUri = contactRef; - } - - /** - * Releases the relevant data. - */ - private void release () { - mHandler.mQueryContext = null; - mHandler.mQueryUri = null; - mHandler.mCallerInfo = null; - mHandler = null; - } - - /** - * static logging method - */ - private static void log(String msg) { - Log.d(LOG_TAG, msg); - } -} - diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java deleted file mode 100644 index d53d4ab..0000000 --- a/telephony/java/com/android/internal/telephony/Connection.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public abstract class Connection -{ - public enum DisconnectCause { - NOT_DISCONNECTED, /* has not yet disconnected */ - INCOMING_MISSED, /* an incoming call that was missed and never answered */ - NORMAL, /* normal; remote */ - LOCAL, /* normal; local hangup */ - BUSY, /* outgoing call to busy line */ - CONGESTION, /* outgoing call to congested network */ - MMI, /* not presently used; dial() returns null */ - INVALID_NUMBER, /* invalid dial string */ - LOST_SIGNAL, - LIMIT_EXCEEDED, /* eg GSM ACM limit exceeded */ - INCOMING_REJECTED, /* an incoming call that was rejected */ - POWER_OFF, /* radio is turned off explicitly */ - OUT_OF_SERVICE, /* out of service */ - SIM_ERROR, /* No SIM, SIM locked, or other SIM error */ - CALL_BARRED, /* call was blocked by call barrring */ - FDN_BLOCKED /* call was blocked by fixed dial number */ - } - - Object userData; - - /* Instance Methods */ - - /** - * Gets address (e.g., phone number) associated with connection - * TODO: distinguish reasons for unavailablity - * - * @return address or null if unavailable - */ - - public abstract String getAddress(); - - /** - * @return Call that owns this Connection, or null if none - */ - public abstract Call getCall(); - - /** - * Connection create time in currentTimeMillis() format - * Basically, set when object is created. - * Effectively, when an incoming call starts ringing or an - * outgoing call starts dialing - */ - public abstract long getCreateTime(); - - /** - * Connection connect time in currentTimeMillis() format - * For outgoing calls: Begins at (DIALING|ALERTING) -> ACTIVE transition - * For incoming calls: Begins at (INCOMING|WAITING) -> ACTIVE transition - * Returns 0 before then - */ - public abstract long getConnectTime(); - - /** - * Disconnect time in currentTimeMillis() format - * The time when this Connection makes a transition into ENDED or FAIL - * Returns 0 before then - */ - public abstract long getDisconnectTime(); - - /** - * returns the number of milliseconds the call has been connected, - * or 0 if the call has never connected. - * If the call is still connected, then returns the elapsed - * time since connect - */ - public abstract long getDurationMillis(); - - /** - * If this connection is HOLDING, return the number of milliseconds - * that it has been on hold for (approximently) - * If this connection is in any other state, return 0 - */ - - public abstract long getHoldDurationMillis(); - - /** - * Returns "NOT_DISCONNECTED" if not yet disconnected - */ - public abstract DisconnectCause getDisconnectCause(); - - /** - * Returns true of this connection originated elsewhere - * ("MT" or mobile terminated; another party called this terminal) - * or false if this call originated here (MO or mobile originated) - */ - public abstract boolean isIncoming(); - - /** - * If this Connection is connected, then it is associated with - * a Call. - * - * Returns getCall().getState() or Call.State.IDLE if not - * connected - */ - public Call.State getState() - { - Call c; - - c = getCall(); - - if (c == null) { - return Call.State.IDLE; - } else { - return c.getState(); - } - } - - /** - * isAlive() - * - * @return true if the connection isn't disconnected - * (could be active, holding, ringing, dialing, etc) - */ - public boolean - isAlive() - { - return getState().isAlive(); - } - - /** - * Returns true if Connection is connected and is INCOMING or WAITING - */ - public boolean - isRinging() - { - return getState().isRinging(); - } - - /** - * - * @return the userdata set in setUserData() - */ - public Object getUserData() - { - return userData; - } - - /** - * - * @param userdata user can store an any userdata in the Connection object. - */ - public void setUserData(Object userdata) - { - this.userData = userdata; - } - - /** - * Hangup individual Connection - */ - public abstract void hangup() throws CallStateException; - - /** - * Separate this call from its owner Call and assigns it to a new Call - * (eg if it is currently part of a Conference call - * TODO: Throw exception? Does GSM require error display on failure here? - */ - public abstract void separate() throws CallStateException; - - public enum PostDialState { - NOT_STARTED, /* The post dial string playback hasn't - been started, or this call is not yet - connected, or this is an incoming call */ - STARTED, /* The post dial string playback has begun */ - WAIT, /* The post dial string playback is waiting for a - call to proceedAfterWaitChar() */ - WILD, /* The post dial string playback is waiting for a - call to proceedAfterWildChar() */ - COMPLETE, /* The post dial string playback is complete */ - CANCELLED /* The post dial string playback was cancelled - with cancelPostDial() */ - } - - public abstract PostDialState getPostDialState(); - - /** - * Returns the portion of the post dial string that has not - * yet been dialed, or "" if none - */ - public abstract String getRemainingPostDialString(); - - /** - * See Phone.setOnPostDialWaitCharacter() - */ - - public abstract void proceedAfterWaitChar(); - - /** - * See Phone.setOnPostDialWildCharacter() - */ - public abstract void proceedAfterWildChar(String str); - /** - * Cancel any post - */ - public abstract void cancelPostDial(); - - -} diff --git a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java deleted file mode 100644 index 81ef623..0000000 --- a/telephony/java/com/android/internal/telephony/DefaultPhoneNotifier.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import android.os.Bundle; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.telephony.TelephonyManager; -import android.util.Log; - -import com.android.internal.telephony.ITelephonyRegistry; - -/** - * broadcast intents - */ -public class DefaultPhoneNotifier implements PhoneNotifier { - - static final String LOG_TAG = "GSM"; - private static final boolean DBG = true; - private ITelephonyRegistry mRegistry; - - /*package*/ - DefaultPhoneNotifier() { - mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - } - - public void notifyPhoneState(Phone sender) { - Call ringingCall = sender.getRingingCall(); - String incomingNumber = ""; - if (ringingCall != null && ringingCall.getEarliestConnection() != null){ - incomingNumber = ringingCall.getEarliestConnection().getAddress(); - } - try { - mRegistry.notifyCallState(convertCallState(sender.getState()), incomingNumber); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyServiceState(Phone sender) { - try { - mRegistry.notifyServiceState(sender.getServiceState()); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifySignalStrength(Phone sender) { - try { - mRegistry.notifySignalStrength(sender.getSignalStrengthASU()); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyMessageWaitingChanged(Phone sender) { - try { - mRegistry.notifyMessageWaitingChanged(sender.getMessageWaitingIndicator()); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyCallForwardingChanged(Phone sender) { - try { - mRegistry.notifyCallForwardingChanged(sender.getCallForwardingIndicator()); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyDataActivity(Phone sender) { - try { - mRegistry.notifyDataActivity(convertDataActivityState(sender.getDataActivityState())); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyDataConnection(Phone sender, String reason) { - try { - mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()), - sender.isDataConnectivityPossible(), reason, sender.getActiveApn(), - sender.getInterfaceName(null)); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyDataConnectionFailed(Phone sender, String reason) { - try { - mRegistry.notifyDataConnectionFailed(reason); - } catch (RemoteException ex) { - // system process is dead - } - } - - public void notifyCellLocation(Phone sender) { - Bundle data = new Bundle(); - sender.getCellLocation().fillInNotifierBundle(data); - try { - mRegistry.notifyCellLocation(data); - } catch (RemoteException ex) { - // system process is dead - } - } - - private void log(String s) { - Log.d(LOG_TAG, "[PhoneNotifier] " + s); - } - - /** - * Convert the {@link State} enum into the TelephonyManager.CALL_STATE_* constants - * for the public API. - */ - public static int convertCallState(Phone.State state) { - switch (state) { - case RINGING: - return TelephonyManager.CALL_STATE_RINGING; - case OFFHOOK: - return TelephonyManager.CALL_STATE_OFFHOOK; - default: - return TelephonyManager.CALL_STATE_IDLE; - } - } - - /** - * Convert the TelephonyManager.CALL_STATE_* constants into the {@link State} enum - * for the public API. - */ - public static Phone.State convertCallState(int state) { - switch (state) { - case TelephonyManager.CALL_STATE_RINGING: - return Phone.State.RINGING; - case TelephonyManager.CALL_STATE_OFFHOOK: - return Phone.State.OFFHOOK; - default: - return Phone.State.IDLE; - } - } - - /** - * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants - * for the public API. - */ - public static int convertDataState(Phone.DataState state) { - switch (state) { - case CONNECTING: - return TelephonyManager.DATA_CONNECTING; - case CONNECTED: - return TelephonyManager.DATA_CONNECTED; - case SUSPENDED: - return TelephonyManager.DATA_SUSPENDED; - default: - return TelephonyManager.DATA_DISCONNECTED; - } - } - - /** - * Convert the TelephonyManager.DATA_* constants into {@link DataState} enum - * for the public API. - */ - public static Phone.DataState convertDataState(int state) { - switch (state) { - case TelephonyManager.DATA_CONNECTING: - return Phone.DataState.CONNECTING; - case TelephonyManager.DATA_CONNECTED: - return Phone.DataState.CONNECTED; - case TelephonyManager.DATA_SUSPENDED: - return Phone.DataState.SUSPENDED; - default: - return Phone.DataState.DISCONNECTED; - } - } - - /** - * Convert the {@link DataState} enum into the TelephonyManager.DATA_* constants - * for the public API. - */ - public static int convertDataActivityState(Phone.DataActivityState state) { - switch (state) { - case DATAIN: - return TelephonyManager.DATA_ACTIVITY_IN; - case DATAOUT: - return TelephonyManager.DATA_ACTIVITY_OUT; - case DATAINANDOUT: - return TelephonyManager.DATA_ACTIVITY_INOUT; - default: - return TelephonyManager.DATA_ACTIVITY_NONE; - } - } - - /** - * Convert the TelephonyManager.DATA_* constants into the {@link DataState} enum - * for the public API. - */ - public static Phone.DataActivityState convertDataActivityState(int state) { - switch (state) { - case TelephonyManager.DATA_ACTIVITY_IN: - return Phone.DataActivityState.DATAIN; - case TelephonyManager.DATA_ACTIVITY_OUT: - return Phone.DataActivityState.DATAOUT; - case TelephonyManager.DATA_ACTIVITY_INOUT: - return Phone.DataActivityState.DATAINANDOUT; - default: - return Phone.DataActivityState.NONE; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl deleted file mode 100644 index e0884b3..0000000 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 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; - -import android.os.Bundle; -import android.telephony.ServiceState; - -oneway interface IPhoneStateListener { - void onServiceStateChanged(in ServiceState serviceState); - void onSignalStrengthChanged(int asu); - void onMessageWaitingIndicatorChanged(boolean mwi); - void onCallForwardingIndicatorChanged(boolean cfi); - - // we use bundle here instead of CellLocation so it can get the right subclass - void onCellLocationChanged(in Bundle location); - void onCallStateChanged(int state, String incomingNumber); - void onDataConnectionStateChanged(int state); - void onDataActivity(int direction); -} - diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl deleted file mode 100644 index 00cbaf9..0000000 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 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; - -/** - * Interface used to retrieve various phone-related subscriber information. - * - */ -interface IPhoneSubInfo { - - /** - * Retrieves the unique device ID, e.g., IMEI for GSM phones. - */ - String getDeviceId(); - - /** - * Retrieves the software version number for the device, e.g., IMEI/SV - * for GSM phones. - */ - String getDeviceSvn(); - - /** - * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones. - */ - String getSubscriberId(); - - /** - * Retrieves the serial number of the SIM, if applicable. - */ - String getSimSerialNumber(); - - /** - * Retrieves the phone number string for line 1. - */ - String getLine1Number(); - - /** - * Retrieves the alpha identifier for line 1. - */ - String getLine1AlphaTag(); - - /** - * Retrieves the voice mail number. - */ - String getVoiceMailNumber(); - - /** - * Retrieves the alpha identifier associated with the voice mail number. - */ - String getVoiceMailAlphaTag(); -} diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl deleted file mode 100644 index 2b4195b..0000000 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 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; - -import android.os.Bundle; -import java.util.List; -import android.telephony.NeighboringCellInfo; - -/** - * Interface used to interact with the phone. Mostly this is used by the - * TelephonyManager class. A few places are still using this directly. - * Please clean them up if possible and use TelephonyManager insteadl. - * - * {@hide} - */ -interface ITelephony { - - /** - * Dial a number. This doesn't place the call. It displays - * the Dialer screen. - * @param number the number to be dialed. If null, this - * would display the Dialer screen with no number pre-filled. - */ - void dial(String number); - - /** - * Place a call to the specified number. - * @param number the number to be called. - */ - void call(String number); - - /** - * If there is currently a call in progress, show the call screen. - * The DTMF dialpad may or may not be visible initially, depending on - * whether it was up when the user last exited the InCallScreen. - * - * @return true if the call screen was shown. - */ - boolean showCallScreen(); - - /** - * Variation of showCallScreen() that also specifies whether the - * DTMF dialpad should be initially visible when the InCallScreen - * comes up. - * - * @param showDialpad if true, make the dialpad visible initially, - * otherwise hide the dialpad initially. - * @return true if the call screen was shown. - * - * @see showCallScreen - */ - boolean showCallScreenWithDialpad(boolean showDialpad); - - /** - * End call or go to the Home screen - * - * @return whether it hung up - */ - boolean endCall(); - - /** - * Answer the currently-ringing call. - * - * If there's already a current active call, that call will be - * automatically put on hold. If both lines are currently in use, the - * current active call will be ended. - * - * TODO: provide a flag to let the caller specify what policy to use - * if both lines are in use. (The current behavior is hardwired to - * "answer incoming, end ongoing", which is how the CALL button - * is specced to behave.) - * - * TODO: this should be a oneway call (especially since it's called - * directly from the key queue thread). - */ - void answerRingingCall(); - - /** - * Silence the ringer if an incoming call is currently ringing. - * (If vibrating, stop the vibrator also.) - * - * It's safe to call this if the ringer has already been silenced, or - * even if there's no incoming call. (If so, this method will do nothing.) - * - * TODO: this should be a oneway call too (see above). - * (Actually *all* the methods here that return void can - * probably be oneway.) - */ - void silenceRinger(); - - /** - * Check if we are in either an active or holding call - * @return true if the phone state is OFFHOOK. - */ - boolean isOffhook(); - - /** - * Check if an incoming phone call is ringing or call waiting. - * @return true if the phone state is RINGING. - */ - boolean isRinging(); - - /** - * Check if the phone is idle. - * @return true if the phone state is IDLE. - */ - boolean isIdle(); - - /** - * Check to see if the radio is on or not. - * @return returns true if the radio is on. - */ - boolean isRadioOn(); - - /** - * Check if the SIM pin lock is enabled. - * @return true if the SIM pin lock is enabled. - */ - boolean isSimPinEnabled(); - - /** - * Cancels the missed calls notification. - */ - void cancelMissedCallsNotification(); - - /** - * Supply a pin to unlock the SIM. Blocks until a result is determined. - * @param pin The pin to check. - * @return whether the operation was a success. - */ - boolean supplyPin(String pin); - - /** - * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated - * without SEND (so <code>dial</code> is not appropriate). - * - * @param dialString the MMI command to be executed. - * @return true if MMI command is executed. - */ - boolean handlePinMmi(String dialString); - - /** - * Toggles the radio on or off. - */ - void toggleRadioOnOff(); - - /** - * Set the radio to on or off - */ - boolean setRadio(boolean turnOn); - - /** - * Request to update location information in service state - */ - void updateServiceLocation(); - - /** - * Enable location update notifications. - */ - void enableLocationUpdates(); - - /** - * Disable location update notifications. - */ - void disableLocationUpdates(); - - /** - * Enable a specific APN type. - */ - int enableApnType(String type); - - /** - * Disable a specific APN type. - */ - int disableApnType(String type); - - /** - * Allow mobile data connections. - */ - boolean enableDataConnectivity(); - - /** - * Disallow mobile data connections. - */ - boolean disableDataConnectivity(); - - /** - * Report whether data connectivity is possible. - */ - boolean isDataConnectivityPossible(); - - Bundle getCellLocation(); - - /** - * Returns the neighboring cell information of the device. - */ - List<NeighboringCellInfo> getNeighboringCellInfo(); - - int getCallState(); - int getDataActivity(); - int getDataState(); -} diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl deleted file mode 100644 index 1b011fe..0000000 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 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; - -import android.content.Intent; -import android.os.Bundle; -import android.telephony.ServiceState; -import com.android.internal.telephony.IPhoneStateListener; - -interface ITelephonyRegistry { - void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - - void notifyCallState(int state, String incomingNumber); - void notifyServiceState(in ServiceState state); - void notifySignalStrength(int signalStrengthASU); - void notifyMessageWaitingChanged(boolean mwi); - void notifyCallForwardingChanged(boolean cfi); - void notifyDataActivity(int state); - void notifyDataConnection(int state, boolean isDataConnectivityPossible, - String reason, String apn, String interfaceName); - void notifyDataConnectionFailed(String reason); - void notifyCellLocation(in Bundle cellLocation); -} diff --git a/telephony/java/com/android/internal/telephony/MmiCode.java b/telephony/java/com/android/internal/telephony/MmiCode.java deleted file mode 100644 index 925b06f..0000000 --- a/telephony/java/com/android/internal/telephony/MmiCode.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public interface MmiCode -{ - /** - * {@hide} - */ - public enum State { - PENDING, - CANCELLED, - COMPLETE, - FAILED - } - - - /** - * @return Current state of MmiCode request - */ - public State getState(); - - /** - * @return Localized message for UI display, valid only in COMPLETE - * or FAILED states. null otherwise - */ - - public CharSequence getMessage(); - - /** - * Cancels pending MMI request. - * State becomes CANCELLED unless already COMPLETE or FAILED - */ - public void cancel(); - - /** - * @return true if the network response is a REQUEST for more user input. - */ - public boolean isUssdRequest(); - - /** - * @return true if an outstanding request can be canceled. - */ - public boolean isCancelable(); -} diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java deleted file mode 100644 index 9a36bc1..0000000 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ /dev/null @@ -1,1128 +0,0 @@ -/* - * Copyright (C) 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; - -import android.content.Context; -import android.os.Handler; -import android.os.Message; -import android.telephony.CellLocation; -import android.telephony.ServiceState; -import com.android.internal.telephony.gsm.NetworkInfo; -import com.android.internal.telephony.gsm.PdpConnection; -import com.android.internal.telephony.test.SimulatedRadioControl; - -import java.util.List; - -/** - * Internal interface used to control the phone; SDK developers cannot - * obtain this interface. - * - * {@hide} - * - */ -public interface Phone { - - /** used to enable additional debug messages */ - static final boolean DEBUG_PHONE = true; - - - /** - * The phone state. One of the following:<p> - * <ul> - * <li>IDLE = no phone activity</li> - * <li>RINGING = a phone call is ringing or call waiting. - * In the latter case, another call is active as well</li> - * <li>OFFHOOK = The phone is off hook. At least one call - * exists that is dialing, active or holding and no calls are - * ringing or waiting.</li> - * </ul> - */ - enum State { - IDLE, RINGING, OFFHOOK; - }; - - /** - * The state of a data connection. - * <ul> - * <li>CONNECTED = IP traffic should be available</li> - * <li>CONNECTING = Currently setting up data connection</li> - * <li>DISCONNECTED = IP not available</li> - * <li>SUSPENDED = connection is created but IP traffic is - * temperately not available. i.e. voice call is in place - * in 2G network</li> - * </ul> - */ - enum DataState { - CONNECTED, CONNECTING, DISCONNECTED, SUSPENDED; - }; - - enum DataActivityState { - /** - * The state of a data activity. - * <ul> - * <li>NONE = No traffic</li> - * <li>DATAIN = Receiving IP ppp traffic</li> - * <li>DATAOUT = Sending IP ppp traffic</li> - * <li>DATAINANDOUT = Both receiving and sending IP ppp traffic</li> - * </ul> - */ - NONE, DATAIN, DATAOUT, DATAINANDOUT; - }; - - enum SuppService { - UNKNOWN, SWITCH, SEPARATE, TRANSFER, CONFERENCE, REJECT, HANGUP; - }; - - static final String STATE_KEY = "state"; - static final String PHONE_NAME_KEY = "phoneName"; - static final String FAILURE_REASON_KEY = "reason"; - static final String STATE_CHANGE_REASON_KEY = "reason"; - static final String DATA_APN_TYPE_KEY = "apnType"; - static final String DATA_APN_KEY = "apn"; - static final String DATA_IFACE_NAME_KEY = "iface"; - static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable"; - - /** - * APN types for data connections. These are usage categories for an APN - * entry. One APN entry may support multiple APN types, eg, a single APN - * may service regular internet traffic ("default") as well as MMS-specific - * connections.<br/> - * APN_TYPE_ALL is a special type to indicate that this APN entry can - * service all data connections. - */ - static final String APN_TYPE_ALL = "*"; - /** APN type for default data traffic */ - static final String APN_TYPE_DEFAULT = "default"; - /** APN type for MMS traffic */ - static final String APN_TYPE_MMS = "mms"; - - // "Features" accessible through the connectivity manager - static final String FEATURE_ENABLE_MMS = "enableMMS"; - - /** - * Return codes for <code>enableApnType()</code> - */ - static final int APN_ALREADY_ACTIVE = 0; - static final int APN_REQUEST_STARTED = 1; - static final int APN_TYPE_NOT_AVAILABLE = 2; - static final int APN_REQUEST_FAILED = 3; - - - /** - * Optional reasons for disconnect and connect - */ - static final String REASON_ROAMING_ON = "roamingOn"; - static final String REASON_ROAMING_OFF = "roamingOff"; - static final String REASON_DATA_DISABLED = "dataDisabled"; - static final String REASON_DATA_ENABLED = "dataEnabled"; - static final String REASON_GPRS_ATTACHED = "gprsAttached"; - static final String REASON_GPRS_DETACHED = "gprsDetached"; - static final String REASON_APN_CHANGED = "apnChanged"; - static final String REASON_APN_SWITCHED = "apnSwitched"; - static final String REASON_RESTORE_DEFAULT_APN = "restoreDefaultApn"; - static final String REASON_RADIO_TURNED_OFF = "radioTurnedOff"; - static final String REASON_PDP_RESET = "pdpReset"; - static final String REASON_VOICE_CALL_ENDED = "2GVoiceCallEnded"; - static final String REASON_VOICE_CALL_STARTED = "2GVoiceCallStarted"; - - // Used for band mode selction methods - static final int BM_UNSPECIFIED = 0; // selected by baseband automatically - static final int BM_EURO_BAND = 1; // GSM-900 / DCS-1800 / WCDMA-IMT-2000 - static final int BM_US_BAND = 2; // GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900 - static final int BM_JPN_BAND = 3; // WCDMA-800 / WCDMA-IMT-2000 - static final int BM_AUS_BAND = 4; // GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000 - static final int BM_AUS2_BAND = 5; // GSM-900 / DCS-1800 / WCDMA-850 - static final int BM_BOUNDARY = 6; // upper band boundary - - // Used for preferred network type - static final int NT_AUTO_TYPE = 0; // WCDMA preferred (auto mode) - static final int NT_GSM_TYPE = 1; // GSM only - static final int NT_WCDMA_TYPE = 2; // WCDMA only - - /** - * Get the current ServiceState. Use - * <code>registerForServiceStateChanged</code> to be informed of - * updates. - */ - ServiceState getServiceState(); - - /** - * Get the current CellLocation. - */ - CellLocation getCellLocation(); - - /** - * Get the current DataState. No change notification exists at this - * interface -- use - * {@link com.android.internal.telephony.PhoneStateIntentReceiver PhoneStateIntentReceiver} instead. - */ - DataState getDataConnectionState(); - - /** - * Get the current DataActivityState. No change notification exists at this - * interface -- use - * {@link TelephonyManager} instead. - */ - DataActivityState getDataActivityState(); - - /** - * Gets the context for the phone, as set at initialization time. - */ - Context getContext(); - - /** - * Get current coarse-grained voice call state. - * Use {@link #registerForPhoneStateChanged(Handler, int, Object) - * registerForPhoneStateChanged()} for change notification. <p> - * If the phone has an active call and call waiting occurs, - * then the phone state is RINGING not OFFHOOK - * <strong>Note:</strong> - * This registration point provides notification of finer-grained - * changes.<p> - * - */ - State getState(); - - /** - * Returns a string identifier for this phone interface for parties - * outside the phone app process. - * @return The string name. - */ - String getPhoneName(); - - /** - * Returns an array of string identifiers for the APN types serviced by the - * currently active or last connected APN. - * @return The string array. - */ - String[] getActiveApnTypes(); - - /** - * Returns a string identifier for currently active or last connected APN. - * @return The string name. - */ - String getActiveApn(); - - /** - * Get current signal strength. No change notification available on this - * interface. Use <code>PhoneStateNotifier</code> or an equivalent. - * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu). - * The following special values are defined:</p> - * <ul><li>0 means "-113 dBm or less".</li> - * <li>31 means "-51 dBm or greater".</li></ul> - * - * @return Current signal strength in ASU's. - */ - int getSignalStrengthASU(); - - /** - * Notifies when a previously untracked non-ringing/waiting connection has appeared. - * This is likely due to some other entity (eg, SIM card application) initiating a call. - */ - void registerForUnknownConnection(Handler h, int what, Object obj); - - /** - * Unregisters for unknown connection notifications. - */ - void unregisterForUnknownConnection(Handler h); - - /** - * Notifies when any aspect of the voice call state changes. - * Resulting events will have an AsyncResult in <code>Message.obj</code>. - * AsyncResult.userData will be set to the obj argument here. - * The <em>h</em> parameter is held only by a weak reference. - */ - void registerForPhoneStateChanged(Handler h, int what, Object obj); - - /** - * Unregisters for voice call state change notifications. - * Extraneous calls are tolerated silently. - */ - void unregisterForPhoneStateChanged(Handler h); - - - /** - * Notifies when a new ringing or waiting connection has appeared.<p> - * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = a Connection. <p> - * Please check Connection.isRinging() to make sure the Connection - * has not dropped since this message was posted. - * If Connection.isRinging() is true, then - * Connection.getCall() == Phone.getRingingCall() - */ - void registerForNewRingingConnection(Handler h, int what, Object obj); - - /** - * Unregisters for new ringing connection notification. - * Extraneous calls are tolerated silently - */ - - void unregisterForNewRingingConnection(Handler h); - - /** - * Notifies when an incoming call rings.<p> - * - * Messages received from this: - * Message.obj will be an AsyncResult - * AsyncResult.userObj = obj - * AsyncResult.result = a Connection. <p> - */ - void registerForIncomingRing(Handler h, int what, Object obj); - - /** - * Unregisters for ring notification. - * Extraneous calls are tolerated silently - */ - - void unregisterForIncomingRing(Handler h); - - - /** - * Notifies when a voice connection has disconnected, either due to local - * or remote hangup or error. - * - * Messages received from this will have the following members:<p> - * <ul><li>Message.obj will be an AsyncResult</li> - * <li>AsyncResult.userObj = obj</li> - * <li>AsyncResult.result = a Connection object that is - * no longer connected.</li></ul> - */ - void registerForDisconnect(Handler h, int what, Object obj); - - /** - * Unregisters for voice disconnection notification. - * Extraneous calls are tolerated silently - */ - void unregisterForDisconnect(Handler h); - - - /** - * Register for notifications of initiation of a new MMI code request. - * MMI codes for GSM are discussed in 3GPP TS 22.030.<p> - * - * Example: If Phone.dial is called with "*#31#", then the app will - * be notified here.<p> - * - * The returned <code>Message.obj</code> will contain an AsyncResult. - * - * <code>obj.result</code> will be an "MmiCode" object. - */ - void registerForMmiInitiate(Handler h, int what, Object obj); - - /** - * Unregisters for new MMI initiate notification. - * Extraneous calls are tolerated silently - */ - void unregisterForMmiInitiate(Handler h); - - /** - * Register for notifications that an MMI request has completed - * its network activity and is in its final state. This may mean a state - * of COMPLETE, FAILED, or CANCELLED. - * - * <code>Message.obj</code> will contain an AsyncResult. - * <code>obj.result</code> will be an "MmiCode" object - */ - void registerForMmiComplete(Handler h, int what, Object obj); - - /** - * Unregisters for MMI complete notification. - * Extraneous calls are tolerated silently - */ - void unregisterForMmiComplete(Handler h); - - /** - * Returns a list of MMI codes that are pending. (They have initiated - * but have not yet completed). - * Presently there is only ever one. - * Use <code>registerForMmiInitiate</code> - * and <code>registerForMmiComplete</code> for change notification. - */ - public List<? extends MmiCode> getPendingMmiCodes(); - - /** - * Sends user response to a USSD REQUEST message. An MmiCode instance - * representing this response is sent to handlers registered with - * registerForMmiInitiate. - * - * @param ussdMessge Message to send in the response. - */ - public void sendUssdResponse(String ussdMessge); - - /** - * Register for ServiceState changed. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a ServiceState instance - */ - void registerForServiceStateChanged(Handler h, int what, Object obj); - - /** - * Unregisters for ServiceStateChange notification. - * Extraneous calls are tolerated silently - */ - void unregisterForServiceStateChanged(Handler h); - - /** - * Register for Supplementary Service notifications from the network. - * Message.obj will contain an AsyncResult. - * AsyncResult.result will be a SuppServiceNotification instance. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForSuppServiceNotification(Handler h, int what, Object obj); - - /** - * Unregisters for Supplementary Service notifications. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForSuppServiceNotification(Handler h); - - /** - * Register for notifications when a supplementary service attempt fails. - * Message.obj will contain an AsyncResult. - * - * @param h Handler that receives the notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void registerForSuppServiceFailed(Handler h, int what, Object obj); - - /** - * Unregister for notifications when a supplementary service attempt fails. - * Extraneous calls are tolerated silently - * - * @param h Handler to be removed from the registrant list. - */ - void unregisterForSuppServiceFailed(Handler h); - - /** - * Returns SIM record load state. Use - * <code>getSimCard().registerForReady()</code> for change notification. - * - * @return true if records from the SIM have been loaded and are - * available (if applicable). If not applicable to the underlying - * technology, returns true as well. - */ - boolean getSimRecordsLoaded(); - - /** - * Returns the SIM card interface for this phone, or null - * if not applicable to underlying technology. - */ - SimCard getSimCard(); - - /** - * Answers a ringing or waiting call. Active calls, if any, go on hold. - * Answering occurs asynchronously, and final notification occurs via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - * - * @exception CallStateException when no call is ringing or waiting - */ - void acceptCall() throws CallStateException; - - /** - * Reject (ignore) a ringing call. In GSM, this means UDUB - * (User Determined User Busy). Reject occurs asynchronously, - * and final notification occurs via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - * - * @exception CallStateException when no call is ringing or waiting - */ - void rejectCall() throws CallStateException; - - /** - * Places any active calls on hold, and makes any held calls - * active. Switch occurs asynchronously and may fail. - * Final notification occurs via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - * - * @exception CallStateException if a call is ringing, waiting, or - * dialing/alerting. In these cases, this operation may not be performed. - */ - void switchHoldingAndActive() throws CallStateException; - - /** - * Whether or not the phone can conference in the current phone - * state--that is, one call holding and one call active. - * @return true if the phone can conference; false otherwise. - */ - boolean canConference(); - - /** - * Conferences holding and active. Conference occurs asynchronously - * and may fail. Final notification occurs via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - * - * @exception CallStateException if canConference() would return false. - * In these cases, this operation may not be performed. - */ - void conference() throws CallStateException; - - /** - * Whether or not the phone can do explicit call transfer in the current - * phone state--that is, one call holding and one call active. - * @return true if the phone can do explicit call transfer; false otherwise. - */ - boolean canTransfer(); - - /** - * Connects the two calls and disconnects the subscriber from both calls - * Explicit Call Transfer occurs asynchronously - * and may fail. Final notification occurs via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - * - * @exception CallStateException if canTransfer() would return false. - * In these cases, this operation may not be performed. - */ - void explicitCallTransfer() throws CallStateException; - - /** - * Clears all DISCONNECTED connections from Call connection lists. - * Calls that were in the DISCONNECTED state become idle. This occurs - * synchronously. - */ - void clearDisconnected(); - - - /** - * Gets the foreground call object, which represents all connections that - * are dialing or active (all connections - * that have their audio path connected).<p> - * - * The foreground call is a singleton object. It is constant for the life - * of this phone. It is never null.<p> - * - * The foreground call will only ever be in one of these states: - * IDLE, ACTIVE, DIALING, ALERTING, or DISCONNECTED. - * - * State change notification is available via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - */ - Call getForegroundCall(); - - /** - * Gets the background call object, which represents all connections that - * are holding (all connections that have been accepted or connected, but - * do not have their audio path connected). <p> - * - * The background call is a singleton object. It is constant for the life - * of this phone object . It is never null.<p> - * - * The background call will only ever be in one of these states: - * IDLE, HOLDING or DISCONNECTED. - * - * State change notification is available via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - */ - Call getBackgroundCall(); - - /** - * Gets the ringing call object, which represents an incoming - * connection (if present) that is pending answer/accept. (This connection - * may be RINGING or WAITING, and there may be only one.)<p> - - * The ringing call is a singleton object. It is constant for the life - * of this phone. It is never null.<p> - * - * The ringing call will only ever be in one of these states: - * IDLE, INCOMING, WAITING or DISCONNECTED. - * - * State change notification is available via - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()}. - */ - Call getRingingCall(); - - /** - * Initiate a new voice connection. This happens asynchronously, so you - * cannot assume the audio path is connected (or a call index has been - * assigned) until PhoneStateChanged notification has occurred. - * - * @exception CallStateException if a new outgoing call is not currently - * possible because no more call slots exist or a call exists that is - * dialing, alerting, ringing, or waiting. Other errors are - * handled asynchronously. - */ - Connection dial(String dialString) throws CallStateException; - - /** - * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated - * without SEND (so <code>dial</code> is not appropriate). - * - * @param dialString the MMI command to be executed. - * @return true if MMI command is executed. - */ - boolean handlePinMmi(String dialString); - - /** - * Handles in-call MMI commands. While in a call, or while receiving a - * call, use this to execute MMI commands. - * see 3GPP 20.030, section 6.5.5.1 for specs on the allowed MMI commands. - * - * @param command the MMI command to be executed. - * @return true if the MMI command is executed. - * @throws CallStateException - */ - boolean handleInCallMmiCommands(String command) throws CallStateException; - - /** - * Play a DTMF tone on the active call. Ignored if there is no active call. - * @param c should be one of 0-9, '*' or '#'. Other values will be - * silently ignored. - */ - void sendDtmf(char c); - - /** - * Start to paly a DTMF tone on the active call. Ignored if there is no active call - * or there is a playing DTMF tone. - * @param c should be one of 0-9, '*' or '#'. Other values will be - * silently ignored. - */ - void startDtmf(char c); - - /** - * Stop the playing DTMF tone. Ignored if there is no playing DTMF - * tone or no active call. - */ - void stopDtmf(); - - - /** - * Sets the radio power on/off state (off is sometimes - * called "airplane mode"). Current state can be gotten via - * {@link #getServiceState()}.{@link - * android.telephony.ServiceState#getState() getState()}. - * <strong>Note: </strong>This request is asynchronous. - * getServiceState().getState() will not change immediately after this call. - * registerForServiceStateChanged() to find out when the - * request is complete. - * - * @param power true means "on", false means "off". - */ - void setRadioPower(boolean power); - - /** - * Get voice message waiting indicator status. No change notification - * available on this interface. Use PhoneStateNotifier or similar instead. - * - * @return true if there is a voice message waiting - */ - boolean getMessageWaitingIndicator(); - - /** - * Get voice call forwarding indicator status. No change notification - * available on this interface. Use PhoneStateNotifier or similar instead. - * - * @return true if there is a voice call forwarding - */ - boolean getCallForwardingIndicator(); - - /** - * Get the line 1 phone number (MSISDN).<p> - * - * @return phone number. May return null if not - * available or the SIM is not ready - */ - String getLine1Number(); - - /** - * Returns the alpha tag associated with the msisdn number. - * If there is no alpha tag associated or the record is not yet available, - * returns a default localized string. <p> - */ - String getLine1AlphaTag(); - - /** - * Sets the MSISDN phone number in the SIM card. - * - * @param alphaTag the alpha tag associated with the MSISDN phone number - * (see getMsisdnAlphaTag) - * @param number the new MSISDN phone number to be set on the SIM. - * @param onComplete a callback message when the action is completed. - */ - void setLine1Number(String alphaTag, String number, Message onComplete); - - /** - * Get the voice mail access phone number. Typically dialed when the - * user holds the "1" key in the phone app. May return null if not - * available or the SIM is not ready.<p> - */ - String getVoiceMailNumber(); - - /** - * Returns the alpha tag associated with the voice mail number. - * If there is no alpha tag associated or the record is not yet available, - * returns a default localized string. <p> - * - * Please use this value instead of some other localized string when - * showing a name for this number in the UI. For example, call log - * entries should show this alpha tag. <p> - * - * Usage of this alpha tag in the UI is a common carrier requirement. - */ - String getVoiceMailAlphaTag(); - - /** - * setVoiceMailNumber - * sets the voicemail number in the SIM card. - * - * @param alphaTag the alpha tag associated with the voice mail number - * (see getVoiceMailAlphaTag) - * @param voiceMailNumber the new voicemail number to be set on the SIM. - * @param onComplete a callback message when the action is completed. - */ - void setVoiceMailNumber(String alphaTag, - String voiceMailNumber, - Message onComplete); - - /** - * getCallForwardingOptions - * gets a call forwarding option. The return value of - * ((AsyncResult)onComplete.obj) is an array of CallForwardInfo. - * - * @param commandInterfaceCFReason is one of the valid call forwarding - * CF_REASONS, as defined in - * <code>com.android.internal.telephony.gsm.CommandsInterface</code> - * @param onComplete a callback message when the action is completed. - * @see com.android.internal.telephony.gsm.CallForwardInfo for details. - */ - void getCallForwardingOption(int commandInterfaceCFReason, - Message onComplete); - - /** - * setCallForwardingOptions - * sets a call forwarding option. - * - * @param commandInterfaceCFReason is one of the valid call forwarding - * CF_REASONS, as defined in - * <code>com.android.internal.telephony.gsm.CommandsInterface</code> - * @param commandInterfaceCFAction is one of the valid call forwarding - * CF_ACTIONS, as defined in - * <code>com.android.internal.telephony.gsm.CommandsInterface</code> - * @param dialingNumber is the target phone number to forward calls to - * @param timerSeconds is used by CFNRy to indicate the timeout before - * forwarding is attempted. - * @param onComplete a callback message when the action is completed. - */ - void setCallForwardingOption(int commandInterfaceCFReason, - int commandInterfaceCFAction, - String dialingNumber, - int timerSeconds, - Message onComplete); - - /** - * getOutgoingCallerIdDisplay - * gets outgoing caller id display. The return value of - * ((AsyncResult)onComplete.obj) is an array of int, with a length of 2. - * - * @param onComplete a callback message when the action is completed. - * @see com.android.internal.telephony.gsm.CommandsInterface.getCLIR for details. - */ - void getOutgoingCallerIdDisplay(Message onComplete); - - /** - * setOutgoingCallerIdDisplay - * sets a call forwarding option. - * - * @param commandInterfaceCLIRMode is one of the valid call CLIR - * modes, as defined in - * <code>com.android.internal.telephony.gsm.CommandsInterface</code> - * @param onComplete a callback message when the action is completed. - */ - void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, - Message onComplete); - - /** - * getCallWaiting - * gets call waiting activation state. The return value of - * ((AsyncResult)onComplete.obj) is an array of int, with a length of 1. - * - * @param onComplete a callback message when the action is completed. - * @see com.android.internal.telephony.gsm.CommandsInterface.queryCallWaiting for details. - */ - void getCallWaiting(Message onComplete); - - /** - * setCallWaiting - * sets a call forwarding option. - * - * @param enable is a boolean representing the state that you are - * requesting, true for enabled, false for disabled. - * @param onComplete a callback message when the action is completed. - */ - void setCallWaiting(boolean enable, Message onComplete); - - /** - * Scan available networks. This method is asynchronous; . - * On completion, <code>response.obj</code> is set to an AsyncResult with - * one of the following members:.<p> - *<ul> - * <li><code>response.obj.result</code> will be a <code>List</code> of - * <code>com.android.internal.telephony.gsm.NetworkInfo</code> objects, or</li> - * <li><code>response.obj.exception</code> will be set with an exception - * on failure.</li> - * </ul> - */ - void getAvailableNetworks(Message response); - - /** - * Switches network selection mode to "automatic", re-scanning and - * re-selecting a network if appropriate. - * - * @param response The message to dispatch when the network selection - * is complete. - * - * @see #selectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo, - * android.os.Message ) - */ - void setNetworkSelectionModeAutomatic(Message response); - - /** - * Manually selects a network. <code>response</code> is - * dispatched when this is complete. <code>response.obj</code> will be - * an AsyncResult, and <code>response.obj.exception</code> will be non-null - * on failure. - * - * @see #setNetworkSelectionModeAutomatic(Message) - */ - void selectNetworkManually(NetworkInfo network, - Message response); - - /** - * Requests to set the preferred network type for searching and registering - * (CS/PS domain, RAT, and operation mode) - * @param networkType one of NT_*_TYPE - * @param response is callback message - */ - void setPreferredNetworkType(int networkType, Message response); - - /** - * Query the preferred network type setting - * - * @param response is callback message to report one of NT_*_TYPE - */ - void getPreferredNetworkType(Message response); - - /** - * Query neighboring cell IDs. <code>response</code> is dispatched when - * this is complete. <code>response.obj</code> will be an AsyncResult, - * and <code>response.obj.exception</code> will be non-null on failure. - * On success, <code>AsyncResult.result</code> will be a <code>String[]</code> - * containing the neighboring cell IDs. Index 0 will contain the count - * of available cell IDs. Cell IDs are in hexadecimal format. - * - * @param response callback message that is dispatched when the query - * completes. - */ - void getNeighboringCids(Message response); - - /** - * Sets an event to be fired when the telephony system processes - * a post-dial character on an outgoing call.<p> - * - * Messages of type <code>what</code> will be sent to <code>h</code>. - * The <code>obj</code> field of these Message's will be instances of - * <code>AsyncResult</code>. <code>Message.obj.result</code> will be - * a Connection object.<p> - * - * Message.arg1 will be the post dial character being processed, - * or 0 ('\0') if end of string.<p> - * - * If Connection.getPostDialState() == WAIT, - * the application must call - * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar() - * Connection.proceedAfterWaitChar()} or - * {@link com.android.internal.telephony.Connection#cancelPostDial() - * Connection.cancelPostDial()} - * for the telephony system to continue playing the post-dial - * DTMF sequence.<p> - * - * If Connection.getPostDialState() == WILD, - * the application must call - * {@link com.android.internal.telephony.Connection#proceedAfterWildChar - * Connection.proceedAfterWildChar()} - * or - * {@link com.android.internal.telephony.Connection#cancelPostDial() - * Connection.cancelPostDial()} - * for the telephony system to continue playing the - * post-dial DTMF sequence.<p> - * - * Only one post dial character handler may be set. <p> - * Calling this method with "h" equal to null unsets this handler.<p> - */ - void setOnPostDialCharacter(Handler h, int what, Object obj); - - - /** - * Mutes or unmutes the microphone for the active call. The microphone - * is automatically unmuted if a call is answered, dialed, or resumed - * from a holding state. - * - * @param muted true to mute the microphone, - * false to activate the microphone. - */ - - void setMute(boolean muted); - - /** - * Gets current mute status. Use - * {@link #registerForPhoneStateChanged(android.os.Handler, int, - * java.lang.Object) registerForPhoneStateChanged()} - * as a change notifcation, although presently phone state changed is not - * fired when setMute() is called. - * - * @return true is muting, false is unmuting - */ - boolean getMute(); - - /** - * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation. - * - * @param data The data for the request. - * @param response <strong>On success</strong>, - * (byte[])(((AsyncResult)response.obj).result) - * <strong>On failure</strong>, - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - * - * @see #invokeOemRilRequestRaw(byte[], android.os.Message) - */ - void invokeOemRilRequestRaw(byte[] data, Message response); - - /** - * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation. - * - * @param strings The strings to make available as the request data. - * @param response <strong>On success</strong>, "response" bytes is - * made available as: - * (String[])(((AsyncResult)response.obj).result). - * <strong>On failure</strong>, - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - * - * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message) - */ - void invokeOemRilRequestStrings(String[] strings, Message response); - - /** - * Get the current active PDP context list - * - * @param response <strong>On success</strong>, "response" bytes is - * made available as: - * (String[])(((AsyncResult)response.obj).result). - * <strong>On failure</strong>, - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - */ - void getPdpContextList(Message response); - - /** - * Get current mutiple PDP link status - * - * @return list of pdp link connections - */ - List<PdpConnection> getCurrentPdpList (); - - /** - * Udpate LAC and CID in service state for currnet GSM netowrk registration - * - * If get different LAC and/or CID, notifyServiceState will be sent - * - * @param - * <strong>On failure</strong>, - * (((AsyncResult)response.obj).result) == null and - * (((AsyncResult)response.obj).exception) being an instance of - * com.android.internal.telephony.gsm.CommandException - */ - void updateServiceLocation(Message response); - - /** - * Enable location update notifications. - */ - void enableLocationUpdates(); - - /** - * Disable location update notifications. - */ - void disableLocationUpdates(); - - /** - * For unit tests; don't send notifications to "Phone" - * mailbox registrants if true. - */ - void setUnitTestMode(boolean f); - - /** - * @return true If unit test mode is enabled - */ - boolean getUnitTestMode(); - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param response is callback message - */ - void setBandMode(int bandMode, Message response); - - /** - * Query the list of band mode supported by RF. - * - * @param response is callback message - * ((AsyncResult)response.obj).result is an int[] with every - * element representing one avialable BM_*_BAND - */ - void queryAvailableBandMode(Message response); - - /** - * @return true if enable data connection on roaming - */ - boolean getDataRoamingEnabled(); - - /** - * @param enable set true if enable data connection on roaming - */ - void setDataRoamingEnabled(boolean enable); - - /** - * If this is a simulated phone interface, returns a SimulatedRadioControl. - * @ return A SimulatedRadioControl if this is a simulated interface; - * otherwise, null. - */ - SimulatedRadioControl getSimulatedRadioControl(); - - /** - * Allow mobile data connections. - * @return {@code true} if the operation started successfully - * <br/>{@code false} if it - * failed immediately.<br/> - * Even in the {@code true} case, it may still fail later - * during setup, in which case an asynchronous indication will - * be supplied. - */ - boolean enableDataConnectivity(); - - /** - * Disallow mobile data connections, and terminate any that - * are in progress. - * @return {@code true} if the operation started successfully - * <br/>{@code false} if it - * failed immediately.<br/> - * Even in the {@code true} case, it may still fail later - * during setup, in which case an asynchronous indication will - * be supplied. - */ - boolean disableDataConnectivity(); - - /** - * Enables the specified APN type. Only works for "special" APN types, - * i.e., not the default APN. - * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}. - * @return <code>APN_ALREADY_ACTIVE</code> if the current APN - * services the requested type.<br/> - * <code>APN_TYPE_NOT_AVAILABLE</code> if the carrier does not - * support the requested APN.<br/> - * <code>APN_REQUEST_STARTED</code> if the request has been initiated.<br/> - * <code>APN_REQUEST_FAILED</code> if the request was invalid.<br/> - * A <code>ACTION_ANY_DATA_CONNECTION_STATE_CHANGED</code> broadcast will - * indicate connection state progress. - */ - int enableApnType(String type); - - /** - * Disables the specified APN type, and switches back to the default APN, - * if necessary. Switching to the default APN will not happen if default - * data traffic has been explicitly disabled via a call to {@link #disableDataConnectivity}. - * <p/>Only works for "special" APN types, - * i.e., not the default APN. - * @param type The desired APN type. Cannot be {@link #APN_TYPE_DEFAULT}. - * @return <code>APN_ALREADY_ACTIVE</code> if the default APN - * is already active.<br/> - * <code>APN_REQUEST_STARTED</code> if the request to switch to the default - * APN has been initiated.<br/> - * <code>APN_REQUEST_FAILED</code> if the request was invalid.<br/> - * A <code>ACTION_ANY_DATA_CONNECTION_STATE_CHANGED</code> broadcast will - * indicate connection state progress. - */ - int disableApnType(String type); - - /** - * Report on whether data connectivity is allowed. - */ - boolean isDataConnectivityPossible(); - - /** - * Returns the name of the network interface used by the specified APN type. - */ - String getInterfaceName(String apnType); - - /** - * Returns the IP address of the network interface used by the specified - * APN type. - */ - String getIpAddress(String apnType); - - /** - * Returns the gateway for the network interface used by the specified APN - * type. - */ - String getGateway(String apnType); - - /** - * Returns the DNS servers for the network interface used by the specified - * APN type. - */ - public String[] getDnsServers(String apnType); - - /** - * Retrieves the unique device ID, e.g., IMEI for GSM phones. - */ - String getDeviceId(); - - /** - * Retrieves the software version number for the device, e.g., IMEI/SV - * for GSM phones. - */ - String getDeviceSvn(); - - /** - * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones. - */ - String getSubscriberId(); - - /** - * Retrieves the serial number of the SIM, if applicable. - */ - String getSimSerialNumber(); -} diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java deleted file mode 100644 index 580814f..0000000 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 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; - -import android.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.RegistrantList; -import android.telephony.ServiceState; -import com.android.internal.telephony.test.SimulatedRadioControl; - -import java.util.List; - -/** - * (<em>Not for SDK use</em>) - * A base implementation for the com.android.internal.telephony.Phone interface. - * - * Note that implementations of Phone.java are expected to be used - * from a single application thread. This should be the same thread that - * originally called PhoneFactory to obtain the interface. - * - * {@hide} - * - */ - -public abstract class PhoneBase implements Phone { - private static final String LOG_TAG = "GSM"; - - protected final RegistrantList mPhoneStateRegistrants - = new RegistrantList(); - - protected final RegistrantList mNewRingingConnectionRegistrants - = new RegistrantList(); - - protected final RegistrantList mIncomingRingRegistrants - = new RegistrantList(); - - protected final RegistrantList mDisconnectRegistrants - = new RegistrantList(); - - protected final RegistrantList mServiceStateRegistrants - = new RegistrantList(); - - protected final RegistrantList mMmiCompleteRegistrants - = new RegistrantList(); - - protected final RegistrantList mMmiRegistrants - = new RegistrantList(); - - protected final RegistrantList mUnknownConnectionRegistrants - = new RegistrantList(); - - protected final RegistrantList mSuppServiceFailedRegistrants - = new RegistrantList(); - - protected Looper mLooper; /* to insure registrants are in correct thread*/ - - protected Context mContext; - - /** - * PhoneNotifier is an abstraction for all system-wide - * state change notification. DefaultPhoneNotifier is - * used here unless running we're inside a unit test. - */ - protected PhoneNotifier mNotifier; - - protected SimulatedRadioControl mSimulatedRadioControl; - - boolean mUnitTestMode; - - /** - * Constructs a PhoneBase in normal (non-unit test) mode. - * - * @param context Context object from hosting application - * @param notifier An instance of DefaultPhoneNotifier, - * unless unit testing. - */ - protected PhoneBase(PhoneNotifier notifier, Context context) { - this(notifier, context, false); - } - - /** - * Constructs a PhoneBase in normal (non-unit test) mode. - * - * @param context Context object from hosting application - * @param notifier An instance of DefaultPhoneNotifier, - * unless unit testing. - * @param unitTestMode when true, prevents notifications - * of state change events - */ - protected PhoneBase(PhoneNotifier notifier, Context context, - boolean unitTestMode) { - this.mNotifier = notifier; - this.mContext = context; - mLooper = Looper.myLooper(); - - setUnitTestMode(unitTestMode); - } - - // Inherited documentation suffices. - public Context getContext() { - return mContext; - } - - // Inherited documentation suffices. - public void registerForPhoneStateChanged(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mPhoneStateRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForPhoneStateChanged(Handler h) { - mPhoneStateRegistrants.remove(h); - } - - /** - * Notify registrants of a PhoneStateChanged. - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyCallStateChangedP() { - AsyncResult ar = new AsyncResult(null, this, null); - mPhoneStateRegistrants.notifyRegistrants(ar); - } - - // Inherited documentation suffices. - public void registerForUnknownConnection(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mUnknownConnectionRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForUnknownConnection(Handler h) { - mUnknownConnectionRegistrants.remove(h); - } - - // Inherited documentation suffices. - public void registerForNewRingingConnection( - Handler h, int what, Object obj) { - checkCorrectThread(h); - - mNewRingingConnectionRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForNewRingingConnection(Handler h) { - mNewRingingConnectionRegistrants.remove(h); - } - - /** - * Notifiy registrants of a new ringing Connection. - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyNewRingingConnectionP(Connection cn) { - AsyncResult ar = new AsyncResult(null, cn, null); - mNewRingingConnectionRegistrants.notifyRegistrants(ar); - } - - // Inherited documentation suffices. - public void registerForIncomingRing( - Handler h, int what, Object obj) { - checkCorrectThread(h); - - mIncomingRingRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForIncomingRing(Handler h) { - mIncomingRingRegistrants.remove(h); - } - - // Inherited documentation suffices. - public void registerForDisconnect(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mDisconnectRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForDisconnect(Handler h) { - mDisconnectRegistrants.remove(h); - } - - // Inherited documentation suffices. - public void registerForSuppServiceFailed(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mSuppServiceFailedRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForSuppServiceFailed(Handler h) { - mSuppServiceFailedRegistrants.remove(h); - } - - // Inherited documentation suffices. - public void registerForMmiInitiate(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mMmiRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForMmiInitiate(Handler h) { - mMmiRegistrants.remove(h); - } - - // Inherited documentation suffices. - public void registerForMmiComplete(Handler h, int what, Object obj) { - checkCorrectThread(h); - - mMmiCompleteRegistrants.addUnique(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForMmiComplete(Handler h) { - checkCorrectThread(h); - - mMmiCompleteRegistrants.remove(h); - } - - /** - * Subclasses should override this. See documentation in superclass. - */ - public abstract List getPendingMmiCodes(); - - // Inherited documentation suffices. - public void setUnitTestMode(boolean f) { - mUnitTestMode = f; - } - - // Inherited documentation suffices. - public boolean getUnitTestMode() { - return mUnitTestMode; - } - - /** - * To be invoked when a voice call Connection disconnects. - * - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyDisconnectP(Connection cn) { - AsyncResult ar = new AsyncResult(null, cn, null); - mDisconnectRegistrants.notifyRegistrants(ar); - } - - // Inherited documentation suffices. - public void registerForServiceStateChanged( - Handler h, int what, Object obj) { - checkCorrectThread(h); - - mServiceStateRegistrants.add(h, what, obj); - } - - // Inherited documentation suffices. - public void unregisterForServiceStateChanged(Handler h) { - mServiceStateRegistrants.remove(h); - } - - /** - * Subclasses of Phone probably want to replace this with a - * version scoped to their packages - */ - protected void notifyServiceStateChangedP(ServiceState ss) { - AsyncResult ar = new AsyncResult(null, ss, null); - mServiceStateRegistrants.notifyRegistrants(ar); - - mNotifier.notifyServiceState(this); - } - - // Inherited documentation suffices. - public SimulatedRadioControl getSimulatedRadioControl() { - return mSimulatedRadioControl; - } - - /** - * Verifies the current thread is the same as the thread originally - * used in the initialization of this instance. Throws RuntimeException - * if not. - * - * @exception RuntimeException if the current thread is not - * the thread that originally obtained this PhoneBase instance. - */ - private void checkCorrectThread(Handler h) { - if (h.getLooper() != mLooper) { - throw new RuntimeException( - "com.android.internal.telephony.Phone must be used from within one thread"); - } - } - -} diff --git a/telephony/java/com/android/internal/telephony/PhoneFactory.java b/telephony/java/com/android/internal/telephony/PhoneFactory.java deleted file mode 100644 index 0ca5f45..0000000 --- a/telephony/java/com/android/internal/telephony/PhoneFactory.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import java.util.ArrayList; -import java.util.List; -import java.io.IOException; -import java.net.InetSocketAddress; - -import java.util.Collections; - -import android.util.Log; -import com.android.internal.telephony.gsm.GSMPhone; -import com.android.internal.telephony.gsm.RIL; -import com.android.internal.telephony.test.ModelInterpreter; -import com.android.internal.telephony.test.SimulatedCommands; -import android.os.Looper; -import android.os.SystemProperties; -import android.content.Context; -import android.content.Intent; -import android.net.LocalServerSocket; -import android.app.ActivityManagerNative; - -/** - * {@hide} - */ -public class PhoneFactory -{ - static final String LOG_TAG="GSM"; - - static final int SOCKET_OPEN_RETRY_MILLIS = 2 * 1000; - static final int SOCKET_OPEN_MAX_RETRY = 3; - //***** Class Variables - - static private ArrayList<Phone> sPhones = new ArrayList<Phone>(); - - static private boolean sMadeDefaults = false; - static private PhoneNotifier sPhoneNotifier; - static private Looper sLooper; - - static private Object testMailbox; - - //***** Class Methods - - private static void - useNewRIL(Context context) - { - ModelInterpreter mi = null; - GSMPhone phone; - - try { - if (false) { - mi = new ModelInterpreter(new InetSocketAddress("127.0.0.1", 6502)); - } - - phone = new GSMPhone(context, new RIL(context), sPhoneNotifier); - - registerPhone (phone); - } catch (IOException ex) { - Log.e(LOG_TAG, "Error creating ModelInterpreter", ex); - } - } - - - /** - * FIXME replace this with some other way of making these - * instances - */ - public static void - makeDefaultPhones(Context context) - { - synchronized(Phone.class) { - if (!sMadeDefaults) { - sLooper = Looper.myLooper(); - - if (sLooper == null) { - throw new RuntimeException( - "PhoneFactory.makeDefaultPhones must be called from Looper thread"); - } - - int retryCount = 0; - for(;;) { - boolean hasException = false; - retryCount ++; - - try { - // use UNIX domain socket to - // prevent subsequent initialization - new LocalServerSocket("com.android.internal.telephony"); - } catch (java.io.IOException ex) { - hasException = true; - } - - if ( !hasException ) { - break; - } else if (retryCount > SOCKET_OPEN_MAX_RETRY) { - throw new RuntimeException("PhoneFactory probably already running"); - }else { - try { - Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); - } catch (InterruptedException er) { - } - } - } - - sPhoneNotifier = new DefaultPhoneNotifier(); - - if ((SystemProperties.get("ro.radio.noril","")).equals("")) { - useNewRIL(context); - } else { - GSMPhone phone; - phone = new GSMPhone(context, new SimulatedCommands(), sPhoneNotifier); - registerPhone (phone); - } - - sMadeDefaults = true; - } - } - } - - public static Phone getDefaultPhone() - { - if (!sMadeDefaults) { - throw new IllegalStateException("Default phones haven't been made yet!"); - } - - if (sLooper != Looper.myLooper()) { - throw new RuntimeException( - "PhoneFactory.getDefaultPhone must be called from Looper thread"); - } - - synchronized (sPhones) { - return sPhones.isEmpty() ? null : sPhones.get(0); - } - } - - public static void registerPhone(Phone p) - { - if (sLooper != Looper.myLooper()) { - throw new RuntimeException( - "PhoneFactory.getDefaultPhone must be called from Looper thread"); - } - synchronized (sPhones) { - sPhones.add(p); - } - } -} - diff --git a/telephony/java/com/android/internal/telephony/PhoneNotifier.java b/telephony/java/com/android/internal/telephony/PhoneNotifier.java deleted file mode 100644 index e96eeae..0000000 --- a/telephony/java/com/android/internal/telephony/PhoneNotifier.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public interface PhoneNotifier { - - public void notifyPhoneState(Phone sender); - - public void notifyServiceState(Phone sender); - - public void notifyCellLocation(Phone sender); - - public void notifySignalStrength(Phone sender); - - public void notifyMessageWaitingChanged(Phone sender); - - public void notifyCallForwardingChanged(Phone sender); - - public void notifyDataConnection(Phone sender, String reason); - - public void notifyDataConnectionFailed(Phone sender, String reason); - - public void notifyDataActivity(Phone sender); - -} diff --git a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java b/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java deleted file mode 100644 index 61d4c9f..0000000 --- a/telephony/java/com/android/internal/telephony/PhoneStateIntentReceiver.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.os.Message; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.util.Log; - -/** - * - * DO NOT USE THIS CLASS: - * - * Use android.telephony.TelephonyManager and PhoneStateListener instead. - * - * - */ -@Deprecated -public final class PhoneStateIntentReceiver extends BroadcastReceiver { - private static final String LOG_TAG = "PhoneStateIntRecv"; - private static final boolean DBG = false; - - public static final String INTENT_KEY_ASU = "asu"; - - private static final int NOTIF_PHONE = 1 << 0; - private static final int NOTIF_SERVICE = 1 << 1; - private static final int NOTIF_SIGNAL = 1 << 2; - - private static final int NOTIF_MAX = 1 << 5; - - Phone.State mPhoneState = Phone.State.IDLE; - ServiceState mServiceState = new ServiceState(); - int mAsu = -1; - private Context mContext; - private Handler mTarget; - private IntentFilter mFilter; - private int mWants; - private int mPhoneStateEventWhat; - private int mServiceStateEventWhat; - private int mLocationEventWhat; - private int mAsuEventWhat; - - public PhoneStateIntentReceiver() { - super(); - mFilter = new IntentFilter(); - } - - public PhoneStateIntentReceiver(Context context, Handler target) { - this(); - setContext(context); - setTarget(target); - } - - public void setContext(Context c) { - mContext = c; - } - - public void setTarget(Handler h) { - mTarget = h; - } - - public Phone.State getPhoneState() { - if ((mWants & NOTIF_PHONE) == 0) { - throw new RuntimeException - ("client must call notifyPhoneCallState(int)"); - } - return mPhoneState; - } - - public ServiceState getServiceState() { - if ((mWants & NOTIF_SERVICE) == 0) { - throw new RuntimeException - ("client must call notifyServiceState(int)"); - } - return mServiceState; - } - - /** - * Returns current signal strength in "asu", ranging from 0-31 - * or -1 if unknown - * - * For GSM, dBm = -113 + 2*asu - * 0 means "-113 dBm or less" - * 31 means "-51 dBm or greater" - * - * @return signal strength in asu, -1 if not yet updated - * Throws RuntimeException if client has not called notifySignalStrength() - */ - public int getSignalStrength() { - if ((mWants & NOTIF_SIGNAL) == 0) { - throw new RuntimeException - ("client must call notifySignalStrength(int)"); - } - - return mAsu; - } - - /** - * Return current signal strength in "dBm", ranging from -113 - -51dBm - * or -1 if unknown - * - * @return signal strength in dBm, -1 if not yet updated - * Throws RuntimeException if client has not called notifySignalStrength() - */ - public int getSignalStrengthDbm() { - if ((mWants & NOTIF_SIGNAL) == 0) { - throw new RuntimeException - ("client must call notifySignalStrength(int)"); - } - - int dBm = -1; - - if (mAsu != -1) { - dBm = -113 + 2*mAsu; - } - - return dBm; - } - - public void notifyPhoneCallState(int eventWhat) { - mWants |= NOTIF_PHONE; - mPhoneStateEventWhat = eventWhat; - mFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); - } - - public boolean getNotifyPhoneCallState() { - return ((mWants & NOTIF_PHONE) != 0); - } - - public void notifyServiceState(int eventWhat) { - mWants |= NOTIF_SERVICE; - mServiceStateEventWhat = eventWhat; - mFilter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED); - } - - public boolean getNotifyServiceState() { - return ((mWants & NOTIF_SERVICE) != 0); - } - - public void notifySignalStrength (int eventWhat) { - mWants |= NOTIF_SIGNAL; - mAsuEventWhat = eventWhat; - mFilter.addAction(TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED); - } - - public boolean getNotifySignalStrength() { - return ((mWants & NOTIF_SIGNAL) != 0); - } - - public void registerIntent() { - mContext.registerReceiver(this, mFilter); - } - - public void unregisterIntent() { - mContext.unregisterReceiver(this); - } - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - try { - if (TelephonyIntents.ACTION_SIGNAL_STRENGTH_CHANGED.equals(action)) { - mAsu = intent.getIntExtra(INTENT_KEY_ASU, mAsu); - if (DBG) Log.d(LOG_TAG, "onReceiveIntent: set asu=" + mAsu); - - if (mTarget != null && getNotifySignalStrength()) { - Message message = Message.obtain(mTarget, mAsuEventWhat); - mTarget.sendMessage(message); - } - } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) { - if (DBG) Log.d(LOG_TAG, "onReceiveIntent: ACTION_PHONE_STATE_CHANGED, state=" - + intent.getStringExtra(Phone.STATE_KEY)); - String phoneState = intent.getStringExtra(Phone.STATE_KEY); - mPhoneState = (Phone.State) Enum.valueOf( - Phone.State.class, phoneState); - - if (mTarget != null && getNotifyPhoneCallState()) { - Message message = Message.obtain(mTarget, - mPhoneStateEventWhat); - mTarget.sendMessage(message); - } - } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) { - mServiceState = ServiceState.newFromBundle(intent.getExtras()); - - if (mTarget != null && getNotifyServiceState()) { - Message message = Message.obtain(mTarget, - mServiceStateEventWhat); - mTarget.sendMessage(message); - } - } - } catch (Exception ex) { - Log.e(LOG_TAG, "[PhoneStateIntentRecv] caught " + ex); - ex.printStackTrace(); - } - } - -} diff --git a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java b/telephony/java/com/android/internal/telephony/PhoneSubInfo.java deleted file mode 100644 index 644d1f4..0000000 --- a/telephony/java/com/android/internal/telephony/PhoneSubInfo.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.android.internal.telephony; - -import android.content.Context; -import android.os.ServiceManager; -import com.android.internal.telephony.*; - -public class PhoneSubInfo extends IPhoneSubInfo.Stub { - private Phone mPhone; - private Context mContext; - private static final String READ_PHONE_STATE = - android.Manifest.permission.READ_PHONE_STATE; - - public PhoneSubInfo(Phone phone) { - mPhone = phone; - mContext = phone.getContext(); - ServiceManager.addService("iphonesubinfo", this); - } - /** - * Retrieves the unique device ID, e.g., IMEI for GSM phones. - */ - public String getDeviceId() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getDeviceId(); - } - - /** - * Retrieves the software version number for the device, e.g., IMEI/SV - * for GSM phones. - */ - public String getDeviceSvn() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getDeviceSvn(); - } - - /** - * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones. - */ - public String getSubscriberId() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getSubscriberId(); - } - - /** - * Retrieves the serial number of the SIM, if applicable. - */ - public String getSimSerialNumber() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getSimSerialNumber(); - } - - /** - * Retrieves the phone number string for line 1. - */ - public String getLine1Number() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return mPhone.getLine1Number(); - } - - /** - * Retrieves the alpha identifier for line 1. - */ - public String getLine1AlphaTag() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return (String) mPhone.getLine1AlphaTag(); - } - - /** - * Retrieves the voice mail number. - */ - public String getVoiceMailNumber() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return (String) mPhone.getVoiceMailNumber(); - } - - /** - * Retrieves the alpha identifier associated with the voice mail number. - */ - public String getVoiceMailAlphaTag() { - mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, "Requires READ_PHONE_STATE"); - return (String) mPhone.getVoiceMailAlphaTag(); - } -} diff --git a/telephony/java/com/android/internal/telephony/SimCard.java b/telephony/java/com/android/internal/telephony/SimCard.java deleted file mode 100644 index 03b366f..0000000 --- a/telephony/java/com/android/internal/telephony/SimCard.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import android.os.Message; -import android.os.Handler; - -/** - * {@hide} - */ -public interface SimCard -{ - /* The extra data for broacasting intent INTENT_SIM_STATE_CHANGE */ - static public final String INTENT_KEY_SIM_STATE = "ss"; - /* NOT_READY means the SIM interface is not ready (eg, radio is off or powering on) */ - static public final String INTENT_VALUE_SIM_NOT_READY = "NOT_READY"; - /* ABSENT means SIM is missing */ - static public final String INTENT_VALUE_SIM_ABSENT = "ABSENT"; - /* LOCKED means SIM is locked by pin or by network */ - static public final String INTENT_VALUE_SIM_LOCKED = "LOCKED"; - /* READY means SIM is ready to access */ - static public final String INTENT_VALUE_SIM_READY = "READY"; - /* IMSI means SIM IMSI is ready in property */ - static public final String INTENT_VALUE_SIM_IMSI = "IMSI"; - /* LOADED means all SIM records, including IMSI, are loaded */ - static public final String INTENT_VALUE_SIM_LOADED = "LOADED"; - /* The extra data for broacasting intent INTENT_SIM_STATE_CHANGE */ - static public final String INTENT_KEY_LOCKED_REASON = "reason"; - /* PIN means SIM is locked on PIN1 */ - static public final String INTENT_VALUE_LOCKED_ON_PIN = "PIN"; - /* PUK means SIM is locked on PUK1 */ - static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK"; - /* NETWORK means SIM is locked on NETWORK PERSONALIZATION */ - static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK"; - - - /* - UNKNOWN is a transient state, for example, after uesr inputs sim pin under - PIN_REQUIRED state, the query for sim status returns UNKNOWN before it - turns to READY - */ - public enum State { - UNKNOWN, - ABSENT, - PIN_REQUIRED, - PUK_REQUIRED, - NETWORK_LOCKED, - READY; - - public boolean isPinLocked() { - return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)); - } - } - - State getState(); - - - /** - * Notifies handler of any transition into State.ABSENT - */ - void registerForAbsent(Handler h, int what, Object obj); - void unregisterForAbsent(Handler h); - - /** - * Notifies handler of any transition into State.isPinLocked() - */ - void registerForLocked(Handler h, int what, Object obj); - void unregisterForLocked(Handler h); - - /** - * Notifies handler of any transition into State.NETWORK_LOCKED - */ - void registerForNetworkLocked(Handler h, int what, Object obj); - void unregisterForNetworkLocked(Handler h); - - /** - * Supply the SIM PIN to the SIM - * - * When the operation is complete, onComplete will be sent to it's - * Handler. - * - * onComplete.obj will be an AsyncResult - * - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - * - * If the supplied PIN is incorrect: - * ((AsyncResult)onComplete.obj).exception != null - * && ((AsyncResult)onComplete.obj).exception - * instanceof com.android.internal.telephony.gsm.CommandException) - * && ((CommandException)(((AsyncResult)onComplete.obj).exception)) - * .getCommandError() == CommandException.Error.PASSWORD_INCORRECT - * - * - */ - - void supplyPin (String pin, Message onComplete); - void supplyPuk (String puk, String newPin, Message onComplete); - void supplyPin2 (String pin2, Message onComplete); - void supplyPuk2 (String puk2, String newPin2, Message onComplete); - - /** - * Check whether sim pin lock is enabled - * This is a sync call which returns the cached pin enabled state - * - * @return true for sim locked enabled - * false for sim locked disabled - */ - boolean getSimLockEnabled (); - - /** - * Set the sim pin lock enabled or disabled - * When the operation is complete, onComplete will be sent to its handler - * - * @param enabled "true" for locked "false" for unlocked. - * @param password needed to change the sim pin state, aka. Pin1 - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - void setSimLockEnabled(boolean enabled, String password, Message onComplete); - - - /** - * Change the sim password used in sim pin lock - * When the operation is complete, onComplete will be sent to its handler - * - * @param oldPassword is the old password - * @param newPassword is the new password - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - void changeSimLockPassword(String oldPassword, String newPassword, - Message onComplete); - - /** - * Check whether sim fdn (fixed dialing number) is enabled - * This is a sync call which returns the cached pin enabled state - * - * @return true for sim fdn enabled - * false for sim fdn disabled - */ - boolean getSimFdnEnabled (); - - /** - * Set the sim fdn enabled or disabled - * When the operation is complete, onComplete will be sent to its handler - * - * @param enabled "true" for locked "false" for unlocked. - * @param password needed to change the sim fdn enable, aka Pin2 - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - void setSimFdnEnabled(boolean enabled, String password, Message onComplete); - - /** - * Change the sim password used in sim fdn enable - * When the operation is complete, onComplete will be sent to its handler - * - * @param oldPassword is the old password - * @param newPassword is the new password - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - void changeSimFdnPassword(String oldPassword, String newPassword, - Message onComplete); - - void supplyNetworkDepersonalization (String pin, Message onComplete); - - /** - * Returns service provider name stored in SIM card. - * If there is no service provider name associated or the record is not - * yet available, null will be returned <p> - * - * Please use this value when display Service Provider Name in idle mode <p> - * - * Usage of this provider name in the UI is a common carrier requirement. - * - * Also available via Android property "gsm.sim.operator.alpha" - * - * @return Service Provider Name stored in SIM card - * null if no service provider name associated or the record is not - * yet available - * - */ - String getServiceProviderName(); -} diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java deleted file mode 100644 index 9219e7a..0000000 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ /dev/null @@ -1,151 +0,0 @@ -package com.android.internal.telephony; - -/** - * The intents that the telephony services broadcast. - * - * <p class="warning"> - * THESE ARE NOT THE API! Use the {@link android.telephony.TelephonyManager} class. - * DON'T LISTEN TO THESE DIRECTLY. - */ -public class TelephonyIntents { - - /** - * Broadcast Action: The phone service state has changed. The intent will have the following - * extra values:</p> - * <ul> - * <li><em>state</em> - An int with one of the following values: - * {@link android.telephony.ServiceState#STATE_IN_SERVICE}, - * {@link android.telephony.ServiceState#STATE_OUT_OF_SERVICE}, - * {@link android.telephony.ServiceState#STATE_EMERGENCY_ONLY} - * or {@link android.telephony.ServiceState#STATE_POWER_OFF} - * <li><em>roaming</em> - A boolean value indicating whether the phone is roaming.</li> - * <li><em>operator-alpha-long</em> - The carrier name as a string.</li> - * <li><em>operator-alpha-short</em> - A potentially shortened version of the carrier name, - * as a string.</li> - * <li><em>operator-numeric</em> - A number representing the carrier, as a string. This is - * a five or six digit number consisting of the MCC (Mobile Country Code, 3 digits) - * and MNC (Mobile Network code, 2-3 digits).</li> - * <li><em>manual</em> - A boolean, where true indicates that the user has chosen to select - * the network manually, and false indicates that network selection is handled by the - * phone.</li> - * </ul> - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - */ - public static final String ACTION_SERVICE_STATE_CHANGED = "android.intent.action.SERVICE_STATE"; - - - /** - * Broadcast Action: The phone's signal strength has changed. The intent will have the - * following extra values:</p> - * <ul> - * <li><em>phoneName</em> - A string version of the phone name.</li> - * <li><em>asu</em> - A numeric value for the signal strength. - * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu). - * The following special values are defined: - * <ul><li>0 means "-113 dBm or less".</li><li>31 means "-51 dBm or greater".</li></ul> - * </li> - * </ul> - * - * <p class="note"> - * You can <em>not</em> receive this through components declared - * in manifests, only by exlicitly registering for it with - * {@link android.content.Context#registerReceiver(android.content.BroadcastReceiver, - * android.content.IntentFilter) Context.registerReceiver()}. - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - */ - public static final String ACTION_SIGNAL_STRENGTH_CHANGED = "android.intent.action.SIG_STR"; - - - /** - * Broadcast Action: The data connection state has changed for any one of the - * phone's mobile data connections (eg, default, MMS or GPS specific connection). - * The intent will have the following extra values:</p> - * <ul> - * <li><em>phoneName</em> - A string version of the phone name.</li> - * <li><em>state</em> - One of <code>"CONNECTED"</code> - * <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li> - * <li><em>apn</em> - A string that is the APN associated with this - * connection.</li> - * <li><em>apnType</em> - A string array of APN types associated with - * this connection. The APN type <code>"*"</code> is a special - * type that means this APN services all types.</li> - * </ul> - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - */ - public static final String ACTION_ANY_DATA_CONNECTION_STATE_CHANGED - = "android.intent.action.ANY_DATA_STATE"; - - - /** - * Broadcast Action: An attempt to establish a data connection has failed. - * The intent will have the following extra values:</p> - * <ul> - * <li><em>phoneName</em> &mdash A string version of the phone name.</li> - * <li><em>state</em> — One of <code>"CONNECTED"</code> - * <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li> - * <li><em>reason</em> — A string indicating the reason for the failure, if available</li> - * </ul> - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - */ - public static final String ACTION_DATA_CONNECTION_FAILED - = "android.intent.action.DATA_CONNECTION_FAILED"; - - - /** - * Broadcast Action: The sim card state has changed. - * The intent will have the following extra values:</p> - * <ul> - * <li><em>phoneName</em> - A string version of the phone name.</li> - * <li><em>ss</em> - The sim state. One of - * <code>"ABSENT"</code> <code>"LOCKED"</code> - * <code>"READY"</code> <code>"ISMI"</code> <code>"LOADED"</code> </li> - * <li><em>reason</em> - The reason while ss is LOCKED, otherwise is null - * <code>"PIN"</code> locked on PIN1 - * <code>"PUK"</code> locked on PUK1 - * <code>"NETWORK"</code> locked on Network Personalization </li> - * </ul> - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - */ - public static final String ACTION_SIM_STATE_CHANGED - = "android.intent.action.SIM_STATE_CHANGED"; - - - /** - * Broadcast Action: The time was set by the carrier (typically by the NITZ string). - * This is a sticky broadcast. - * The intent will have the following extra values:</p> - * <ul> - * <li><em>time</em> - The time as a long in UTC milliseconds.</li> - * </ul> - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - */ - public static final String ACTION_NETWORK_SET_TIME = "android.intent.action.NETWORK_SET_TIME"; - - - /** - * Broadcast Action: The timezone was set by the carrier (typically by the NITZ string). - * This is a sticky broadcast. - * The intent will have the following extra values:</p> - * <ul> - * <li><em>time-zone</em> - The java.util.TimeZone.getID() value identifying the new time - * zone.</li> - * </ul> - * - * <p class="note"> - * Requires the READ_PHONE_STATE permission. - */ - public static final String ACTION_NETWORK_SET_TIMEZONE - = "android.intent.action.NETWORK_SET_TIMEZONE"; -} diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java deleted file mode 100644 index 6aa90f1..0000000 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * Contains a list of string constants used to get or set telephone properties - * in the system. You can use {@link android.os.SystemProperties os.SystemProperties} - * to get and set these values. - * @hide - */ -public interface TelephonyProperties -{ - //****** Baseband and Radio Interface version - - /** - * Baseband version - * Availability: property is available any time radio is on - */ - static final String PROPERTY_BASEBAND_VERSION = "gsm.version.baseband"; - - /** Radio Interface Layer (RIL) library implementation. */ - static final String PROPERTY_RIL_IMPL = "gsm.version.ril-impl"; - - //****** Current Network - - /** Alpha name of current registered operator. - * Availability: when registered to a network - */ - static final String PROPERTY_OPERATOR_ALPHA = "gsm.operator.alpha"; - - /** Numeric name (MCC+MNC) of current registered operator. - * Availability: when registered to a network - */ - static final String PROPERTY_OPERATOR_NUMERIC = "gsm.operator.numeric"; - - /** 'true' if the device is considered roaming on this network for GSM - * purposes. - * Availability: when registered to a network - */ - static final String PROPERTY_OPERATOR_ISROAMING = "gsm.operator.isroaming"; - - /** The ISO country code equivalent of the current registered operator's - * MCC (Mobile Country Code) - * Availability: when registered to a network - */ - static final String PROPERTY_OPERATOR_ISO_COUNTRY = "gsm.operator.iso-country"; - - //****** SIM Card - /** - * One of <code>"UNKNOWN"</code> <code>"ABSENT"</code> <code>"PIN_REQUIRED"</code> - * <code>"PUK_REQUIRED"</code> <code>"NETWORK_LOCKED"</code> or <code>"READY"</code> - */ - static String PROPERTY_SIM_STATE = "gsm.sim.state"; - - /** The MCC+MNC (mobile country code+mobile network code) of the - * provider of the SIM. 5 or 6 decimal digits. - * Availablity: SIM state must be "READY" - */ - static String PROPERTY_SIM_OPERATOR_NUMERIC = "gsm.sim.operator.numeric"; - - /** PROPERTY_SIM_OPERATOR_ALPHA is also known as the SPN, or Service Provider Name. - * Availablity: SIM state must be "READY" - */ - static String PROPERTY_SIM_OPERATOR_ALPHA = "gsm.sim.operator.alpha"; - - /** ISO country code equivalent for the SIM provider's country code*/ - static String PROPERTY_SIM_OPERATOR_ISO_COUNTRY = "gsm.sim.operator.iso-country"; - - /** - * Indicates the available radio technology. Values include: <code>"unknown"</code>, - * <code>"GPRS"</code>, <code>"EDGE"</code> and <code>"UMTS"</code>. - */ - static String PROPERTY_DATA_NETWORK_TYPE = "gsm.network.type"; - -} diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java deleted file mode 100644 index 66fa943..0000000 --- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2008 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; - -import android.content.Intent; -import android.provider.Telephony.Sms.Intents; -import android.util.Config; -import android.util.Log; -import com.android.internal.telephony.gsm.GSMPhone; -import com.android.internal.telephony.gsm.SimUtils; - - -/** - * WAP push handler class. - * - * @hide - */ -public class WapPushOverSms { - private static final String LOG_TAG = "WAP PUSH"; - - private final GSMPhone mPhone; - private WspTypeDecoder pduDecoder; - - - public WapPushOverSms(GSMPhone phone) { - mPhone = phone; - } - - /** - * Dispatches inbound messages that are in the WAP PDU format. See - * wap-230-wsp-20010705-a section 8 for details on the WAP PDU format. - * - * @param pdu The WAP PDU, made up of one or more SMS PDUs - */ - public void dispatchWapPdu(byte[] pdu) { - - if (Config.LOGD) Log.d(LOG_TAG, "Rx: " + SimUtils.bytesToHexString(pdu)); - - int index = 0; - int transactionId = pdu[index++] & 0xFF; - int pduType = pdu[index++] & 0xFF; - int headerLength = 0; - - if ((pduType != WspTypeDecoder.PDU_TYPE_PUSH) && - (pduType != WspTypeDecoder.PDU_TYPE_CONFIRMED_PUSH)) { - if (Config.LOGD) Log.w(LOG_TAG, "Received non-PUSH WAP PDU. Type = " + pduType); - return; - } - - pduDecoder = new WspTypeDecoder(pdu); - - /** - * Parse HeaderLen(unsigned integer). - * From wap-230-wsp-20010705-a section 8.1.2 - * The maximum size of a uintvar is 32 bits. - * So it will be encoded in no more than 5 octets. - */ - if (pduDecoder.decodeUintvarInteger(index) == false) { - if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Length error."); - return; - } - headerLength = (int)pduDecoder.getValue32(); - index += pduDecoder.getDecodedDataLength(); - - int headerStartIndex = index; - - /** - * Parse Content-Type. - * From wap-230-wsp-20010705-a section 8.4.2.24 - * - * Content-type-value = Constrained-media | Content-general-form - * Content-general-form = Value-length Media-type - * Media-type = (Well-known-media | Extension-Media) *(Parameter) - * Value-length = Short-length | (Length-quote Length) - * Short-length = <Any octet 0-30> (octet <= WAP_PDU_SHORT_LENGTH_MAX) - * Length-quote = <Octet 31> (WAP_PDU_LENGTH_QUOTE) - * Length = Uintvar-integer - */ - if (pduDecoder.decodeContentType(index) == false) { - if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Header Content-Type error."); - return; - } - int binaryContentType; - String mimeType = pduDecoder.getValueString(); - if (mimeType == null) { - binaryContentType = (int)pduDecoder.getValue32(); - switch (binaryContentType) { - case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML: - mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML; - break; - case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML: - mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML; - break; - case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI: - mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI; - break; - case WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL: - mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL; - break; - case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO: - mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO; - break; - case WspTypeDecoder.CONTENT_TYPE_B_MMS: - mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS; - break; - default: - if (Config.LOGD) { - Log.w(LOG_TAG, - "Received PDU. Unsupported Content-Type = " + binaryContentType); - } - return; - } - } else { - if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML)) { - binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML; - } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML)) { - binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_WBXML; - } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SI)) { - binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SI; - } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_SL)) { - binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_SL; - } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO)) { - binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO; - } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS)) { - binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS; - } else { - if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType); - return; - } - } - index += pduDecoder.getDecodedDataLength(); - - int dataIndex = headerStartIndex + headerLength; - boolean dispatchedByApplication = false; - switch (binaryContentType) { - case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO: - dispatchWapPdu_PushCO(pdu, transactionId, pduType); - dispatchedByApplication = true; - break; - case WspTypeDecoder.CONTENT_TYPE_B_MMS: - dispatchWapPdu_MMS(pdu, transactionId, pduType, dataIndex); - dispatchedByApplication = true; - break; - default: - break; - } - if (dispatchedByApplication == false) { - dispatchWapPdu_default(pdu, transactionId, pduType, mimeType, dataIndex); - } - } - - - - private void dispatchWapPdu_default( - byte[] pdu, int transactionId, int pduType, String mimeType, int dataIndex) { - byte[] data; - - data = new byte[pdu.length - dataIndex]; - System.arraycopy(pdu, dataIndex, data, 0, data.length); - - Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); - intent.setType(mimeType); - intent.putExtra("transactionId", transactionId); - intent.putExtra("pduType", pduType); - intent.putExtra("data", data); - - mPhone.getContext().sendBroadcast( - intent, "android.permission.RECEIVE_WAP_PUSH"); - } - - private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType) { - Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); - intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO); - intent.putExtra("transactionId", transactionId); - intent.putExtra("pduType", pduType); - intent.putExtra("data", pdu); - - mPhone.getContext().sendBroadcast( - intent, "android.permission.RECEIVE_WAP_PUSH"); - } - - private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType, int dataIndex) { - byte[] data; - - data = new byte[pdu.length - dataIndex]; - System.arraycopy(pdu, dataIndex, data, 0, data.length); - - Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION); - intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS); - intent.putExtra("transactionId", transactionId); - intent.putExtra("pduType", pduType); - intent.putExtra("data", data); - - mPhone.getContext().sendBroadcast( - intent, "android.permission.RECEIVE_MMS"); - } -} diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java deleted file mode 100644 index 2984fa8..0000000 --- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (C) 2008 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; - - -/** - * Implement the WSP data type decoder. - * - * @hide - */ -public class WspTypeDecoder { - - private static final int WAP_PDU_SHORT_LENGTH_MAX = 30; - private static final int WAP_PDU_LENGTH_QUOTE = 31; - - public static final int PDU_TYPE_PUSH = 0x06; - public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07; - - public static final int CONTENT_TYPE_B_DRM_RIGHTS_XML = 0x4a; - public static final int CONTENT_TYPE_B_DRM_RIGHTS_WBXML = 0x4b; - public static final int CONTENT_TYPE_B_PUSH_SI = 0x2e; - public static final int CONTENT_TYPE_B_PUSH_SL = 0x30; - public static final int CONTENT_TYPE_B_PUSH_CO = 0x32; - public static final int CONTENT_TYPE_B_MMS = 0x3e; - - public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML = - "application/vnd.oma.drm.rights+xml"; - public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_WBXML = - "application/vnd.oma.drm.rights+wbxml"; - public static final String CONTENT_MIME_TYPE_B_PUSH_SI = "application/vnd.wap.sic"; - public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc"; - public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc"; - public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message"; - - public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f; - - - byte[] wspData; - int dataLength; - long unsigned32bit; - String stringValue; - - public WspTypeDecoder(byte[] pdu) { - wspData = pdu; - } - - /** - * Decode the "Text-string" type for WSP pdu - * - * @param startIndex The starting position of the "Text-string" in this pdu - * - * @return false when error(not a Text-string) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeTextString(int startIndex) { - int index = startIndex; - while (wspData[index] != 0) { - index++; - } - dataLength = index - startIndex + 1; - if (wspData[startIndex] == 127) { - stringValue = new String(wspData, startIndex+1, dataLength - 2); - } else { - stringValue = new String(wspData, startIndex, dataLength - 1); - } - return true; - } - - /** - * Decode the "Short-integer" type for WSP pdu - * - * @param startIndex The starting position of the "Short-integer" in this pdu - * - * @return false when error(not a Short-integer) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeShortInteger(int startIndex) { - if ((wspData[startIndex] & 0x80) == 0) { - return false; - } - unsigned32bit = wspData[startIndex] & 0x7f; - dataLength = 1; - return true; - } - - /** - * Decode the "Long-integer" type for WSP pdu - * - * @param startIndex The starting position of the "Long-integer" in this pdu - * - * @return false when error(not a Long-integer) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeLongInteger(int startIndex) { - int lengthMultiOctet = wspData[startIndex] & 0xff; - - if (lengthMultiOctet > WAP_PDU_SHORT_LENGTH_MAX) { - return false; - } - unsigned32bit = 0; - for (int i=1; i<=lengthMultiOctet; i++) { - unsigned32bit = (unsigned32bit << 8) | (wspData[startIndex+i] & 0xff); - } - dataLength = 1+lengthMultiOctet; - return true; - } - - /** - * Decode the "Integer-Value" type for WSP pdu - * - * @param startIndex The starting position of the "Integer-Value" in this pdu - * - * @return false when error(not a Integer-Value) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeIntegerValue(int startIndex) { - if (decodeShortInteger(startIndex) == true) { - return true; - } - return decodeLongInteger(startIndex); - } - - /** - * Decode the "Uintvar-integer" type for WSP pdu - * - * @param startIndex The starting position of the "Uintvar-integer" in this pdu - * - * @return false when error(not a Uintvar-integer) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeUintvarInteger(int startIndex) { - int index = startIndex; - - unsigned32bit = 0; - while ((wspData[index] & 0x80) != 0) { - if ((index - startIndex) >= 4) { - return false; - } - unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f); - index++; - } - unsigned32bit = (unsigned32bit << 7) | (wspData[index] & 0x7f); - dataLength = index - startIndex + 1; - return true; - } - - /** - * Decode the "Value-length" type for WSP pdu - * - * @param startIndex The starting position of the "Value-length" in this pdu - * - * @return false when error(not a Value-length) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeValueLength(int startIndex) { - if ((wspData[startIndex] & 0xff) > WAP_PDU_LENGTH_QUOTE) { - return false; - } - if (wspData[startIndex] < WAP_PDU_LENGTH_QUOTE) { - unsigned32bit = wspData[startIndex]; - dataLength = 1; - } else { - decodeUintvarInteger(startIndex+1); - dataLength ++; - } - return true; - } - - /** - * Decode the "Extension-media" type for WSP pdu - * - * @param startIndex The starting position of the "Extension-media" in this pdu - * - * @return false when error(not a Extension-media) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeExtensionMedia(int startIndex) { - int index = startIndex; - while (wspData[index] != 0) { - index++; - } - dataLength = index - startIndex + 1; - stringValue = new String(wspData, startIndex, dataLength - 1); - return true; - } - - /** - * Decode the "Constrained-encoding" type for WSP pdu - * - * @param startIndex The starting position of the "Constrained-encoding" in this pdu - * - * @return false when error(not a Constrained-encoding) occur - * return value can be retrieved first by getValueString() and second by getValue32() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeConstrainedEncoding(int startIndex) { - if (decodeShortInteger(startIndex) == true) { - stringValue = null; - return true; - } - return decodeExtensionMedia(startIndex); - } - - /** - * Decode the "Content-type" type for WSP pdu - * - * @param startIndex The starting position of the "Content-type" in this pdu - * - * @return false when error(not a Content-type) occur - * return value can be retrieved first by getValueString() and second by getValue32() - * method length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeContentType(int startIndex) { - int mediaPrefixLength; - long mediaFieldLength; - - if (decodeValueLength(startIndex) == false) { - return decodeConstrainedEncoding(startIndex); - } - mediaPrefixLength = getDecodedDataLength(); - mediaFieldLength = getValue32(); - if (decodeIntegerValue(startIndex + mediaPrefixLength) == true) { - dataLength += mediaPrefixLength; - stringValue = null; - return true; - } - if (decodeExtensionMedia(startIndex + mediaPrefixLength) == true) { - dataLength += mediaPrefixLength; - return true; - } - return false; - } - - /** - * Decode the "Content length" type for WSP pdu - * - * @param startIndex The starting position of the "Content length" in this pdu - * - * @return false when error(not a Content length) occur - * return value can be retrieved by getValue32() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeContentLength(int startIndex) { - return decodeIntegerValue(startIndex); - } - - /** - * Decode the "Content location" type for WSP pdu - * - * @param startIndex The starting position of the "Content location" in this pdu - * - * @return false when error(not a Content location) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeContentLocation(int startIndex) { - return decodeTextString(startIndex); - } - - /** - * Decode the "X-Wap-Application-Id" type for WSP pdu - * - * @param startIndex The starting position of the "X-Wap-Application-Id" in this pdu - * - * @return false when error(not a X-Wap-Application-Id) occur - * return value can be retrieved first by getValueString() and second by getValue32() - * method length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeXWapApplicationId(int startIndex) { - if (decodeIntegerValue(startIndex) == true) { - stringValue = null; - return true; - } - return decodeTextString(startIndex); - } - - /** - * Decode the "X-Wap-Content-URI" type for WSP pdu - * - * @param startIndex The starting position of the "X-Wap-Content-URI" in this pdu - * - * @return false when error(not a X-Wap-Content-URI) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeXWapContentURI(int startIndex) { - return decodeTextString(startIndex); - } - - /** - * Decode the "X-Wap-Initiator-URI" type for WSP pdu - * - * @param startIndex The starting position of the "X-Wap-Initiator-URI" in this pdu - * - * @return false when error(not a X-Wap-Initiator-URI) occur - * return value can be retrieved by getValueString() method - * length of data in pdu can be retrieved by getValue32() method - */ - public boolean decodeXWapInitiatorURI(int startIndex) { - return decodeTextString(startIndex); - } - - /** - * The data length of latest operation. - */ - public int getDecodedDataLength() { - return dataLength; - } - - /** - * The 32-bits result of latest operation. - */ - public long getValue32() { - return unsigned32bit; - } - - /** - * The String result of latest operation. - */ - public String getValueString() { - return stringValue; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/AdnRecord.aidl b/telephony/java/com/android/internal/telephony/gsm/AdnRecord.aidl deleted file mode 100644 index 68d9a7c..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/AdnRecord.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* -** 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; - -parcelable AdnRecord; diff --git a/telephony/java/com/android/internal/telephony/gsm/AdnRecord.java b/telephony/java/com/android/internal/telephony/gsm/AdnRecord.java deleted file mode 100644 index 30df699..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/AdnRecord.java +++ /dev/null @@ -1,570 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.Message; -import android.os.Handler; -import android.os.Looper; -import android.os.AsyncResult; -import android.util.Log; -import android.telephony.PhoneNumberUtils; -import java.util.ArrayList; - -class AdnRecordLoader extends Handler -{ - static final String LOG_TAG = "GSM"; - - //***** Instance Variables - - GSMPhone phone; - int ef; - int extensionEF; - int pendingExtLoads; - Message userResponse; - String pin2; - - // For "load one" - int recordNumber; - - // for "load all" - ArrayList<AdnRecord> adns; // only valid after EVENT_ADN_LOAD_ALL_DONE - - // Either an AdnRecord or a reference to adns depending - // if this is a load one or load all operation - Object result; - - //***** Event Constants - - static final int EVENT_ADN_LOAD_DONE = 1; - static final int EVENT_EXT_RECORD_LOAD_DONE = 2; - static final int EVENT_ADN_LOAD_ALL_DONE = 3; - static final int EVENT_EF_LINEAR_RECORD_SIZE_DONE = 4; - static final int EVENT_UPDATE_RECORD_DONE = 5; - - //***** Constructor - - AdnRecordLoader(GSMPhone phone) - { - // The telephony unit-test cases may create AdnRecords - // in secondary threads - super(phone.h.getLooper()); - - this.phone = phone; - } - - /** - * Resulting AdnRecord is placed in response.obj.result - * or response.obj.exception is set - */ - void - loadFromEF(int ef, int extensionEF, int recordNumber, - Message response) - { - this.ef = ef; - this.extensionEF = extensionEF; - this.recordNumber = recordNumber; - this.userResponse = response; - - phone.mSIMFileHandler.loadEFLinearFixed( - ef, recordNumber, - obtainMessage(EVENT_ADN_LOAD_DONE)); - - } - - - /** - * Resulting ArrayList<adnRecord> is placed in response.obj.result - * or response.obj.exception is set - */ - void - loadAllFromEF(int ef, int extensionEF, - Message response) - { - this.ef = ef; - this.extensionEF = extensionEF; - this.userResponse = response; - - phone.mSIMFileHandler.loadEFLinearFixedAll( - ef, - obtainMessage(EVENT_ADN_LOAD_ALL_DONE)); - - } - - /** - * Write adn to a EF SIM record - * It will get the record size of EF record and compose hex adn array - * then write the hex array to EF record - * - * @param adn is set with alphaTag and phoneNubmer - * @param ef EF fileid - * @param extensionEF extension EF fileid - * @param recordNumber 1-based record index - * @param pin2 for CHV2 operations, must be null if pin2 is not needed - * @param response will be sent to its handler when completed - */ - void - updateEF(AdnRecord adn, int ef, int extensionEF, int recordNumber, - String pin2, Message response) - { - this.ef = ef; - this.extensionEF = extensionEF; - this.recordNumber = recordNumber; - this.userResponse = response; - this.pin2 = pin2; - - phone.mSIMFileHandler.getEFLinearRecordSize( ef, - obtainMessage(EVENT_EF_LINEAR_RECORD_SIZE_DONE, adn)); - } - - //***** Overridden from Handler - - public void - handleMessage(Message msg) - { - AsyncResult ar; - byte data[]; - AdnRecord adn; - - try { - switch (msg.what) { - case EVENT_EF_LINEAR_RECORD_SIZE_DONE: - ar = (AsyncResult)(msg.obj); - adn = (AdnRecord)(ar.userObj); - - if (ar.exception != null) { - throw new RuntimeException("get EF record size failed", - ar.exception); - } - - int[] recordSize = (int[])ar.result; - // recordSize is int[3] array - // int[0] is the record length - // int[1] is the total length of the EF file - // int[2] is the number of records in the EF file - // So int[0] * int[2] = int[1] - if (recordSize.length != 3 || recordNumber > recordSize[2]) { - throw new RuntimeException("get wrong EF record size format", - ar.exception); - } - - data = adn.buildAdnString(recordSize[0]); - - if(data == null) { - throw new RuntimeException("worong ADN format", - ar.exception); - } - - phone.mSIMFileHandler.updateEFLinearFixed(ef, recordNumber, - data, pin2, obtainMessage(EVENT_UPDATE_RECORD_DONE)); - - pendingExtLoads = 1; - - break; - case EVENT_UPDATE_RECORD_DONE: - ar = (AsyncResult)(msg.obj); - if (ar.exception != null) { - throw new RuntimeException("update EF adn record failed", - ar.exception); - } - pendingExtLoads = 0; - result = null; - break; - case EVENT_ADN_LOAD_DONE: - ar = (AsyncResult)(msg.obj); - data = (byte[])(ar.result); - - if (ar.exception != null) { - throw new RuntimeException("load failed", ar.exception); - } - - if (false) { - Log.d(LOG_TAG,"ADN EF: 0x" - + Integer.toHexString(ef) - + ":" + recordNumber - + "\n" + SimUtils.bytesToHexString(data)); - } - - adn = new AdnRecord(ef, recordNumber, data); - result = adn; - - if (adn.hasExtendedRecord()) { - // If we have a valid value in the ext record field, - // we're not done yet: we need to read the corresponding - // ext record and append it - - pendingExtLoads = 1; - - phone.mSIMFileHandler.loadEFLinearFixed( - extensionEF, adn.extRecord, - obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn)); - } - break; - - case EVENT_EXT_RECORD_LOAD_DONE: - ar = (AsyncResult)(msg.obj); - data = (byte[])(ar.result); - adn = (AdnRecord)(ar.userObj); - - if (ar.exception != null) { - throw new RuntimeException("load failed", ar.exception); - } - - Log.d(LOG_TAG,"ADN extention EF: 0x" - + Integer.toHexString(extensionEF) - + ":" + adn.extRecord - + "\n" + SimUtils.bytesToHexString(data)); - - adn.appendExtRecord(data); - - pendingExtLoads--; - // result should have been set in - // EVENT_ADN_LOAD_DONE or EVENT_ADN_LOAD_ALL_DONE - break; - - case EVENT_ADN_LOAD_ALL_DONE: - ar = (AsyncResult)(msg.obj); - ArrayList<byte[]> datas = (ArrayList<byte[]>)(ar.result); - - if (ar.exception != null) { - throw new RuntimeException("load failed", ar.exception); - } - - adns = new ArrayList<AdnRecord>(datas.size()); - result = adns; - pendingExtLoads = 0; - - for(int i = 0, s = datas.size() ; i < s ; i++) { - adn = new AdnRecord(ef, 1 + i, datas.get(i)); - adns.add(adn); - - if (adn.hasExtendedRecord()) { - // If we have a valid value in the ext record field, - // we're not done yet: we need to read the corresponding - // ext record and append it - - pendingExtLoads++; - - phone.mSIMFileHandler.loadEFLinearFixed( - extensionEF, adn.extRecord, - obtainMessage(EVENT_EXT_RECORD_LOAD_DONE, adn)); - } - } - break; - } - } catch (RuntimeException exc) { - if (userResponse != null) { - AsyncResult.forMessage(userResponse) - .exception = exc; - userResponse.sendToTarget(); - // Loading is all or nothing--either every load succeeds - // or we fail the whole thing. - userResponse = null; - } - return; - } - - if (userResponse != null && pendingExtLoads == 0) { - AsyncResult.forMessage(userResponse).result - = result; - - userResponse.sendToTarget(); - userResponse = null; - } - } - - -} - -/** - * - * Used to load or store ADNs (Abbreviated Dialing Numbers). - * - * {@hide} - * - */ -public class AdnRecord implements Parcelable -{ - static final String LOG_TAG = "GSM"; - - //***** Instance Variables - - String alphaTag = ""; - String number = ""; - int extRecord = 0xff; - int efid; // or 0 if none - int recordNumber; // or 0 if none - - - //***** Constants - - // In an ADN record, everything but the alpha identifier - // is in a footer that's 14 bytes - static final int FOOTER_SIZE_BYTES = 14; - - // Maximum size of the un-extended number field - static final int MAX_NUMBER_SIZE_BYTES = 11; - - static final int EXT_RECORD_LENGTH_BYTES = 13; - static final int EXT_RECORD_TYPE_ADDITIONAL_DATA = 2; - static final int EXT_RECORD_TYPE_MASK = 3; - static final int MAX_EXT_CALLED_PARTY_LENGTH = 0xa; - - // ADN offset - static final int ADN_BCD_NUMBER_LENGTH = 0; - static final int ADN_TON_AND_NPI = 1; - static final int ADN_DAILING_NUMBER_START = 2; - static final int ADN_DAILING_NUMBER_END = 11; - static final int ADN_CAPABILITY_ID = 12; - static final int ADN_EXTENSION_ID = 13; - - //***** Static Methods - - public static final Parcelable.Creator<AdnRecord> CREATOR - = new Parcelable.Creator<AdnRecord>() - { - public AdnRecord createFromParcel(Parcel source) - { - int efid; - int recordNumber; - String alphaTag; - String number; - - efid = source.readInt(); - recordNumber = source.readInt(); - alphaTag = source.readString(); - number = source.readString(); - - return new AdnRecord(efid, recordNumber, alphaTag, number); - } - - public AdnRecord[] newArray(int size) - { - return new AdnRecord[size]; - } - }; - - - //***** Constructor - public - AdnRecord (byte[] record) - { - this(0, 0, record); - } - - public - AdnRecord (int efid, int recordNumber, byte[] record) - { - this.efid = efid; - this.recordNumber = recordNumber; - parseRecord(record); - } - - public - AdnRecord (String alphaTag, String number) - { - this(0, 0, alphaTag, number); - } - - public - AdnRecord (int efid, int recordNumber, String alphaTag, String number) - { - this.efid = efid; - this.recordNumber = recordNumber; - this.alphaTag = alphaTag; - this.number = number; - } - - //***** Instance Methods - - public String getAlphaTag() - { - return alphaTag; - } - - public String getNumber() - { - return number; - } - - public String toString() - { - return "ADN Record '" + alphaTag + "' '" + number + "'"; - } - - public boolean isEmpty() - { - return alphaTag.equals("") && number.equals(""); - } - - public boolean hasExtendedRecord() - { - return extRecord != 0 && extRecord != 0xff; - } - - public boolean isEqual(AdnRecord adn) { - return ( alphaTag.equals(adn.getAlphaTag()) && - number.equals(adn.getNumber()) ); - } - //***** Parcelable Implementation - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) - { - dest.writeInt(efid); - dest.writeInt(recordNumber); - dest.writeString(alphaTag); - dest.writeString(number); - } - - /** - * Build adn hex byte array based on record size - * The format of byte array is defined in 51.011 10.5.1 - * - * @param recordSize is the size X of EF record - * @return hex byte[recordSize] to be written to EF record - * return nulll for wrong format of dialing nubmer or tag - */ - public byte[] buildAdnString(int recordSize) { - byte[] bcdNumber; - byte[] byteTag; - byte[] adnString = null; - int footerOffset = recordSize - FOOTER_SIZE_BYTES; - - if (number == null || number.equals("") || - alphaTag == null || alphaTag.equals("")) { - - Log.w(LOG_TAG, "[buildAdnString] Empty alpha tag or number"); - adnString = new byte[recordSize]; - for (int i = 0; i < recordSize; i++) { - adnString[i] = (byte) 0xFF; - } - } else if (number.length() - > (ADN_DAILING_NUMBER_END - ADN_DAILING_NUMBER_START + 1) * 2) { - Log.w(LOG_TAG, - "[buildAdnString] Max length of dailing number is 20"); - } else if (alphaTag.length() > footerOffset) { - Log.w(LOG_TAG, - "[buildAdnString] Max length of tag is " + footerOffset); - } else { - - adnString = new byte[recordSize]; - for (int i = 0; i < recordSize; i++) { - adnString[i] = (byte) 0xFF; - } - - bcdNumber = PhoneNumberUtils.numberToCalledPartyBCD(number); - - System.arraycopy(bcdNumber, 0, adnString, - footerOffset + ADN_TON_AND_NPI, bcdNumber.length); - - adnString[footerOffset + ADN_BCD_NUMBER_LENGTH] - = (byte) (bcdNumber.length); - adnString[footerOffset + ADN_CAPABILITY_ID] - = (byte) 0xFF; // Capacility Id - adnString[footerOffset + ADN_EXTENSION_ID] - = (byte) 0xFF; // Extension Record Id - - byteTag = GsmAlphabet.stringToGsm8BitPacked(alphaTag); - System.arraycopy(byteTag, 0, adnString, 0, byteTag.length); - - } - - return adnString; - } - - /** - * See TS 51.011 10.5.10 - */ - public void - appendExtRecord (byte[] extRecord) { - try { - if (extRecord.length != EXT_RECORD_LENGTH_BYTES) { - return; - } - - if ((extRecord[0] & EXT_RECORD_TYPE_MASK) - != EXT_RECORD_TYPE_ADDITIONAL_DATA - ) { - return; - } - - if ((0xff & extRecord[1]) > MAX_EXT_CALLED_PARTY_LENGTH) { - // invalid or empty record - return; - } - - number += PhoneNumberUtils.calledPartyBCDFragmentToString( - extRecord, 2, 0xff & extRecord[1]); - - // We don't support ext record chaining. - - } catch (RuntimeException ex) { - - - - - Log.w(LOG_TAG, "Error parsing AdnRecord ext record", ex); - } - } - - //***** Private Methods - - /** - * alphaTag and number are set to null on invalid format - */ - private void - parseRecord(byte[] record) { - try { - alphaTag = SimUtils.adnStringFieldToString( - record, 0, record.length - FOOTER_SIZE_BYTES); - - int footerOffset = record.length - FOOTER_SIZE_BYTES; - - int numberLength = 0xff & record[footerOffset]; - - if (numberLength > MAX_NUMBER_SIZE_BYTES) { - // Invalid number length - number = ""; - return; - } - - // Please note 51.011 10.5.1: - // - // "If the Dialling Number/SSC String does not contain - // a dialling number, e.g. a control string deactivating - // a service, the TON/NPI byte shall be set to 'FF' by - // the ME (see note 2)." - - number = PhoneNumberUtils.calledPartyBCDToString( - record, footerOffset + 1, numberLength); - - - extRecord = 0xff & record[record.length - 1]; - - } catch (RuntimeException ex) { - Log.w(LOG_TAG, "Error parsing AdnRecord", ex); - number = ""; - alphaTag = ""; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/AdnRecordCache.java b/telephony/java/com/android/internal/telephony/gsm/AdnRecordCache.java deleted file mode 100644 index 9da18e3..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/AdnRecordCache.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (C) 2006 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.util.SparseArray; -import android.util.Log; -import android.os.Message; -import android.os.Handler; -import android.os.AsyncResult; -import java.util.ArrayList; -import java.util.Iterator; - -/** - * {@hide} - */ -public final class AdnRecordCache extends Handler implements SimConstants -{ - //***** Instance Variables - - GSMPhone phone; - - // Indexed by EF ID - SparseArray<ArrayList<AdnRecord>> adnLikeFiles - = new SparseArray<ArrayList<AdnRecord>>(); - - // People waiting for ADN-like files to be loaded - SparseArray<ArrayList<Message>> adnLikeWaiters - = new SparseArray<ArrayList<Message>>(); - - // People waiting for adn record to be updated - SparseArray<Message> userWriteResponse = new SparseArray<Message>(); - - //***** Event Constants - - static final int EVENT_LOAD_ALL_ADN_LIKE_DONE = 1; - static final int EVENT_UPDATE_ADN_DONE = 2; - - //***** Constructor - - - /*package*/ - AdnRecordCache(GSMPhone phone) - { - this.phone = phone; - } - - //***** Called from SIMRecords - - /** - * Called from SIMRecords.onRadioNotAvailable and SIMRecords.handleSimRefresh. - */ - /*package*/ void - reset() - { - adnLikeFiles.clear(); - - clearWaiters(); - clearUserWriters(); - - } - - private void clearWaiters() { - int size = adnLikeWaiters.size(); - for (int i = 0; i < size; i++) { - ArrayList<Message> waiters = adnLikeWaiters.valueAt(i); - AsyncResult ar = new AsyncResult(null, null, new RuntimeException("AdnCache reset")); - notifyWaiters(waiters, ar); - } - adnLikeWaiters.clear(); - } - - private void clearUserWriters() { - int size = userWriteResponse.size(); - for (int i = 0; i < size; i++) { - sendErrorResponse(userWriteResponse.valueAt(i), "AdnCace reset"); - } - userWriteResponse.clear(); - } - - /** - * @return List of AdnRecords for efid if we've already loaded them this - * radio session, or null if we haven't - */ - /*package*/ ArrayList<AdnRecord> - getRecordsIfLoaded(int efid) - { - return adnLikeFiles.get(efid); - } - - /** - * Returns extension ef associated with ADN-like EF or -1 if - * we don't know. - * - * See 3GPP TS 51.011 for this mapping - */ - private int - extensionEfForEf(int efid) - { - switch (efid) { - case EF_MBDN: return EF_EXT6; - case EF_ADN: return EF_EXT1; - case EF_SDN: return EF_EXT3; - case EF_FDN: return EF_EXT2; - case EF_MSISDN: return EF_EXT1; - default: return -1; - } - } - - private void sendErrorResponse(Message response, String errString) { - if (response != null) { - Exception e = new RuntimeException(errString); - AsyncResult.forMessage(response).exception = e; - response.sendToTarget(); - } - } - - /** - * Update an ADN-like record in EF by record index - * - * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN - * @param adn is the new adn to be stored - * @param recordIndex is the 1-based adn record index - * @param pin2 is required to update EF_FDN, otherwise must be null - * @param response message to be posted when done - * response.exception hold the exception in error - */ - void updateAdnByIndex(int efid, AdnRecord adn, int recordIndex, String pin2, - Message response) { - - int extensionEF = extensionEfForEf(efid); - if (extensionEF < 0) { - sendErrorResponse(response, "EF is not known ADN-like EF:" + efid); - return; - } - - Message pendingResponse = userWriteResponse.get(efid); - if (pendingResponse != null) { - sendErrorResponse(response, "Have pending update for EF:" + efid); - return; - } - - userWriteResponse.put(efid, response); - - new AdnRecordLoader(phone).updateEF(adn, efid, extensionEF, - recordIndex, pin2, - obtainMessage(EVENT_UPDATE_ADN_DONE, efid, recordIndex, adn)); - } - - /** - * Replace oldAdn with newAdn in ADN-like record in EF - * - * The ADN-like records must be read through requestLoadAllAdnLike() before - * - * @param efid must be one of EF_ADN, EF_FDN, and EF_SDN - * @param oldAdn is the adn to be replaced - * If oldAdn.isEmpty() is ture, it insert the newAdn - * @param newAdn is the adn to be stored - * If newAdn.isEmpty() is true, it delete the oldAdn - * @param pin2 is required to update EF_FDN, otherwise must be null - * @param response message to be posted when done - * response.exception hold the exception in error - */ - void updateAdnBySearch(int efid, AdnRecord oldAdn, AdnRecord newAdn, - String pin2, Message response) { - - int extensionEF; - extensionEF = extensionEfForEf(efid); - - if (extensionEF < 0) { - sendErrorResponse(response, "EF is not known ADN-like EF:" + efid); - return; - } - - ArrayList<AdnRecord> oldAdnList; - oldAdnList = getRecordsIfLoaded(efid); - - if (oldAdnList == null) { - sendErrorResponse(response, "Adn list not exist for EF:" + efid); - return; - } - - int index = -1; - int count = 1; - for (Iterator<AdnRecord> it = oldAdnList.iterator(); it.hasNext(); ) { - if (oldAdn.isEqual(it.next())) { - index = count; - break; - } - count++; - } - - if (index == -1) { - sendErrorResponse(response, "Adn record don't exist for " + oldAdn); - return; - } - - Message pendingResponse = userWriteResponse.get(efid); - - if (pendingResponse != null) { - sendErrorResponse(response, "Have pending update for EF:" + efid); - return; - } - - userWriteResponse.put(efid, response); - - new AdnRecordLoader(phone).updateEF(newAdn, efid, extensionEF, - index, pin2, - obtainMessage(EVENT_UPDATE_ADN_DONE, efid, index, newAdn)); - } - - - /** - * Responds with exception (in response) if efid is not a known ADN-like - * record - */ - /*package*/ void - requestLoadAllAdnLike (int efid, Message response) - { - ArrayList<Message> waiters; - ArrayList<AdnRecord> result; - - result = getRecordsIfLoaded(efid); - - // Have we already loaded this efid? - if (result != null) { - if (response != null) { - AsyncResult.forMessage(response).result = result; - response.sendToTarget(); - } - - return; - } - - // Have we already *started* loading this efid? - - waiters = adnLikeWaiters.get(efid); - - if (waiters != null) { - // There's a pending request for this EF already - // just add ourselves to it - - waiters.add(response); - return; - } - - // Start loading efid - - waiters = new ArrayList<Message>(); - waiters.add(response); - - adnLikeWaiters.put(efid, waiters); - - int extensionEF = extensionEfForEf(efid); - - if (extensionEF < 0) { - // respond with error if not known ADN-like record - - if (response != null) { - AsyncResult.forMessage(response).exception - = new RuntimeException("EF is not known ADN-like EF:" + efid); - response.sendToTarget(); - } - - return; - } - - new AdnRecordLoader(phone).loadAllFromEF(efid, extensionEF, - obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE, efid, 0)); - } - - //***** Private methods - - private void - notifyWaiters(ArrayList<Message> waiters, AsyncResult ar) - { - - if (waiters == null) { - return; - } - - for (int i = 0, s = waiters.size() ; i < s ; i++) { - Message waiter = waiters.get(i); - - AsyncResult.forMessage(waiter, ar.result, ar.exception); - waiter.sendToTarget(); - } - } - - //***** Overridden from Handler - - public void - handleMessage(Message msg) { - AsyncResult ar; - int efid; - - switch(msg.what) { - case EVENT_LOAD_ALL_ADN_LIKE_DONE: - /* arg1 is efid, obj.result is ArrayList<AdnRecord>*/ - ar = (AsyncResult) msg.obj; - efid = msg.arg1; - ArrayList<Message> waiters; - - waiters = adnLikeWaiters.get(efid); - adnLikeWaiters.delete(efid); - - if (ar.exception == null) { - adnLikeFiles.put(efid, (ArrayList<AdnRecord>) (ar.result)); - } - notifyWaiters(waiters, ar); - break; - case EVENT_UPDATE_ADN_DONE: - ar = (AsyncResult)msg.obj; - efid = msg.arg1; - int index = msg.arg2; - AdnRecord adn = (AdnRecord) (ar.userObj); - - if (ar.exception == null) { - adnLikeFiles.get(efid).set(index - 1, adn); - } - - Message response = userWriteResponse.get(efid); - userWriteResponse.delete(efid); - - AsyncResult.forMessage(response, null, ar.exception); - response.sendToTarget(); - break; - } - - } - - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java b/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java deleted file mode 100644 index 2f91411..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -/** - * This class represents a apn setting for create PDP link - */ -public class ApnSetting { - - String carrier; - String apn; - String proxy; - String port; - String mmsc; - String mmsProxy; - String mmsPort; - String user; - String password; - String[] types; - - - ApnSetting(String carrier, String apn, String proxy, String port, - String mmsc, String mmsProxy, String mmsPort, - String user, String password, String[] types) { - this.carrier = carrier; - this.apn = apn; - this.proxy = proxy; - this.port = port; - this.mmsc = mmsc; - this.mmsProxy = mmsProxy; - this.mmsPort = mmsPort; - this.user = user; - this.password = password; - this.types = types; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(carrier) - .append(", ").append(apn) - .append(", ").append(proxy) - .append(", ").append(mmsc) - .append(", ").append(mmsProxy) - .append(", ").append(mmsPort) - .append(", ").append(port); - for (String t : types) { - sb.append(", ").append(t); - } - return sb.toString(); - } - - boolean canHandleType(String type) { - for (String t : types) { - if (t.equals(type) || t.equals(Phone.APN_TYPE_ALL)) { - return true; - } - } - return false; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/BaseCommands.java b/telephony/java/com/android/internal/telephony/gsm/BaseCommands.java deleted file mode 100644 index 58a5bba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/BaseCommands.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (C) 2006 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.RegistrantList; -import android.os.Registrant; -import android.os.Handler; -import android.os.AsyncResult; -import android.os.SystemProperties; -import android.provider.Checkin; -import android.util.Config; -import android.util.Log; - -/** - * {@hide} - */ -public abstract class BaseCommands implements CommandsInterface -{ - static final String LOG_TAG = "GSM"; - - //***** Instance Variables - protected Context mContext; - protected RadioState mState = RadioState.RADIO_UNAVAILABLE; - protected Object mStateMonitor = new Object(); - - protected RegistrantList mRadioStateChangedRegistrants = new RegistrantList(); - protected RegistrantList mOnRegistrants = new RegistrantList(); - protected RegistrantList mAvailRegistrants = new RegistrantList(); - protected RegistrantList mOffOrNotAvailRegistrants = new RegistrantList(); - protected RegistrantList mNotAvailRegistrants = new RegistrantList(); - protected RegistrantList mSIMReadyRegistrants = new RegistrantList(); - protected RegistrantList mSIMLockedRegistrants = new RegistrantList(); - protected RegistrantList mCallStateRegistrants = new RegistrantList(); - protected RegistrantList mNetworkStateRegistrants = new RegistrantList(); - protected RegistrantList mPDPRegistrants = new RegistrantList(); - protected Registrant mSMSRegistrant; - protected Registrant mNITZTimeRegistrant; - protected Registrant mSignalStrengthRegistrant; - protected Registrant mUSSDRegistrant; - protected Registrant mSmsOnSimRegistrant; - /** Registrant for handling SMS Status Reports */ - protected Registrant mSmsStatusRegistrant; - /** Registrant for handling Supplementary Service Notifications */ - protected Registrant mSsnRegistrant; - protected Registrant mStkSessionEndRegistrant; - protected Registrant mStkProCmdRegistrant; - protected Registrant mStkEventRegistrant; - protected Registrant mStkCallSetUpRegistrant; - /** Registrant for handling SIM SMS storage full messages */ - protected Registrant mSimSmsFullRegistrant; - /** Registrant for handling SIM Refresh notifications */ - protected Registrant mSimRefreshRegistrant; - /** Registrant for handling RING notifications */ - protected Registrant mRingRegistrant; - - public BaseCommands(Context context) { - mContext = context; // May be null (if so we won't log statistics) - } - - //***** CommandsInterface implementation - - public RadioState - getRadioState() - { - return mState; - } - - - public void - registerForRadioStateChanged(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mRadioStateChangedRegistrants.add(r); - r.notifyRegistrant(); - } - } - - public void - registerForOn(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mOnRegistrants.add(r); - - if (mState.isOn()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - - public void - registerForAvailable(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mAvailRegistrants.add(r); - - if (mState.isAvailable()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - public void - registerForNotAvailable(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mNotAvailRegistrants.add(r); - - if (!mState.isAvailable()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - public void - registerForOffOrNotAvailable(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mOffOrNotAvailRegistrants.add(r); - - if (mState == RadioState.RADIO_OFF || !mState.isAvailable()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - - /** Any transition into SIM_READY */ - public void - registerForSIMReady(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mSIMReadyRegistrants.add(r); - - if (mState.isSIMReady()) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - public void - registerForSIMLockedOrAbsent(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - synchronized (mStateMonitor) { - mSIMLockedRegistrants.add(r); - - if (mState == RadioState.SIM_LOCKED_OR_ABSENT) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - } - - public void - registerForCallStateChanged(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - mCallStateRegistrants.add(r); - } - - public void - registerForNetworkStateChanged(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - mNetworkStateRegistrants.add(r); - } - - public void - registerForPDPStateChanged(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - mPDPRegistrants.add(r); - } - - public void - setOnNewSMS(Handler h, int what, Object obj) - { - mSMSRegistrant = new Registrant (h, what, obj); - } - - public void - setOnSmsOnSim(Handler h, int what, Object obj) - { - mSmsOnSimRegistrant = new Registrant (h, what, obj); - } - - public void setOnSmsStatus(Handler h, int what, Object obj) { - mSmsStatusRegistrant = new Registrant (h, what, obj); - } - - public void - setOnSignalStrengthUpdate(Handler h, int what, Object obj) - { - mSignalStrengthRegistrant = new Registrant (h, what, obj); - } - - public void - setOnNITZTime(Handler h, int what, Object obj) - { - mNITZTimeRegistrant = new Registrant (h, what, obj); - } - - public void - setOnUSSD(Handler h, int what, Object obj) - { - mUSSDRegistrant = new Registrant (h, what, obj); - } - - public void - setOnSuppServiceNotification(Handler h, int what, Object obj) - { - mSsnRegistrant = new Registrant (h, what, obj); - } - - public void - setOnStkSessionEnd(Handler h, int what, Object obj) - { - mStkSessionEndRegistrant = new Registrant (h, what, obj); - } - - public void - setOnStkProactiveCmd(Handler h, int what, Object obj) - { - mStkProCmdRegistrant = new Registrant (h, what, obj); - } - - public void - setOnStkEvent(Handler h, int what, Object obj) - { - mStkEventRegistrant = new Registrant (h, what, obj); - } - - public void - setOnStkCallSetUp(Handler h, int what, Object obj) - { - mStkCallSetUpRegistrant = new Registrant (h, what, obj); - } - - public void setOnSimSmsFull(Handler h, int what, Object obj) { - mSimSmsFullRegistrant = new Registrant (h, what, obj); - } - - public void setOnSimRefresh(Handler h, int what, Object obj) { - mSimRefreshRegistrant = new Registrant (h, what, obj); - } - - public void setOnCallRing(Handler h, int what, Object obj) { - mRingRegistrant = new Registrant (h, what, obj); - } - - //***** Protected Methods - /** - * Store new RadioState and send notification based on the changes - * - * This function is called only by RIL.java when receiving unsolicited - * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED - * - * RadioState has 5 values : RADIO_OFF, RADIO_UNAVAILABLE, SIM_NOT_READY, - * SIM_LOCKED_OR_ABSENT, and SIM_READY. - * - * @param newState new RadioState decoded from RIL_UNSOL_RADIO_STATE_CHANGED - */ - protected void setRadioState(RadioState newState) { - RadioState oldState; - - synchronized (mStateMonitor) { - if (Config.LOGV) { - Log.v(LOG_TAG, "setRadioState old: " + mState - + " new " + newState); - } - - oldState = mState; - mState = newState; - - if (oldState == mState) { - // no state transition - return; - } - - if (mContext != null && - newState == RadioState.RADIO_UNAVAILABLE && - oldState != RadioState.RADIO_OFF) { - Checkin.updateStats(mContext.getContentResolver(), - Checkin.Stats.Tag.PHONE_RADIO_RESETS, 1, 0.0); - } - - mRadioStateChangedRegistrants.notifyRegistrants(); - - if (mState.isAvailable() && !oldState.isAvailable()) { - Log.d(LOG_TAG,"Notifying: radio available"); - mAvailRegistrants.notifyRegistrants(); - onRadioAvailable(); - } - - if (!mState.isAvailable() && oldState.isAvailable()) { - Log.d(LOG_TAG,"Notifying: radio not available"); - mNotAvailRegistrants.notifyRegistrants(); - } - - if (mState.isSIMReady() && !oldState.isSIMReady()) { - Log.d(LOG_TAG,"Notifying: SIM ready"); - mSIMReadyRegistrants.notifyRegistrants(); - } - - if (mState == RadioState.SIM_LOCKED_OR_ABSENT) { - Log.d(LOG_TAG,"Notifying: SIM locked or absent"); - mSIMLockedRegistrants.notifyRegistrants(); - } - - if (mState.isOn() && !oldState.isOn()) { - Log.d(LOG_TAG,"Notifying: Radio On"); - mOnRegistrants.notifyRegistrants(); - } - - if ((!mState.isOn() || !mState.isAvailable()) - && !((!oldState.isOn() || !oldState.isAvailable())) - ) { - Log.d(LOG_TAG,"Notifying: radio off or not available"); - mOffOrNotAvailRegistrants.notifyRegistrants(); - } - } - } - - protected void - onRadioAvailable() - { - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java b/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java deleted file mode 100644 index e7fbf6b..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/CallFailCause.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * Call fail causes from TS 24.008 . - * These are mostly the cause codes we need to distinguish for the UI. - * See 22.001 Annex F.4 for mapping of cause codes to local tones. - * - * {@hide} - * - */ -public interface CallFailCause { - static final int NORMAL_CLEARING = 16; - // Busy Tone - static final int USER_BUSY = 17; - - // No Tone - static final int NUMBER_CHANGED = 22; - static final int STATUS_ENQUIRY = 30; - static final int NORMAL_UNSPECIFIED = 31; - - // Congestion Tone - static final int NO_CIRCUIT_AVAIL = 34; - static final int TEMPORARY_FAILURE = 41; - static final int SWITCHING_CONGESTION = 42; - static final int CHANNEL_NOT_AVAIL = 44; - static final int QOS_NOT_AVAIL = 49; - static final int BEARER_NOT_AVAIL = 58; - - // others - static final int ACM_LIMIT_EXCEEDED = 68; - static final int CALL_BARRED = 240; - static final int FDN_BLOCKED = 241; - static final int ERROR_UNSPECIFIED = 0xffff; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/CallForwardInfo.java b/telephony/java/com/android/internal/telephony/gsm/CallForwardInfo.java deleted file mode 100644 index bf31b13..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/CallForwardInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2006 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.telephony.PhoneNumberUtils; - -/** - * See also RIL_CallForwardInfo in include/telephony/ril.h - * - * {@hide} - */ -public class CallForwardInfo -{ - public int status; /*1 = active, 0 = not active */ - public int reason; /* from TS 27.007 7.11 "reason" */ - public int serviceClass; /* Sum of CommandsInterface.SERVICE_CLASS */ - public int toa; /* "type" from TS 27.007 7.11 */ - public String number; /* "number" from TS 27.007 7.11 */ - public int timeSeconds; /* for CF no reply only */ - - public String toString() - { - return super.toString() + (status == 0 ? " not active " : " active ") - + " reason: " + reason - + " serviceClass: " + serviceClass - + " \"" + PhoneNumberUtils.stringFromStringAndTOA(number, toa) + "\" " - + timeSeconds + " seconds"; - - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/CallTracker.java b/telephony/java/com/android/internal/telephony/gsm/CallTracker.java deleted file mode 100644 index 2d716bb..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/CallTracker.java +++ /dev/null @@ -1,984 +0,0 @@ -/* - * Copyright (C) 2006 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 static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE; -import static com.android.internal.telephony.gsm.ServiceStateTracker.DATA_ACCESS_EDGE; -import static com.android.internal.telephony.gsm.ServiceStateTracker.DATA_ACCESS_GPRS; -import static com.android.internal.telephony.gsm.ServiceStateTracker.DATA_ACCESS_UMTS; -import static com.android.internal.telephony.gsm.ServiceStateTracker.DATA_ACCESS_UNKNOWN; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemProperties; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.telephony.gsm.GsmCellLocation; -import android.util.EventLog; -import android.util.Log; - -import com.android.internal.telephony.Call; -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.Phone; - -import java.util.ArrayList; -import java.util.List; - -/** - * {@hide} - */ -public final class CallTracker extends Handler -{ - static final String LOG_TAG = "GSM"; - private static final boolean REPEAT_POLLING = false; - - private static final boolean DBG_POLL = false; - - //***** Constants - - static final int POLL_DELAY_MSEC = 250; - static final int MAX_CONNECTIONS = 7; // only 7 connections allowed in GSM - static final int MAX_CONNECTIONS_PER_CALL = 5; // only 5 connections allowed per call - - //***** Instance Variables - - GSMConnection connections[] = new GSMConnection[MAX_CONNECTIONS]; - RegistrantList voiceCallEndedRegistrants = new RegistrantList(); - RegistrantList voiceCallStartedRegistrants = new RegistrantList(); - - - // connections dropped durin last poll - ArrayList<GSMConnection> droppedDuringPoll - = new ArrayList<GSMConnection>(MAX_CONNECTIONS); - - GSMCall ringingCall = new GSMCall(this); - // A call that is ringing or (call) waiting - GSMCall foregroundCall = new GSMCall(this); - GSMCall backgroundCall = new GSMCall(this); - - GSMConnection pendingMO; - boolean hangupPendingMO; - - GSMPhone phone; - CommandsInterface cm; - boolean desiredMute = false; // false = mute off - - Phone.State state = Phone.State.IDLE; - - int pendingOperations; - boolean needsPoll; - Message lastRelevantPoll; - - - //***** Events - - static final int EVENT_POLL_CALLS_RESULT = 1; - static final int EVENT_CALL_STATE_CHANGE = 2; - static final int EVENT_REPOLL_AFTER_DELAY = 3; - static final int EVENT_OPERATION_COMPLETE = 4; - static final int EVENT_GET_LAST_CALL_FAIL_CAUSE = 5; - - static final int EVENT_SWITCH_RESULT = 8; - static final int EVENT_RADIO_AVAILABLE = 9; - static final int EVENT_RADIO_NOT_AVAILABLE = 10; - static final int EVENT_CONFERENCE_RESULT = 11; - static final int EVENT_SEPARATE_RESULT = 12; - static final int EVENT_ECT_RESULT = 13; - - //***** Constructors - - CallTracker (GSMPhone phone) - { - this.phone = phone; - cm = phone.mCM; - - cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); - - cm.registerForOn(this, EVENT_RADIO_AVAILABLE, null); - cm.registerForNotAvailable(this, EVENT_RADIO_NOT_AVAILABLE, null); - } - - //***** Instance Methods - - //***** Public Methods - public void registerForVoiceCallStarted(Handler h, int what, Object obj) - { - Registrant r = new Registrant(h, what, obj); - voiceCallStartedRegistrants.add(r); - } - - public void registerForVoiceCallEnded(Handler h, int what, Object obj) - { - Registrant r = new Registrant(h, what, obj); - voiceCallEndedRegistrants.add(r); - } - - private void - fakeHoldForegroundBeforeDial() - { - List<Connection> connCopy; - - // We need to make a copy here, since fakeHoldBeforeDial() - // modifies the lists, and we don't want to reverse the order - connCopy = (List<Connection>) foregroundCall.connections.clone(); - - for (int i = 0, s = connCopy.size() ; i < s ; i++) { - GSMConnection conn = (GSMConnection)connCopy.get(i); - - conn.fakeHoldBeforeDial(); - } - } - - /** - * clirMode is one of the CLIR_ constants - */ - Connection - dial (String dialString, int clirMode) throws CallStateException { - // note that this triggers call state changed notif - clearDisconnected(); - - if (!canDial()) { - throw new CallStateException("cannot dial in current state"); - } - - // The new call must be assigned to the foreground call. - // That call must be idle, so place anything that's - // there on hold - if (foregroundCall.getState() == Call.State.ACTIVE) { - // this will probably be done by the radio anyway - // but the dial might fail before this happens - // and we need to make sure the foreground call is clear - // for the newly dialed connection - switchWaitingOrHoldingAndActive(); - - // Fake local state so that - // a) foregroundCall is empty for the newly dialed connection - // b) hasNonHangupStateChanged remains false in the - // next poll, so that we don't clear a failed dialing call - fakeHoldForegroundBeforeDial(); - } - - if (foregroundCall.getState() != Call.State.IDLE) { - //we should have failed in !canDial() above before we get here - throw new CallStateException("cannot dial in current state"); - } - - pendingMO = new GSMConnection(phone.getContext(), dialString, this, foregroundCall); - hangupPendingMO = false; - - if (pendingMO.address == null || pendingMO.address.length() == 0 - || pendingMO.address.indexOf(PhoneNumberUtils.WILD) >= 0 - ) { - // Phone number is invalid - pendingMO.cause = Connection.DisconnectCause.INVALID_NUMBER; - - // handlePollCalls() will notice this call not present - // and will mark it as dropped. - pollCallsWhenSafe(); - } else { - // Always unmute when initiating a new call - setMute(false); - - cm.dial(pendingMO.address, clirMode, obtainCompleteMessage()); - } - - updatePhoneState(); - phone.notifyCallStateChanged(); - - return pendingMO; - } - - - Connection - dial (String dialString) throws CallStateException - { - return dial(dialString, CommandsInterface.CLIR_DEFAULT); - } - - void - acceptCall () throws CallStateException - { - // FIXME if SWITCH fails, should retry with ANSWER - // in case the active/holding call disappeared and this - // is no longer call waiting - - if (ringingCall.getState() == Call.State.INCOMING) { - Log.i("phone", "acceptCall: incoming..."); - // Always unmute when answering a new call - setMute(false); - cm.acceptCall(obtainCompleteMessage()); - } else if (ringingCall.getState() == Call.State.WAITING) { - setMute(false); - switchWaitingOrHoldingAndActive(); - } else { - throw new CallStateException("phone not ringing"); - } - } - - void - rejectCall () throws CallStateException - { - // AT+CHLD=0 means "release held or UDUB" - // so if the phone isn't ringing, this could hang up held - if (ringingCall.getState().isRinging()) { - cm.rejectCall(obtainCompleteMessage()); - } else { - throw new CallStateException("phone not ringing"); - } - } - - void - switchWaitingOrHoldingAndActive() throws CallStateException { - // Should we bother with this check? - if (ringingCall.getState() == Call.State.INCOMING) { - throw new CallStateException("cannot be in the incoming state"); - } else { - cm.switchWaitingOrHoldingAndActive( - obtainCompleteMessage(EVENT_SWITCH_RESULT)); - } - } - - void - conference() throws CallStateException - { - cm.conference(obtainCompleteMessage(EVENT_CONFERENCE_RESULT)); - } - - void - explicitCallTransfer() throws CallStateException - { - cm.explicitCallTransfer(obtainCompleteMessage(EVENT_ECT_RESULT)); - } - - void - clearDisconnected() - { - internalClearDisconnected(); - - updatePhoneState(); - phone.notifyCallStateChanged(); - } - - boolean - canConference() - { - return foregroundCall.getState() == Call.State.ACTIVE - && backgroundCall.getState() == Call.State.HOLDING - && !backgroundCall.isFull() - && !foregroundCall.isFull(); - } - - boolean - canDial() - { - boolean ret; - int serviceState = phone.getServiceState().getState(); - - ret = (serviceState != ServiceState.STATE_POWER_OFF) && - pendingMO == null - && !ringingCall.isRinging() - && (!foregroundCall.getState().isAlive() - || !backgroundCall.getState().isAlive()); - - return ret; - } - - boolean - canTransfer() - { - return foregroundCall.getState() == Call.State.ACTIVE - && backgroundCall.getState() == Call.State.HOLDING; - } - - //***** Private Instance Methods - - private void - internalClearDisconnected() - { - ringingCall.clearDisconnected(); - foregroundCall.clearDisconnected(); - backgroundCall.clearDisconnected(); - } - - /** - * @return true if we're idle or there's a call to getCurrentCalls() pending - * but nothing else - */ - private boolean - checkNoOperationsPending() - { - if (DBG_POLL) log("checkNoOperationsPending: pendingOperations=" + - pendingOperations); - return pendingOperations == 0; - } - - - /** - * Obtain a message to use for signalling "invoke getCurrentCalls() when - * this operation and all other pending operations are complete - */ - private Message - obtainCompleteMessage() - { - return obtainCompleteMessage(EVENT_OPERATION_COMPLETE); - } - - /** - * Obtain a message to use for signalling "invoke getCurrentCalls() when - * this operation and all other pending operations are complete - */ - private Message - obtainCompleteMessage(int what) - { - pendingOperations++; - lastRelevantPoll = null; - needsPoll = true; - - if (DBG_POLL) log("obtainCompleteMessage: pendingOperations=" + - pendingOperations + ", needsPoll=" + needsPoll); - - return obtainMessage(what); - } - - /** - * Obtain a complete message that indicates that this operation - * does not require polling of getCurrentCalls(). However, if other - * operations that do need getCurrentCalls() are pending or are - * scheduled while this operation is pending, the invocatoin - * of getCurrentCalls() will be postponed until this - * operation is also complete. - */ - private Message - obtainNoPollCompleteMessage(int what) - { - pendingOperations++; - lastRelevantPoll = null; - return obtainMessage(what); - } - - - private void - operationComplete() - { - pendingOperations--; - - if (DBG_POLL) log("operationComplete: pendingOperations=" + - pendingOperations + ", needsPoll=" + needsPoll); - - if (pendingOperations == 0 && needsPoll) { - lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); - cm.getCurrentCalls(lastRelevantPoll); - } else if (pendingOperations < 0) { - // this should never happen - Log.e(LOG_TAG,"CallTracker.pendingOperations < 0"); - pendingOperations = 0; - } - } - - private void - pollCallsWhenSafe() - { - needsPoll = true; - - if (checkNoOperationsPending()) { - lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); - cm.getCurrentCalls(lastRelevantPoll); - } - } - - private void - pollCallsAfterDelay() - { - Message msg = obtainMessage(); - - msg.what = EVENT_REPOLL_AFTER_DELAY; - sendMessageDelayed(msg, POLL_DELAY_MSEC); - } - - private boolean - isCommandExceptionRadioNotAvailable(Throwable e) - { - return e != null && e instanceof CommandException - && ((CommandException)e).getCommandError() - == CommandException.Error.RADIO_NOT_AVAILABLE; - } - - private void - updatePhoneState() - { - Phone.State oldState = state; - - if (ringingCall.isRinging()) { - state = Phone.State.RINGING; - } else if (pendingMO != null || - !(foregroundCall.isIdle() && backgroundCall.isIdle())) { - state = Phone.State.OFFHOOK; - } else { - state = Phone.State.IDLE; - } - - if (state == Phone.State.IDLE && oldState != state) { - voiceCallEndedRegistrants.notifyRegistrants( - new AsyncResult(null, null, null)); - } else if (oldState == Phone.State.IDLE && oldState != state) { - voiceCallStartedRegistrants.notifyRegistrants ( - new AsyncResult(null, null, null)); - } - - if (state != oldState) { - phone.notifyPhoneStateChanged(); - } - } - - private void - handlePollCalls(AsyncResult ar) - { - List polledCalls; - - if (ar.exception == null) { - polledCalls = (List)ar.result; - } else if (isCommandExceptionRadioNotAvailable(ar.exception)) { - // just a dummy empty ArrayList to cause the loop - // to hang up all the calls - polledCalls = new ArrayList(); - } else { - // Radio probably wasn't ready--try again in a bit - // But don't keep polling if the channel is closed - pollCallsAfterDelay(); - return; - } - - Connection newRinging = null; //or waiting - boolean hasNonHangupStateChanged = false; // Any change besides - // a dropped connection - boolean needsPollDelay = false; - boolean unknownConnectionAppeared = false; - - for (int i = 0, curDC = 0, dcSize = polledCalls.size() - ; i < connections.length; i++) { - GSMConnection conn = connections[i]; - DriverCall dc = null; - - // polledCall list is sparse - if (curDC < dcSize) { - dc = (DriverCall) polledCalls.get(curDC); - - if (dc.index == i+1) { - curDC++; - } else { - dc = null; - } - } - - if (DBG_POLL) log("poll: conn[i=" + i + "]=" + - conn+", dc=" + dc); - - if (conn == null && dc != null) { - // Connection appeared in CLCC response that we don't know about - if (pendingMO != null && pendingMO.compareTo(dc)) { - - if (DBG_POLL) log("poll: pendingMO=" + pendingMO); - - // It's our pending mobile originating call - connections[i] = pendingMO; - pendingMO.index = i; - pendingMO.update(dc); - pendingMO = null; - - // Someone has already asked to hangup this call - if (hangupPendingMO) { - hangupPendingMO = false; - try { - if (Phone.DEBUG_PHONE) log( - "poll: hangupPendingMO, hangup conn " + i); - hangup(connections[i]); - } catch (CallStateException ex) { - Log.e(LOG_TAG, "unexpected error on hangup"); - } - - // Do not continue processing this poll - // Wait for hangup and repoll - return; - } - } else { - connections[i] = new GSMConnection(phone.getContext(), dc, this, i); - - // it's a ringing call - if (connections[i].getCall() == ringingCall) { - newRinging = connections[i]; - } else { - // Something strange happened: a call appeared - // which is neither a ringing call or one we created. - // Either we've crashed and re-attached to an existing - // call, or something else (eg, SIM) initiated the call. - - Log.i(LOG_TAG,"Phantom call appeared " + dc); - - // If it's a connected call, set the connect time so that - // it's non-zero. It may not be accurate, but at least - // it won't appear as a Missed Call. - if (dc.state != DriverCall.State.ALERTING - && dc.state != DriverCall.State.DIALING) { - connections[i].connectTime = System.currentTimeMillis(); - } - - unknownConnectionAppeared = true; - } - } - hasNonHangupStateChanged = true; - } else if (conn != null && dc == null) { - // Connection missing in CLCC response that we were - // tracking. - droppedDuringPoll.add(conn); - // Dropped connections are removed from the CallTracker - // list but kept in the GSMCall list - connections[i] = null; - } else if (conn != null && dc != null && !conn.compareTo(dc)) { - // Connection in CLCC response does not match what - // we were tracking. Assume dropped call and new call - - droppedDuringPoll.add(conn); - connections[i] = new GSMConnection (phone.getContext(), dc, this, i); - - if (connections[i].getCall() == ringingCall) { - newRinging = connections[i]; - } // else something strange happened - hasNonHangupStateChanged = true; - } else if (conn != null && dc != null) { /* implicit conn.compareTo(dc) */ - boolean changed; - changed = conn.update(dc); - hasNonHangupStateChanged = hasNonHangupStateChanged || changed; - } - - if (REPEAT_POLLING) { - if (dc != null) { - // FIXME with RIL, we should not need this anymore - if ((dc.state == DriverCall.State.DIALING - /*&& cm.getOption(cm.OPTION_POLL_DIALING)*/) - || (dc.state == DriverCall.State.ALERTING - /*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/) - || (dc.state == DriverCall.State.INCOMING - /*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/) - || (dc.state == DriverCall.State.WAITING - /*&& cm.getOption(cm.OPTION_POLL_WAITING)*/) - ) { - // Sometimes there's no unsolicited notification - // for state transitions - needsPollDelay = true; - } - } - } - } - - // This is the first poll after an ATD. - // We expect the pending call to appear in the list - // If it does not, we land here - if (pendingMO != null) { - Log.d(LOG_TAG,"Pending MO dropped before poll fg state:" - + foregroundCall.getState()); - - droppedDuringPoll.add(pendingMO); - pendingMO = null; - hangupPendingMO = false; - } - - if (newRinging != null) { - phone.notifyNewRingingConnection(newRinging); - } - - // clear the "local hangup" and "missed/rejected call" - // cases from the "dropped during poll" list - // These cases need no "last call fail" reason - for (int i = droppedDuringPoll.size() - 1; i >= 0 ; i--) { - GSMConnection conn = droppedDuringPoll.get(i); - - if (conn.isIncoming() && conn.getConnectTime() == 0) { - // Missed or rejected call - Connection.DisconnectCause cause; - if (conn.cause == Connection.DisconnectCause.LOCAL) { - cause = Connection.DisconnectCause.INCOMING_REJECTED; - } else { - cause = Connection.DisconnectCause.INCOMING_MISSED; - } - - if (Phone.DEBUG_PHONE) { - log("missed/rejected call, conn.cause=" + conn.cause); - log("setting cause to " + cause); - } - droppedDuringPoll.remove(i); - conn.onDisconnect(cause); - } else if (conn.cause == Connection.DisconnectCause.LOCAL) { - // Local hangup - droppedDuringPoll.remove(i); - conn.onDisconnect(Connection.DisconnectCause.LOCAL); - } else if (conn.cause == - Connection.DisconnectCause.INVALID_NUMBER) { - droppedDuringPoll.remove(i); - conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER); - } - } - - // Any non-local disconnects: determine cause - if (droppedDuringPoll.size() > 0) { - cm.getLastCallFailCause( - obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE)); - } - - if (needsPollDelay) { - pollCallsAfterDelay(); - } - - // Cases when we can no longer keep disconnected Connection's - // with their previous calls - // 1) the phone has started to ring - // 2) A Call/Connection object has changed state... - // we may have switched or held or answered (but not hung up) - if (newRinging != null || hasNonHangupStateChanged) { - internalClearDisconnected(); - } - - updatePhoneState(); - - if (unknownConnectionAppeared) { - phone.notifyUnknownConnection(); - } - - if (hasNonHangupStateChanged || newRinging != null) { - phone.notifyCallStateChanged(); - } - - //dumpState(); - } - - private void - handleRadioAvailable() - { - pollCallsWhenSafe(); - } - - private void - handleRadioNotAvailable() - { - // handlePollCalls will clear out its - // call list when it gets the CommandException - // error result from this - pollCallsWhenSafe(); - } - - private void - dumpState() - { - List l; - - Log.i(LOG_TAG,"Phone State:" + state); - - Log.i(LOG_TAG,"Ringing call: " + ringingCall.toString()); - - l = ringingCall.getConnections(); - for (int i = 0, s = l.size(); i < s; i++) { - Log.i(LOG_TAG,l.get(i).toString()); - } - - Log.i(LOG_TAG,"Foreground call: " + foregroundCall.toString()); - - l = foregroundCall.getConnections(); - for (int i = 0, s = l.size(); i < s; i++) { - Log.i(LOG_TAG,l.get(i).toString()); - } - - Log.i(LOG_TAG,"Background call: " + backgroundCall.toString()); - - l = backgroundCall.getConnections(); - for (int i = 0, s = l.size(); i < s; i++) { - Log.i(LOG_TAG,l.get(i).toString()); - } - - } - - //***** Called from GSMConnection - - /*package*/ void - hangup (GSMConnection conn) throws CallStateException - { - if (conn.owner != this) { - throw new CallStateException ("Connection " + conn - + "does not belong to CallTracker " + this); - } - - if (conn == pendingMO) { - // We're hanging up an outgoing call that doesn't have it's - // GSM index assigned yet - - if (Phone.DEBUG_PHONE) log("hangup: set hangupPendingMO to true"); - hangupPendingMO = true; - } else { - try { - cm.hangupConnection (conn.getGSMIndex(), obtainCompleteMessage()); - } catch (CallStateException ex) { - // Ignore "connection not found" - // Call may have hung up already - Log.w(LOG_TAG,"CallTracker WARN: hangup() on absent connection " - + conn); - } - } - - conn.onHangupLocal(); - } - - /*package*/ void - separate (GSMConnection conn) throws CallStateException - { - if (conn.owner != this) { - throw new CallStateException ("Connection " + conn - + "does not belong to CallTracker " + this); - } - try { - cm.separateConnection (conn.getGSMIndex(), - obtainCompleteMessage(EVENT_SEPARATE_RESULT)); - } catch (CallStateException ex) { - // Ignore "connection not found" - // Call may have hung up already - Log.w(LOG_TAG,"CallTracker WARN: separate() on absent connection " - + conn); - } - } - - //***** Called from GSMPhone - - /*package*/ void - setMute(boolean mute) - { - desiredMute = mute; - cm.setMute(desiredMute, null); - } - - /*package*/ boolean - getMute() - { - return desiredMute; - } - - - //***** Called from GSMCall - - /* package */ void - hangup (GSMCall call) throws CallStateException - { - if (call.getConnections().size() == 0) { - throw new CallStateException("no connections in call"); - } - - if (call == ringingCall) { - if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background"); - cm.hangupWaitingOrBackground(obtainCompleteMessage()); - } else if (call == foregroundCall) { - if (call.isDialingOrAlerting()) { - if (Phone.DEBUG_PHONE) { - log("(foregnd) hangup dialing or alerting..."); - } - hangup((GSMConnection)(call.getConnections().get(0))); - } else { - hangupForegroundResumeBackground(); - } - } else if (call == backgroundCall) { - if (ringingCall.isRinging()) { - if (Phone.DEBUG_PHONE) { - log("hangup all conns in background call"); - } - hangupAllConnections(call); - } else { - hangupWaitingOrBackground(); - } - } else { - throw new RuntimeException ("Call " + call + - "does not belong to CallTracker " + this); - } - - call.onHangupLocal(); - } - - /* package */ - void hangupWaitingOrBackground() { - if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground"); - cm.hangupWaitingOrBackground(obtainCompleteMessage()); - } - - /* package */ - void hangupForegroundResumeBackground() { - if (Phone.DEBUG_PHONE) log("hangupForegroundResumeBackground"); - cm.hangupForegroundResumeBackground(obtainCompleteMessage()); - } - - void hangupConnectionByIndex(GSMCall call, int index) - throws CallStateException { - int count = call.connections.size(); - for (int i = 0; i < count; i++) { - GSMConnection cn = (GSMConnection)call.connections.get(i); - if (cn.getGSMIndex() == index) { - cm.hangupConnection(index, obtainCompleteMessage()); - return; - } - } - - throw new CallStateException("no gsm index found"); - } - - void hangupAllConnections(GSMCall call) throws CallStateException{ - try { - int count = call.connections.size(); - for (int i = 0; i < count; i++) { - GSMConnection cn = (GSMConnection)call.connections.get(i); - cm.hangupConnection(cn.getGSMIndex(), obtainCompleteMessage()); - } - } catch (CallStateException ex) { - Log.e(LOG_TAG, "hangupConnectionByIndex caught " + ex); - } - } - - /* package */ - GSMConnection getConnectionByIndex(GSMCall call, int index) - throws CallStateException { - int count = call.connections.size(); - for (int i = 0; i < count; i++) { - GSMConnection cn = (GSMConnection)call.connections.get(i); - if (cn.getGSMIndex() == index) { - return cn; - } - } - - return null; - } - - private Phone.SuppService getFailedService(int what) { - switch (what) { - case EVENT_SWITCH_RESULT: - return Phone.SuppService.SWITCH; - case EVENT_CONFERENCE_RESULT: - return Phone.SuppService.CONFERENCE; - case EVENT_SEPARATE_RESULT: - return Phone.SuppService.SEPARATE; - case EVENT_ECT_RESULT: - return Phone.SuppService.TRANSFER; - } - return Phone.SuppService.UNKNOWN; - } - - //****** Overridden from Handler - - public void - handleMessage (Message msg) - { - AsyncResult ar; - - switch (msg.what) { - case EVENT_POLL_CALLS_RESULT: - ar = (AsyncResult)msg.obj; - - if (msg == lastRelevantPoll) { - if (DBG_POLL) log( - "handle EVENT_POLL_CALL_RESULT: set needsPoll=F"); - needsPoll = false; - lastRelevantPoll = null; - handlePollCalls((AsyncResult)msg.obj); - } - break; - - case EVENT_OPERATION_COMPLETE: - ar = (AsyncResult)msg.obj; - operationComplete(); - break; - - case EVENT_SWITCH_RESULT: - case EVENT_CONFERENCE_RESULT: - case EVENT_SEPARATE_RESULT: - case EVENT_ECT_RESULT: - ar = (AsyncResult)msg.obj; - if (ar.exception != null) { - phone.notifySuppServiceFailed(getFailedService(msg.what)); - } - operationComplete(); - break; - - case EVENT_GET_LAST_CALL_FAIL_CAUSE: - int causeCode; - ar = (AsyncResult)msg.obj; - - operationComplete(); - - if (ar.exception != null) { - // An exception occurred...just treat the disconnect - // cause as "normal" - causeCode = CallFailCause.NORMAL_CLEARING; - Log.i(LOG_TAG, - "Exception during getLastCallFailCause, assuming normal disconnect"); - } else { - causeCode = ((int[])ar.result)[0]; - } - // Log the causeCode if its not normal - if (causeCode == CallFailCause.NO_CIRCUIT_AVAIL || - causeCode == CallFailCause.TEMPORARY_FAILURE || - causeCode == CallFailCause.SWITCHING_CONGESTION || - causeCode == CallFailCause.CHANNEL_NOT_AVAIL || - causeCode == CallFailCause.QOS_NOT_AVAIL || - causeCode == CallFailCause.BEARER_NOT_AVAIL || - causeCode == CallFailCause.ERROR_UNSPECIFIED) { - int cid = -1; - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - if (loc != null) cid = loc.getCid(); - - EventLog.List val = new EventLog.List(causeCode, cid, - TelephonyManager.getDefault().getNetworkType()); - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_CALL_DROP, val); - } - - for (int i = 0, s = droppedDuringPoll.size() - ; i < s ; i++ - ) { - GSMConnection conn = droppedDuringPoll.get(i); - - conn.onRemoteDisconnect(causeCode); - } - - updatePhoneState(); - - phone.notifyCallStateChanged(); - droppedDuringPoll.clear(); - break; - - case EVENT_REPOLL_AFTER_DELAY: - case EVENT_CALL_STATE_CHANGE: - pollCallsWhenSafe(); - break; - - case EVENT_RADIO_AVAILABLE: - handleRadioAvailable(); - break; - - case EVENT_RADIO_NOT_AVAILABLE: - handleRadioNotAvailable(); - break; - } - } - - private void log(String msg) { - Log.d(LOG_TAG, "[CallTracker] " + msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/CommandException.java b/telephony/java/com/android/internal/telephony/gsm/CommandException.java deleted file mode 100644 index 5cf48f3..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/CommandException.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 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.util.Log; - -/** - * {@hide} - */ -public class CommandException extends RuntimeException -{ - private Error e; - - public enum Error { - INVALID_RESPONSE, - RADIO_NOT_AVAILABLE, - GENERIC_FAILURE, - PASSWORD_INCORRECT, - SIM_PIN2, - SIM_PUK2, - REQUEST_NOT_SUPPORTED, - OP_NOT_ALLOWED_DURING_VOICE_CALL, - OP_NOT_ALLOWED_BEFORE_REG_NW, - SMS_FAIL_RETRY, - } - - public CommandException(Error e) - { - super(e.toString()); - this.e = e; - } - - public static CommandException - fromRilErrno(int ril_errno) - { - switch(ril_errno) { - case RILConstants.SUCCESS: return null; - case RILConstants.RIL_ERRNO_INVALID_RESPONSE: - return new CommandException(Error.INVALID_RESPONSE); - case RILConstants.RADIO_NOT_AVAILABLE: - return new CommandException(Error.RADIO_NOT_AVAILABLE); - case RILConstants.GENERIC_FAILURE: - return new CommandException(Error.GENERIC_FAILURE); - case RILConstants.PASSWORD_INCORRECT: - return new CommandException(Error.PASSWORD_INCORRECT); - case RILConstants.SIM_PIN2: - return new CommandException(Error.SIM_PIN2); - case RILConstants.SIM_PUK2: - return new CommandException(Error.SIM_PUK2); - case RILConstants.REQUEST_NOT_SUPPORTED: - return new CommandException(Error.REQUEST_NOT_SUPPORTED); - case RILConstants.OP_NOT_ALLOWED_DURING_VOICE_CALL: - return new CommandException(Error.OP_NOT_ALLOWED_DURING_VOICE_CALL); - case RILConstants.OP_NOT_ALLOWED_BEFORE_REG_NW: - return new CommandException(Error.OP_NOT_ALLOWED_BEFORE_REG_NW); - case RILConstants.SMS_SEND_FAIL_RETRY: - return new CommandException(Error.SMS_FAIL_RETRY); - default: - Log.e("GSM", "Unrecognized RIL errno " + ril_errno); - return new CommandException(Error.INVALID_RESPONSE); - } - } - - public Error getCommandError() - { - return e; - } - - - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/CommandsInterface.java b/telephony/java/com/android/internal/telephony/gsm/CommandsInterface.java deleted file mode 100644 index c7b08d2..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/CommandsInterface.java +++ /dev/null @@ -1,915 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -import android.os.Message; -import android.os.Handler; - -/** - * {@hide} - */ -public interface CommandsInterface -{ - enum RadioState { - RADIO_OFF, /* Radio explictly powered off (eg CFUN=0) */ - RADIO_UNAVAILABLE, /* Radio unavailable (eg, resetting or not booted) */ - SIM_NOT_READY, /* Radio is on, but the SIM interface is not ready */ - SIM_LOCKED_OR_ABSENT, /* SIM PIN locked, PUK required, network - personalization, or SIM absent */ - SIM_READY; /* Radio is on and SIM interface is available */ - - boolean isOn() /* and available...*/ - { - return this == SIM_NOT_READY - || this == SIM_LOCKED_OR_ABSENT - || this == SIM_READY; - } - - boolean isAvailable() - { - return this != RADIO_UNAVAILABLE; - } - - boolean isSIMReady() - { - // if you add new states after SIM_READY, include them too - return this == SIM_READY; - } - } - - enum SimStatus { - SIM_ABSENT, - SIM_NOT_READY, - SIM_READY, - SIM_PIN, - SIM_PUK, - SIM_NETWORK_PERSONALIZATION - } - - //***** Constants - - // Used as parameter to dial() and setCLIR() below - static final int CLIR_DEFAULT = 0; // "use subscription default value" - static final int CLIR_INVOCATION = 1; // (restrict CLI presentation) - static final int CLIR_SUPPRESSION = 2; // (allow CLI presentation) - - - // Used as parameters for call forward methods below - static final int CF_ACTION_DISABLE = 0; - static final int CF_ACTION_ENABLE = 1; -// static final int CF_ACTION_UNUSED = 2; - static final int CF_ACTION_REGISTRATION = 3; - static final int CF_ACTION_ERASURE = 4; - - static final int CF_REASON_UNCONDITIONAL = 0; - static final int CF_REASON_BUSY = 1; - static final int CF_REASON_NO_REPLY = 2; - static final int CF_REASON_NOT_REACHABLE = 3; - static final int CF_REASON_ALL = 4; - static final int CF_REASON_ALL_CONDITIONAL = 5; - - // Used for call barring methods below - static final String CB_FACILITY_BAOC = "AO"; - static final String CB_FACILITY_BAOIC = "OI"; - static final String CB_FACILITY_BAOICxH = "OX"; - static final String CB_FACILITY_BAIC = "AI"; - static final String CB_FACILITY_BAICr = "IR"; - static final String CB_FACILITY_BA_ALL = "AB"; - static final String CB_FACILITY_BA_MO = "AG"; - static final String CB_FACILITY_BA_MT = "AC"; - static final String CB_FACILITY_BA_SIM = "SC"; - static final String CB_FACILITY_BA_FD = "FD"; - - - // Used for various supp services apis - // See 27.007 +CCFC or +CLCK - static final int SERVICE_CLASS_NONE = 0; // no user input - static final int SERVICE_CLASS_VOICE = (1 << 0); - static final int SERVICE_CLASS_DATA = (1 << 1); //synoym for 16+32+64+128 - static final int SERVICE_CLASS_FAX = (1 << 2); - static final int SERVICE_CLASS_SMS = (1 << 3); - static final int SERVICE_CLASS_DATA_SYNC = (1 << 4); - static final int SERVICE_CLASS_DATA_ASYNC = (1 << 5); - static final int SERVICE_CLASS_PACKET = (1 << 6); - static final int SERVICE_CLASS_PAD = (1 << 7); - static final int SERVICE_CLASS_MAX = (1 << 7); // Max SERVICE_CLASS value - - // Numeric representation of string values returned - // by messages sent to setOnUSSD handler - static final int USSD_MODE_NOTIFY = 0; - static final int USSD_MODE_REQUEST = 1; - - // SIM Refresh results, passed up from RIL. - static final int SIM_REFRESH_FILE_UPDATED = 0; // Single file updated - static final int SIM_REFRESH_INIT = 1; // SIM initialized; reload all - static final int SIM_REFRESH_RESET = 2; // SIM reset; may be locked - - //***** Methods - - RadioState getRadioState(); - - /** - * Fires on any RadioState transition - * Always fires immediately as well - * - * do not attempt to calculate transitions by storing getRadioState() values - * on previous invocations of this notification. Instead, use the other - * registration methods - */ - void registerForRadioStateChanged(Handler h, int what, Object obj); - - /** - * Fires on any transition into RadioState.isOn() - * Fires immediately if currently in that state - * In general, actions should be idempotent. State may change - * before event is received. - */ - void registerForOn(Handler h, int what, Object obj); - - /** - * Fires on any transition out of RadioState.isAvailable() - * Fires immediately if currently in that state - * In general, actions should be idempotent. State may change - * before event is received. - */ - void registerForAvailable(Handler h, int what, Object obj); - //void unregisterForAvailable(Handler h); - /** - * Fires on any transition into !RadioState.isAvailable() - * Fires immediately if currently in that state - * In general, actions should be idempotent. State may change - * before event is received. - */ - void registerForNotAvailable(Handler h, int what, Object obj); - //void unregisterForNotAvailable(Handler h); - /** - * Fires on any transition into RADIO_OFF or !RadioState.isAvailable() - * Fires immediately if currently in that state - * In general, actions should be idempotent. State may change - * before event is received. - */ - void registerForOffOrNotAvailable(Handler h, int what, Object obj); - //void unregisterForNotAvailable(Handler h); - - /** - * Fires on any transition into SIM_READY - * Fires immediately if if currently in that state - * In general, actions should be idempotent. State may change - * before event is received. - */ - void registerForSIMReady(Handler h, int what, Object obj); - //void unregisterForSIMReady(Handler h); - /** Any transition into SIM_LOCKED_OR_ABSENT */ - void registerForSIMLockedOrAbsent(Handler h, int what, Object obj); - //void unregisterForSIMLockedOrAbsent(Handler h); - - void registerForCallStateChanged(Handler h, int what, Object obj); - //void unregisterForCallStateChanged(Handler h); - void registerForNetworkStateChanged(Handler h, int what, Object obj); - //void unregisterForNetworkStateChanged(Handler h); - void registerForPDPStateChanged(Handler h, int what, Object obj); - //void unregisterForPDPStateChanged(Handler h); - - /** - * unlike the register* methods, there's only one new SMS handler - * if you need to unregister, you should also tell the radio to stop - * sending SMS's to you (via AT+CNMI) - * - * AsyncResult.result is a String containing the SMS PDU - */ - void setOnNewSMS(Handler h, int what, Object obj); - - /** - * Register for NEW_SMS_ON_SIM unsolicited message - * - * AsyncResult.result is an int array containing the index of new SMS - */ - void setOnSmsOnSim(Handler h, int what, Object obj); - - /** - * Register for NEW_SMS_STATUS_REPORT unsolicited message - * - * AsyncResult.result is a String containing the status report PDU - */ - void setOnSmsStatus(Handler h, int what, Object obj); - - /** - * unlike the register* methods, there's only one NITZ time handler - * - * AsyncResult.result is an Object[] - * ((Object[])AsyncResult.result)[0] is a String containing the NITZ time string - * ((Object[])AsyncResult.result)[1] is a Long containing the milliseconds since boot as - * returned by elapsedRealtime() when this NITZ time - * was posted. - * - * Please note that the delivery of this message may be delayed several - * seconds on system startup - */ - void setOnNITZTime(Handler h, int what, Object obj); - - /** - * unlike the register* methods, there's only one USSD notify handler - * - * Represents the arrival of a USSD "notify" message, which may - * or may not have been triggered by a previous USSD send - * - * AsyncResult.result is a String[] - * ((String[])(AsyncResult.result))[0] contains status code - * "0" USSD-Notify -- text in ((const char **)data)[1] - * "1" USSD-Request -- text in ((const char **)data)[1] - * "2" Session terminated by network - * "3" other local client (eg, SIM Toolkit) has responded - * "4" Operation not supported - * "5" Network timeout - * - * ((String[])(AsyncResult.result))[1] contains the USSD message - * The numeric representations of these are in USSD_MODE_* - */ - - void setOnUSSD(Handler h, int what, Object obj); - - /** - * unlike the register* methods, there's only one signal strength handler - * AsyncResult.result is an int[2] - * response.obj.result[0] is received signal strength (0-31, 99) - * response.obj.result[1] is bit error rate (0-7, 99) - * as defined in TS 27.007 8.5 - */ - - void setOnSignalStrengthUpdate(Handler h, int what, Object obj); - - /** - * Sets the handler for SIM SMS storage full unsolicited message. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnSimSmsFull(Handler h, int what, Object obj); - - /** - * Sets the handler for SIM Refresh notifications. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnSimRefresh(Handler h, int what, Object obj); - - /** - * Sets the handler for RING notifications. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnCallRing(Handler h, int what, Object obj); - - /** - * Sets the handler for Supplementary Service Notifications. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnSuppServiceNotification(Handler h, int what, Object obj); - - /** - * Sets the handler for Session End Notifications for STK. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnStkSessionEnd(Handler h, int what, Object obj); - - /** - * Sets the handler for Proactive Commands for STK. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnStkProactiveCmd(Handler h, int what, Object obj); - - /** - * Sets the handler for Event Notifications for STK. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnStkEvent(Handler h, int what, Object obj); - - /** - * Sets the handler for Call Set Up Notifications for STK. - * Unlike the register* methods, there's only one notification handler - * - * @param h Handler for notification message. - * @param what User-defined message code. - * @param obj User object. - */ - void setOnStkCallSetUp(Handler h, int what, Object obj); - - /** - * Enables/disbables supplementary service related notifications from - * the network. - * - * @param enable true to enable notifications, false to disable. - * @param result Message to be posted when command completes. - */ - void setSuppServiceNotifications(boolean enable, Message result); - - /** - * Returns current SIM status. - * - * AsyncResult.result is SimStatus - * - */ - - void getSimStatus(Message result); - - /** - * Supply the SIM PIN to the SIM card - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplySimPin(String pin, Message result); - - /** - * Supply the SIM PUK to the SIM card - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplySimPuk(String puk, String newPin, Message result); - - /** - * Supply the SIM PIN2 to the SIM card - * Only called following operation where SIM_PIN2 was - * returned as a a failure from a previous operation - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplySimPin2(String pin2, Message result); - - /** - * Supply the SIM PUK2 to the SIM card - * Only called following operation where SIM_PUK2 was - * returned as a a failure from a previous operation - * - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * This exception is CommandException with an error of PASSWORD_INCORRECT - * if the password is incorrect - * - * ar.exception and ar.result are null on success - */ - - void supplySimPuk2(String puk2, String newPin2, Message result); - - void changeSimPin(String oldPin, String newPin, Message result); - void changeSimPin2(String oldPin2, String newPin2, Message result); - - void changeBarringPassword(String facility, String oldPwd, String newPwd, Message result); - - void supplyNetworkDepersonalization(String netpin, Message result); - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result contains a List of DriverCall - * The ar.result List is sorted by DriverCall.index - */ - void getCurrentCalls (Message result); - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result contains a List of PDPContextState - */ - void getPDPContextList(Message result); - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - * - * CLIR_DEFAULT == on "use subscription default value" - * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) - * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) - */ - void dial (String address, int clirMode, Message result); - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is String containing IMSI on success - */ - void getIMSI(Message result); - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is String containing IMEI on success - */ - void getIMEI(Message result); - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is String containing IMEISV on success - */ - void getIMEISV(Message result); - - /** - * Hang up one individual connection. - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - * - * 3GPP 22.030 6.5.5 - * "Releases a specific active call X" - */ - void hangupConnection (int gsmIndex, Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Releases all held calls or sets User Determined User Busy (UDUB) - * for a waiting call." - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void hangupWaitingOrBackground (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Releases all active calls (if any exist) and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void hangupForegroundResumeBackground (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls (if any exist) on hold and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void switchWaitingOrHoldingAndActive (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Adds a held call to the conversation" - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void conference (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls on hold except call X with which - * communication shall be supported." - */ - void separateConnection (int gsmIndex, Message result); - - /** - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void acceptCall (Message result); - - /** - * also known as UDUB - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void rejectCall (Message result); - - /** - * 3GPP 22.030 6.5.5 - * "Connects the two calls and disconnects the subscriber from both calls" - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void explicitCallTransfer (Message result); - - /** - * cause code returned as int[0] in Message.obj.response - * Returns integer cause code defined in TS 24.008 - * Annex H or closest approximation. - * Most significant codes: - * - Any defined in 22.001 F.4 (for generating busy/congestion) - * - Cause 68: ACM >= ACMMax - */ - void getLastCallFailCause (Message result); - - - /** - * Reason for last PDP context deactivate or failure to activate - * cause code returned as int[0] in Message.obj.response - * returns an integer cause code defined in TS 24.008 - * section 6.1.3.1.3 or close approximation - */ - void getLastPdpFailCause (Message result); - - void setMute (boolean enableMute, Message response); - - void getMute (Message response); - - /** - * response.obj is an AsyncResult - * response.obj.result is an int[2] - * response.obj.result[0] is received signal strength (0-31, 99) - * response.obj.result[1] is bit error rate (0-7, 99) - * as defined in TS 27.007 8.5 - */ - void getSignalStrength (Message response); - - - /** - * response.obj.result is an int[3] - * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2 - * response.obj.result[1] is LAC if registered or -1 if not - * response.obj.result[2] is CID if registered or -1 if not - * valid LAC and CIDs are 0x0000 - 0xffff - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" above - */ - void getRegistrationState (Message response); - - /** - * response.obj.result is an int[3] - * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2 - * response.obj.result[1] is LAC if registered or -1 if not - * response.obj.result[2] is CID if registered or -1 if not - * valid LAC and CIDs are 0x0000 - 0xffff - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" above - */ - void getGPRSRegistrationState (Message response); - - /** - * response.obj.result is a String[3] - * response.obj.result[0] is long alpha or null if unregistered - * response.obj.result[1] is short alpha or null if unregistered - * response.obj.result[2] is numeric or null if unregistered - */ - void getOperator(Message response); - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void sendDtmf(char c, Message result); - - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void startDtmf(char c, Message result); - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - void stopDtmf(Message result); - - - /** - * smscPDU is smsc address in PDU form GSM BCD format prefixed - * by a length byte (as expected by TS 27.005) or NULL for default SMSC - * pdu is SMS in PDU format as an ASCII hex string - * less the SMSC address - */ - void sendSMS (String smscPDU, String pdu, Message response); - - /** - * Deletes the specified SMS record from SIM memory (EF_SMS). - * - * @param index index of the SMS record to delete - * @param response sent when operation completes - */ - void deleteSmsOnSim(int index, Message response); - - /** - * Writes an SMS message to SIM memory (EF_SMS). - * - * @param status status of message on SIM. One of: - * SmsManger.STATUS_ON_SIM_READ - * SmsManger.STATUS_ON_SIM_UNREAD - * SmsManger.STATUS_ON_SIM_SENT - * SmsManger.STATUS_ON_SIM_UNSENT - * @param pdu message PDU, as hex string - * @param response sent when operation completes. - * response.obj will be an AsyncResult, and will indicate - * any error that may have occurred (eg, out of memory). - */ - void writeSmsToSim(int status, String smsc, String pdu, Message response); - - void setupDefaultPDP(String apn, String user, String password, Message response); - - void deactivateDefaultPDP(int cid, Message response); - - void setRadioPower(boolean on, Message response); - - void acknowledgeLastIncomingSMS(boolean success, Message response); - - /** - * parameters equivilient to 27.007 AT+CRSM command - * response.obj will be an AsyncResult - * response.obj.userObj will be a SimIoResult on success - */ - void simIO (int command, int fileid, String path, int p1, int p2, int p3, - String data, String pin2, Message response); - - /** - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned". - * - * @param response is callback message - */ - - void queryCLIP(Message response); - - /** - * response.obj will be a an int[2] - * - * response.obj[0] will be TS 27.007 +CLIR parameter 'n' - * 0 presentation indicator is used according to the subscription of the CLIR service - * 1 CLIR invocation - * 2 CLIR suppression - * - * response.obj[1] will be TS 27.007 +CLIR parameter 'm' - * 0 CLIR not provisioned - * 1 CLIR provisioned in permanent mode - * 2 unknown (e.g. no network, etc.) - * 3 CLIR temporary mode presentation restricted - * 4 CLIR temporary mode presentation allowed - */ - - void getCLIR(Message response); - - /** - * clirMode is one of the CLIR_* constants above - * - * response.obj is null - */ - - void setCLIR(int clirMode, Message response); - - /** - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 0 for disabled, 1 for enabled. - * - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - void queryCallWaiting(int serviceClass, Message response); - - /** - * @param enable is true to enable, false to disable - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - void setCallWaiting(boolean enable, int serviceClass, Message response); - - /** - * @param action is one of CF_ACTION_* - * @param cfReason is one of CF_REASON_* - * @param serviceClass is a sum of SERVICE_CLASSS_* - */ - void setCallForward(int action, int cfReason, int serviceClass, - String number, int timeSeconds, Message response); - - /** - * cfReason is one of CF_REASON_* - * - * ((AsyncResult)response.obj).result will be an array of - * CallForwardInfo's - * - * An array of length 0 means "disabled for all codes" - */ - void queryCallForwardStatus(int cfReason, int serviceClass, - String number, Message response); - - void setNetworkSelectionModeAutomatic(Message response); - - void setNetworkSelectionModeManual(String operatorNumeric, Message response); - - /** - * Queries whether the current network selection mode is automatic - * or manual - * - * ((AsyncResult)response.obj).result is an int[] with element [0] being - * a 0 for automatic selection and a 1 for manual selection - */ - - void getNetworkSelectionMode(Message response); - - /** - * Queries the currently available networks - * - * ((AsyncResult)response.obj).result is a List of NetworkInfo objects - */ - void getAvailableNetworks(Message response); - - void getBasebandVersion (Message response); - - - /** - * (AsyncResult)response.obj).result will be an Integer representing - * the sum of enabled serivice classes (sum of SERVICE_CLASS_*) - * - * @param facility one of CB_FACILTY_* - * @param password password or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - void queryFacilityLock (String facility, String password, int serviceClass, - Message response); - - /** - * @param facility one of CB_FACILTY_* - * @param lockState true means lock, false means unlock - * @param password password or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - void setFacilityLock (String facility, boolean lockState, String password, - int serviceClass, Message response); - - - void sendUSSD (String ussdString, Message response); - - /** - * Cancels a pending USSD session if one exists. - * @param response callback message - */ - void cancelPendingUssd (Message response); - - void resetRadio(Message result); - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param response is callback message - */ - void setBandMode (int bandMode, Message response); - - /** - * Query the list of band mode supported by RF. - * - * @param response is callback message - * ((AsyncResult)response.obj).result is an int[] with every - * element representing one avialable BM_*_BAND - */ - void queryAvailableBandMode (Message response); - - /** - * Requests to set the preferred network type for searching and registering - * (CS/PS domain, RAT, and operation mode) - * @param networkType one of NT_*_TYPE - * @param response is callback message - */ - void setPreferredNetworkType(int networkType , Message response); - - /** - * Query the preferred network type setting - * - * @param response is callback message to report one of NT_*_TYPE - */ - void getPreferredNetworkType(Message response); - - /** - * Query neighboring cell ids - * - * @param response s callback message to cell ids - */ - void getNeighboringCids(Message response); - - /** - * Request to enable/disable network state change notifications when - * location informateion (lac and/or cid) has changed. - * - * @param enable true to enable, false to disable - * @param response callback message - */ - void setLocationUpdates(boolean enable, Message response); - - - void invokeOemRilRequestRaw(byte[] data, Message response); - - void invokeOemRilRequestStrings(String[] strings, Message response); - - - /** - * Send TERMINAL RESPONSE to the SIM, after processing a proactive command - * sent by the SIM. - * - * @param contents String containing SAT/USAT response in hexadecimal - * format starting with first byte of response data. See - * TS 102 223 for details. - * @param response Callback message - */ - public void sendTerminalResponse(String contents, Message response); - - /** - * Send ENVELOPE to the SIM, after processing a proactive command sent by - * the SIM. - * - * @param contents String containing SAT/USAT response in hexadecimal - * format starting with command tag. See TS 102 223 for - * details. - * @param response Callback message - */ - public void sendEnvelope(String contents, Message response); - - /** - * Accept or reject the call setup request from SIM. - * - * @param accept true if the call is to be accepted, false otherwise. - * @param response Callback message - */ - public void handleCallSetupRequestFromSim(boolean accept, Message response); -} diff --git a/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java deleted file mode 100644 index 1c64641..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/DataConnectionTracker.java +++ /dev/null @@ -1,1694 +0,0 @@ -/* - * Copyright (C) 2006 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.app.AlarmManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.database.ContentObserver; -import android.database.Cursor; -import android.net.NetworkInfo; -import android.net.wifi.WifiManager; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.INetStatService; -import android.os.Message; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.preference.PreferenceManager; -import android.provider.Checkin; -import android.provider.Settings; -import android.provider.Telephony; -import android.provider.Settings.SettingNotFoundException; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.telephony.gsm.GsmCellLocation; -import android.text.TextUtils; -import android.util.EventLog; -import android.util.Log; - -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.gsm.PdpConnection.PdpFailCause; - -import java.io.IOException; -import java.util.ArrayList; - -/** - * {@hide} - */ -final class DataConnectionTracker extends Handler -{ - private static final String LOG_TAG = "GSM"; - private static final boolean DBG = true; - - /** - * IDLE: ready to start data connection setup, default state - * INITING: state of issued setupDefaultPDP() but not finish yet - * CONNECTING: state of issued startPppd() but not finish yet - * SCANNING: data connection fails with one apn but other apns are available - * ready to start data connection on other apns (before INITING) - * CONNECTED: IP connection is setup - * DISCONNECTING: PdpConnection.disconnect() has been called, but PDP - * context is not yet deactivated - * FAILED: data connection fail for all apns settings - * - * getDataConnectionState() maps State to DataState - * FAILED or IDLE : DISCONNECTED - * INITING or CONNECTING or SCANNING: CONNECTING - * CONNECTED : CONNECTED or DISCONNECTING - */ - enum State { - IDLE, - INITING, - CONNECTING, - SCANNING, - CONNECTED, - DISCONNECTING, - FAILED - } - - enum Activity { - NONE, - DATAIN, - DATAOUT, - DATAINANDOUT - } - - /** - * Handles changes to the APN db. - */ - private class ApnChangeObserver extends ContentObserver { - public ApnChangeObserver () { - super(mDataConnectionTracker); - } - - @Override - public void onChange(boolean selfChange) { - sendMessage(obtainMessage(EVENT_APN_CHANGED)); - } - } - - //***** Instance Variables - - GSMPhone phone; - INetStatService netstat; - State state = State.IDLE; - Activity activity = Activity.NONE; - boolean netStatPollEnabled = false; - // Indicates baseband will not auto-attach - private boolean noAutoAttach = false; - long nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS; - Handler mDataConnectionTracker = null; - private ContentResolver mResolver; - - long txPkts, rxPkts, sentSinceLastRecv; - int netStatPollPeriod; - private int mNoRecvPollCount = 0; - private boolean mPingTestActive = false; - // Count of PDP reset attempts; reset when we see incoming, - // call reRegisterNetwork, or pingTest succeeds. - private int mPdpResetCount = 0; - private boolean mIsScreenOn = true; - - //useful for debugging - boolean failNextConnect = false; - - /** - * allApns holds all apns for this sim spn, retrieved from - * the Carrier DB. - * - * Create once after simcard info is loaded - */ - private ArrayList<ApnSetting> allApns = null; - - /** - * waitingApns holds all apns that are waiting to be connected - * - * It is a subset of allApns and has the same format - */ - private ArrayList<ApnSetting> waitingApns = null; - - /** - * pdpList holds all the PDP connection, i.e. IP Link in GPRS - */ - private ArrayList<PdpConnection> pdpList; - - /** CID of active PDP */ - int cidActive; - - /** Currently requested APN type */ - private String mRequestedApnType = Phone.APN_TYPE_DEFAULT; - - /** Currently active APN */ - private ApnSetting mActiveApn; - - /** Currently active PdpConnection */ - private PdpConnection mActivePdp; - - private static int APN_DEFAULT_ID = 0; - private static int APN_MMS_ID = 1; - private static int APN_NUM_TYPES = 2; - - private boolean[] dataEnabled = new boolean[APN_NUM_TYPES]; - - // wifi connection status will be updated by sticky intent - private boolean mIsWifiConnected = false; - - /** Intent sent when the reconnect alarm fires. */ - private PendingIntent mReconnectIntent = null; - - //***** Constants - - // TODO: Increase this to match the max number of simultaneous - // PDP contexts we plan to support. - /** - * Pool size of PdpConnection objects. - */ - private static final int PDP_CONNECTION_POOL_SIZE = 1; - - private static final int POLL_PDP_MILLIS = 5 * 1000; - private static final int RECONNECT_DELAY_INITIAL_MILLIS = 5 * 1000; - /** Cap out with 1 hour retry interval. */ - private static final int RECONNECT_DELAY_MAX_MILLIS = 60 * 60 * 1000; - - /** Slow poll when attempting connection recovery. */ - private static final int POLL_NETSTAT_SLOW_MILLIS = 5000; - - /** Default ping deadline, in seconds. */ - private final int DEFAULT_PING_DEADLINE = 5; - /** Default max failure count before attempting to network re-registration. */ - private final int DEFAULT_MAX_PDP_RESET_FAIL = 3; - - /** - * After detecting a potential connection problem, this is the max number - * of subsequent polls before attempting a radio reset. At this point, - * poll interval is 5 seconds (POLL_NETSTAT_SLOW_MILLIS), so set this to - * poll for about 2 more minutes. - */ - private static final int NO_RECV_POLL_LIMIT = 24; - - // 1 sec. default polling interval when screen is on. - private static final int POLL_NETSTAT_MILLIS = 1000; - // 10 min. default polling interval when screen is off. - private static final int POLL_NETSTAT_SCREEN_OFF_MILLIS = 1000*60*10; - // 2 min for round trip time - private static final int POLL_LONGEST_RTT = 120 * 1000; - // 10 for packets without ack - private static final int NUMBER_SENT_PACKETS_OF_HANG = 10; - // how long to wait before switching back to default APN - private static final int RESTORE_DEFAULT_APN_DELAY = 1 * 60 * 1000; - // system property that can override the above value - private static final String APN_RESTORE_DELAY_PROP_NAME = "android.telephony.apn-restore"; - // represents an invalid IP address - private static final String NULL_IP = "0.0.0.0"; - - private static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect"; - private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason"; - - - //***** Event Codes - static final int EVENT_DATA_SETUP_COMPLETE = 1; - static final int EVENT_RADIO_AVAILABLE = 3; - static final int EVENT_RECORDS_LOADED = 4; - static final int EVENT_TRY_SETUP_DATA = 5; - static final int EVENT_PDP_STATE_CHANGED = 6; - static final int EVENT_POLL_PDP = 7; - static final int EVENT_GET_PDP_LIST_COMPLETE = 11; - static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 12; - static final int EVENT_VOICE_CALL_STARTED = 14; - static final int EVENT_VOICE_CALL_ENDED = 15; - static final int EVENT_GPRS_DETACHED = 19; - static final int EVENT_LINK_STATE_CHANGED = 20; - static final int EVENT_ROAMING_ON = 21; - static final int EVENT_ROAMING_OFF = 22; - static final int EVENT_ENABLE_NEW_APN = 23; - static final int EVENT_RESTORE_DEFAULT_APN = 24; - static final int EVENT_DISCONNECT_DONE = 25; - static final int EVENT_GPRS_ATTACHED = 26; - static final int EVENT_START_NETSTAT_POLL = 27; - static final int EVENT_START_RECOVERY = 28; - static final int EVENT_APN_CHANGED = 29; - - BroadcastReceiver mIntentReceiver = new BroadcastReceiver () - { - @Override - public void onReceive(Context context, Intent intent) - { - String action = intent.getAction(); - if (action.equals(Intent.ACTION_SCREEN_ON)) { - mIsScreenOn = true; - stopNetStatPoll(); - startNetStatPoll(); - } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { - mIsScreenOn = false; - stopNetStatPoll(); - startNetStatPoll(); - } else if (action.equals((INTENT_RECONNECT_ALARM))) { - Log.d(LOG_TAG, "GPRS reconnect alarm. Previous state was " + state); - - String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON); - if (state == State.FAILED) { - cleanUpConnection(false, reason); - } - trySetupData(reason); - } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - final android.net.NetworkInfo networkInfo = (NetworkInfo) - intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - mIsWifiConnected = (networkInfo != null && networkInfo.isConnected()); - } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; - - if (!enabled) { - // when wifi got disabeled, the NETWORK_STATE_CHANGED_ACTION - // quit and wont report disconnected til next enalbing. - mIsWifiConnected = false; - } - } - } - }; - - /** Watches for changes to the APN db. */ - private ApnChangeObserver apnObserver; - - //***** Constructor - - DataConnectionTracker(GSMPhone phone) - { - this.phone = phone; - phone.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null); - phone.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - phone.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null); - phone.mCM.registerForPDPStateChanged (this, EVENT_PDP_STATE_CHANGED, null); - phone.mCT.registerForVoiceCallEnded (this, EVENT_VOICE_CALL_ENDED, null); - phone.mCT.registerForVoiceCallStarted (this, EVENT_VOICE_CALL_STARTED, null); - phone.mSST.registerForGprsAttached(this, EVENT_GPRS_ATTACHED, null); - phone.mSST.registerForGprsDetached(this, EVENT_GPRS_DETACHED, null); - phone.mSST.registerForRoamingOn(this, EVENT_ROAMING_ON, null); - phone.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null); - - this.netstat = INetStatService.Stub.asInterface(ServiceManager.getService("netstat")); - - IntentFilter filter = new IntentFilter(); - filter.addAction(INTENT_RECONNECT_ALARM); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); - filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - - phone.getContext().registerReceiver(mIntentReceiver, filter, null, phone.h); - - - mDataConnectionTracker = this; - mResolver = phone.getContext().getContentResolver(); - - apnObserver = new ApnChangeObserver(); - phone.getContext().getContentResolver().registerContentObserver( - Telephony.Carriers.CONTENT_URI, true, apnObserver); - - createAllPdpList(); - - // This preference tells us 1) initial condition for "dataEnabled", - // and 2) whether the RIL will setup the baseband to auto-PS attach. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext()); - dataEnabled[APN_DEFAULT_ID] = !sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false); - noAutoAttach = !dataEnabled[APN_DEFAULT_ID]; - } - - void setState(State s) { - if (DBG) log ("setState: " + s); - if (state != s) { - if (s == State.INITING) { // request PDP context - Checkin.updateStats( - phone.getContext().getContentResolver(), - Checkin.Stats.Tag.PHONE_GPRS_ATTEMPTED, 1, 0.0); - } - - if (s == State.CONNECTED) { // pppd is up - Checkin.updateStats( - phone.getContext().getContentResolver(), - Checkin.Stats.Tag.PHONE_GPRS_CONNECTED, 1, 0.0); - } - } - - state = s; - - if (state == State.FAILED) { - if (waitingApns != null) - waitingApns.clear(); // when teardown the connection and set to IDLE - } - } - - String getStateInString() { - switch (state) { - case IDLE: return "IDLE"; - case INITING: return "INIT"; - case CONNECTING: return "CING"; - case SCANNING: return "SCAN"; - case CONNECTED: return "CNTD"; - case DISCONNECTING: return "DING"; - case FAILED: return "FAIL"; - default: return "ERRO"; - } - } - - String[] getActiveApnTypes() { - String[] result; - if (mActiveApn != null) { - result = mActiveApn.types; - } else { - result = new String[1]; - result[0] = Phone.APN_TYPE_DEFAULT; - } - return result; - } - - String getActiveApnString() { - String result = null; - if (mActiveApn != null) { - result = mActiveApn.apn; - } - return result; - } - - /** - * Ensure that we are connected to an APN of the specified type. - * @param type the APN type (currently the only valid value - * is {@link Phone#APN_TYPE_MMS}) - * @return the result of the operation. Success is indicated by - * a return value of either {@code Phone.APN_ALREADY_ACTIVE} or - * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a broadcast - * will be sent by the ConnectivityManager when a connection to - * the APN has been established. - */ - int enableApnType(String type) { - if (!TextUtils.equals(type, Phone.APN_TYPE_MMS)) { - return Phone.APN_REQUEST_FAILED; - } - // If already active, return - Log.d(LOG_TAG, "enableApnType("+type+")"); - if (isApnTypeActive(type)) { - setEnabled(type, true); - removeMessages(EVENT_RESTORE_DEFAULT_APN); - /** - * We're being asked to enable a non-default APN that's already in use. - * This means we should restart the timer that will automatically - * switch back to the default APN and disable the non-default APN - * when it expires. - */ - sendMessageDelayed( - obtainMessage(EVENT_RESTORE_DEFAULT_APN), - getRestoreDefaultApnDelay()); - if (state == State.INITING) return Phone.APN_REQUEST_STARTED; - else if (state == State.CONNECTED) return Phone.APN_ALREADY_ACTIVE; - } - - if (!isApnTypeAvailable(type)) { - return Phone.APN_TYPE_NOT_AVAILABLE; - } - - setEnabled(type, true); - mRequestedApnType = type; - sendMessage(obtainMessage(EVENT_ENABLE_NEW_APN)); - return Phone.APN_REQUEST_STARTED; - } - - /** - * The APN of the specified type is no longer needed. Ensure that if - * use of the default APN has not been explicitly disabled, we are connected - * to the default APN. - * @param type the APN type. The only valid value currently is {@link Phone#APN_TYPE_MMS}. - * @return - */ - int disableApnType(String type) { - Log.d(LOG_TAG, "disableApnType("+type+")"); - if (TextUtils.equals(type, Phone.APN_TYPE_MMS)) { - removeMessages(EVENT_RESTORE_DEFAULT_APN); - setEnabled(type, false); - if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { - if (dataEnabled[APN_DEFAULT_ID]) { - return Phone.APN_ALREADY_ACTIVE; - } else { - cleanUpConnection(true, Phone.REASON_DATA_DISABLED); - return Phone.APN_REQUEST_STARTED; - } - } else { - /* - * Note that if default data is disabled, the following - * has the effect of disabling the MMS APN, and then - * ignoring the request to enable the default APN. - * The net result is that data is completely disabled. - */ - sendMessage(obtainMessage(EVENT_RESTORE_DEFAULT_APN)); - return Phone.APN_REQUEST_STARTED; - } - } else { - return Phone.APN_REQUEST_FAILED; - } - } - - /** - * The data connection is expected to be setup while device - * 1. has sim card - * 2. registered to gprs service - * 3. user doesn't explicitly disable data service - * 4. wifi is not on - * - * @return false while no data connection if all above requirements are met. - */ - boolean isDataConnectionAsDesired() { - boolean roaming = phone.getServiceState().getRoaming(); - - if (phone.mSIMRecords.getRecordsLoaded() && - phone.mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE && - (!roaming || getDataOnRoamingEnabled()) && - !mIsWifiConnected ) { - return (state == State.CONNECTED); - } - return true; - } - - private boolean isApnTypeActive(String type) { - // TODO: to support simultaneous, mActiveApn can be a List instead. - return mActiveApn != null && mActiveApn.canHandleType(type); - } - - private boolean isApnTypeAvailable(String type) { - if (allApns != null) { - for (ApnSetting apn : allApns) { - if (apn.canHandleType(type)) { - return true; - } - } - } - return false; - } - - private boolean isEnabled(String apnType) { - if (TextUtils.equals(apnType, Phone.APN_TYPE_DEFAULT)) { - return dataEnabled[APN_DEFAULT_ID]; - } else if (TextUtils.equals(apnType, Phone.APN_TYPE_MMS)) { - return dataEnabled[APN_MMS_ID]; - } else { - return false; - } - } - - private void setEnabled(String apnType, boolean enable) { - Log.d(LOG_TAG, "setEnabled(" + apnType + ", " + enable + ')'); - if (TextUtils.equals(apnType, Phone.APN_TYPE_DEFAULT)) { - dataEnabled[APN_DEFAULT_ID] = enable; - } else if (TextUtils.equals(apnType, Phone.APN_TYPE_MMS)) { - dataEnabled[APN_MMS_ID] = enable; - } - Log.d(LOG_TAG, "dataEnabled[DEFAULT_APN]=" + dataEnabled[APN_DEFAULT_ID] + - " dataEnabled[MMS_APN]=" + dataEnabled[APN_MMS_ID]); - } - - /** - * Prevent mobile data connections from being established, - * or once again allow mobile data connections. If the state - * toggles, then either tear down or set up data, as - * appropriate to match the new state. - * <p>This operation only affects the default APN, and if the same APN is - * currently being used for MMS traffic, the teardown will not happen - * even when {@code enable} is {@code false}.</p> - * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data - * @return {@code true} if the operation succeeded - */ - public boolean setDataEnabled(boolean enable) { - boolean isEnabled = isEnabled(Phone.APN_TYPE_DEFAULT); - Log.d(LOG_TAG, "setDataEnabled("+enable+") isEnabled=" + isEnabled); - if (!isEnabled && enable) { - setEnabled(Phone.APN_TYPE_DEFAULT, true); - // trySetupData() will be a no-op if we are currently - // connected to the MMS APN - return trySetupData(Phone.REASON_DATA_ENABLED); - } else if (!enable) { - setEnabled(Phone.APN_TYPE_DEFAULT, false); - // Don't tear down if there is an active APN and it handles MMS. - // TODO: This isn't very general. - if (!isApnTypeActive(Phone.APN_TYPE_MMS) || !isEnabled(Phone.APN_TYPE_MMS)) { - cleanUpConnection(true, Phone.REASON_DATA_DISABLED); - return true; - } - return false; - } else // isEnabled && enable - return true; - } - - /** - * Simply tear down data connections due to radio off - * and don't setup again. - */ - public void cleanConnectionBeforeRadioOff() { - cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF); - } - - /** - * Report the current state of data connectivity (enabled or disabled) for - * the default APN. - * @return {@code false} if data connectivity has been explicitly disabled, - * {@code true} otherwise. - */ - public boolean getDataEnabled() { - return dataEnabled[APN_DEFAULT_ID]; - } - - /** - * Report on whether data connectivity is enabled for any APN. - * @return {@code false} if data connectivity has been explicitly disabled, - * {@code true} otherwise. - */ - public boolean getAnyDataEnabled() { - return dataEnabled[APN_DEFAULT_ID] || dataEnabled[APN_MMS_ID]; - } - - //The data roaming setting is now located in the shared preferences. - // See if the requested preference value is the same as that stored in - // the shared values. If it is not, then update it. - public void setDataOnRoamingEnabled(boolean enabled) { - if (getDataOnRoamingEnabled() != enabled) { - Settings.Secure.putInt(phone.getContext().getContentResolver(), - Settings.Secure.DATA_ROAMING, enabled ? 1 : 0); - } - Message roamingMsg = phone.getServiceState().getRoaming() ? - obtainMessage(EVENT_ROAMING_ON) : obtainMessage(EVENT_ROAMING_OFF); - sendMessage(roamingMsg); - } - - //Retrieve the data roaming setting from the shared preferences. - public boolean getDataOnRoamingEnabled() { - try { - return Settings.Secure.getInt(phone.getContext().getContentResolver(), - Settings.Secure.DATA_ROAMING) > 0; - } catch (SettingNotFoundException snfe) { - return false; - } - } - - public ArrayList<PdpConnection> getAllPdps() { - ArrayList<PdpConnection> pdps = (ArrayList<PdpConnection>)pdpList.clone(); - return pdps; - } - - private boolean isDataAllowed() { - boolean roaming = phone.getServiceState().getRoaming(); - return getAnyDataEnabled() && (!roaming || getDataOnRoamingEnabled()); - } - - //****** Called from ServiceStateTracker - /** - * Invoked when ServiceStateTracker observes a transition from GPRS - * attach to detach. - */ - private void onGprsDetached() - { - /* - * We presently believe it is unnecessary to tear down the PDP context - * when GPRS detaches, but we should stop the network polling. - */ - stopNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_GPRS_DETACHED); - } - - private void onGprsAttached() { - if (state == State.CONNECTED) { - startNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_GPRS_ATTACHED); - } else { - if (state == State.FAILED) { - cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED); - nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS; - } - trySetupData(Phone.REASON_GPRS_ATTACHED); - } - } - - private boolean trySetupData(String reason) - { - if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason)); - - if (phone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - setState(State.CONNECTED); - phone.notifyDataConnection(reason); - - Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected"); - return true; - } - - int gprsState = phone.mSST.getCurrentGprsState(); - boolean roaming = phone.getServiceState().getRoaming(); - - if ((state == State.IDLE || state == State.SCANNING) - && (gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach) - && phone.mSIMRecords.getRecordsLoaded() - && ( phone.mSST.isConcurrentVoiceAndData() || - phone.getState() == Phone.State.IDLE ) - && isDataAllowed()) { - - if (state == State.IDLE) { - waitingApns = buildWaitingApns(); - if (waitingApns.isEmpty()) { - if (DBG) log("No APN found"); - notifyNoData(PdpConnection.PdpFailCause.BAD_APN); - return false; - } else { - log ("Create from allApns : " + apnListToString(allApns)); - } - } - - if (DBG) { - log ("Setup watingApns : " + apnListToString(waitingApns)); - } - return setupData(reason); - } else { - if (DBG) - log("trySetupData: Not ready for data: " + - " dataState=" + state + - " gprsState=" + gprsState + - " sim=" + phone.mSIMRecords.getRecordsLoaded() + - " UMTS=" + phone.mSST.isConcurrentVoiceAndData() + - " phoneState=" + phone.getState() + - " dataEnabled=" + getAnyDataEnabled() + - " roaming=" + roaming + - " dataOnRoamingEnable=" + getDataOnRoamingEnabled()); - return false; - } - } - - /** - * If tearDown is true, this only tears down a CONNECTED session. Presently, - * there is no mechanism for abandoning an INITING/CONNECTING session, - * but would likely involve cancelling pending async requests or - * setting a flag or new state to ignore them when they came in - * @param tearDown true if the underlying PdpConnection should be - * disconnected. - * @param reason reason for the clean up. - */ - private void cleanUpConnection(boolean tearDown, String reason) { - if (DBG) log("Clean up connection due to " + reason); - - // Clear the reconnect alarm, if set. - if (mReconnectIntent != null) { - AlarmManager am = - (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); - am.cancel(mReconnectIntent); - mReconnectIntent = null; - } - - for (PdpConnection pdp : pdpList) { - if (tearDown) { - Message msg = obtainMessage(EVENT_DISCONNECT_DONE, reason); - pdp.disconnect(msg); - } else { - pdp.clearSettings(); - } - } - stopNetStatPoll(); - - /* - * If we've been asked to tear down the connection, - * set the state to DISCONNECTING. However, there's - * a race that can occur if for some reason we were - * already in the IDLE state. In that case, the call - * to pdp.disconnect() above will immediately post - * a message to the handler thread that the disconnect - * is done, and if the handler runs before the code - * below does, the handler will have set the state to - * IDLE before the code below runs. If we didn't check - * for that, future calls to trySetupData would fail, - * and we would never get out of the DISCONNECTING state. - */ - if (!tearDown) { - setState(State.IDLE); - phone.notifyDataConnection(reason); - mActiveApn = null; - } else if (state != State.IDLE) { - setState(State.DISCONNECTING); - } - } - - /** - * @param types comma delimited list of APN types - * @return array of APN types - */ - private String[] parseTypes(String types) { - String[] result; - // If unset, set to DEFAULT. - if (types == null || types.equals("")) { - result = new String[1]; - result[0] = Phone.APN_TYPE_ALL; - } else { - result = types.split(","); - } - return result; - } - - private ArrayList<ApnSetting> createApnList(Cursor cursor) { - ArrayList<ApnSetting> result = new ArrayList<ApnSetting>(); - if (cursor.moveToFirst()) { - do { - String[] types = parseTypes( - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.TYPE))); - ApnSetting apn = new ApnSetting( - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.NAME)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PROXY)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PORT)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSC)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPROXY)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.MMSPORT)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.USER)), - cursor.getString(cursor.getColumnIndexOrThrow(Telephony.Carriers.PASSWORD)), - types); - result.add(apn); - } while (cursor.moveToNext()); - } - return result; - } - - private PdpConnection findFreePdp() { - for (PdpConnection pdp : pdpList) { - if (pdp.getState() == PdpConnection.PdpState.INACTIVE) { - return pdp; - } - } - return null; - } - - private boolean setupData(String reason) { - ApnSetting apn; - PdpConnection pdp; - - apn = getNextApn(); - if (apn == null) return false; - pdp = findFreePdp(); - if (pdp == null) { - if (DBG) log("setupData: No free PdpConnection found!"); - return false; - } - mActiveApn = apn; - mActivePdp = pdp; - - Message msg = obtainMessage(); - msg.what = EVENT_DATA_SETUP_COMPLETE; - msg.obj = reason; - pdp.connect(apn, msg); - - setState(State.INITING); - phone.notifyDataConnection(reason); - return true; - } - - String getInterfaceName(String apnType) { - if (mActivePdp != null - && (apnType == null || mActiveApn.canHandleType(apnType))) { - return mActivePdp.getInterface(); - } - return null; - } - - String getIpAddress(String apnType) { - if (mActivePdp != null - && (apnType == null || mActiveApn.canHandleType(apnType))) { - return mActivePdp.getIpAddress(); - } - return null; - } - - String getGateway(String apnType) { - if (mActivePdp != null - && (apnType == null || mActiveApn.canHandleType(apnType))) { - return mActivePdp.getGatewayAddress(); - } - return null; - } - - String[] getDnsServers(String apnType) { - if (mActivePdp != null - && (apnType == null || mActiveApn.canHandleType(apnType))) { - return mActivePdp.getDnsServers(); - } - return null; - } - - private boolean - pdpStatesHasCID (ArrayList<PDPContextState> states, int cid) - { - for (int i = 0, s = states.size() ; i < s ; i++) { - if (states.get(i).cid == cid) return true; - } - - return false; - } - - private boolean - pdpStatesHasActiveCID (ArrayList<PDPContextState> states, int cid) - { - for (int i = 0, s = states.size() ; i < s ; i++) { - if (states.get(i).cid == cid) return states.get(i).active; - } - - return false; - } - - /** - * Handles changes to the APN database. - */ - private void onApnChanged() { - boolean isConnected; - - isConnected = (state != State.IDLE && state != State.FAILED); - - // TODO: It'd be nice to only do this if the changed entrie(s) - // match the current operator. - createAllApnList(); - if (state != State.DISCONNECTING) { - cleanUpConnection(isConnected, Phone.REASON_APN_CHANGED); - if (!isConnected) { - trySetupData(Phone.REASON_APN_CHANGED); - } - } - } - - /** - * @param explicitPoll if true, indicates that *we* polled for this - * update while state == CONNECTED rather than having it delivered - * via an unsolicited response (which could have happened at any - * previous state - */ - private void - onPdpStateChanged (AsyncResult ar, boolean explicitPoll) - { - ArrayList<PDPContextState> pdpStates; - - pdpStates = (ArrayList<PDPContextState>)(ar.result); - - if (ar.exception != null) { - // This is probably "radio not available" or something - // of that sort. If so, the whole connection is going - // to come down soon anyway - return; - } - - - // This is how things are supposed to work: - // The PDP list is supposed to be empty of the CID - // when it disconnects - - if (state == State.CONNECTED - && !pdpStatesHasCID(pdpStates, cidActive)) { - - // It looks like the PDP context has deactivated - // Tear everything down and try to reconnect - - Log.i(LOG_TAG, "PDP connection has dropped. Reconnecting"); - - // Add an event log when the network drops PDP - int cid = -1; - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - if (loc != null) cid = loc.getCid(); - - EventLog.List val = new EventLog.List(cid, - TelephonyManager.getDefault().getNetworkType()); - - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_PDP_NETWORK_DROP, val); - - cleanUpConnection(true, null); - - return; - } - - if (true) { - // - // Workaround for issue #655426 - // - - // -------------------------- - - // This is how some things work now: the PDP context is still - // listed with active = false, which makes it hard to - // distinguish an activating context from an activated-and-then - // deactivated one. - // - // Here, we only consider this authoritative if we asked for the - // PDP list. If it was an unsolicited response, we poll again - // to make sure everyone agrees on the initial state - - if (state == State.CONNECTED - && !pdpStatesHasActiveCID(pdpStates, cidActive)) { - - if (!explicitPoll) { - // We think it disconnected but aren't sure...poll from our side - phone.mCM.getPDPContextList( - this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE)); - } else { - Log.i(LOG_TAG, "PDP connection has dropped (active=false case). " - + " Reconnecting"); - - // Log the network drop on the event log. - int cid = -1; - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - if (loc != null) cid = loc.getCid(); - - EventLog.List val = new EventLog.List(cid, - TelephonyManager.getDefault().getNetworkType()); - - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_PDP_NETWORK_DROP, val); - - cleanUpConnection(true, null); - } - } - } - } - - private void notifyDefaultData(String reason) { - setupDnsProperties(); - setState(State.CONNECTED); - phone.notifyDataConnection(reason); - startNetStatPoll(); - // reset reconnect timer - nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS; - } - - private void setupDnsProperties() { - int mypid = android.os.Process.myPid(); - String[] servers = getDnsServers(null); - String propName; - String propVal; - int count; - - count = 0; - for (int i = 0; i < servers.length; i++) { - String serverAddr = servers[i]; - if (!TextUtils.equals(serverAddr, "0.0.0.0")) { - SystemProperties.set("net.dns" + (i+1) + "." + mypid, serverAddr); - count++; - } - } - for (int i = count+1; i <= 4; i++) { - propName = "net.dns" + i + "." + mypid; - propVal = SystemProperties.get(propName); - if (propVal.length() != 0) { - SystemProperties.set(propName, ""); - } - } - /* - * Bump the property that tells the name resolver library - * to reread the DNS server list from the properties. - */ - propVal = SystemProperties.get("net.dnschange"); - if (propVal.length() != 0) { - try { - int n = Integer.parseInt(propVal); - SystemProperties.set("net.dnschange", "" + (n+1)); - } catch (NumberFormatException e) { - } - } - } - - /** - * This is a kludge to deal with the fact that - * the PDP state change notification doesn't always work - * with certain RIL impl's/basebands - * - */ - private void - startPeriodicPdpPoll() - { - removeMessages(EVENT_POLL_PDP); - - sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS); - } - - private void resetPollStats() { - txPkts = -1; - rxPkts = -1; - sentSinceLastRecv = 0; - mNoRecvPollCount = 0; - } - - private void doRecovery() { - if (state == State.CONNECTED) { - int maxPdpReset = Settings.Gservices.getInt(mResolver, - Settings.Gservices.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT, - DEFAULT_MAX_PDP_RESET_FAIL); - if (mPdpResetCount < maxPdpReset) { - mPdpResetCount++; - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_PDP_RESET, sentSinceLastRecv); - cleanUpConnection(true, Phone.REASON_PDP_RESET); - } else { - mPdpResetCount = 0; - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_REREGISTER_NETWORK, sentSinceLastRecv); - phone.mSST.reRegisterNetwork(null); - } - // TODO: Add increasingly drastic recovery steps, eg, - // reset the radio, reset the device. - } - } - - private void - startNetStatPoll() - { - if (state == State.CONNECTED && mPingTestActive == false && netStatPollEnabled == false) { - Log.d(LOG_TAG, "[DataConnection] Start poll NetStat"); - resetPollStats(); - netStatPollEnabled = true; - mPollNetStat.run(); - } - } - - private void - stopNetStatPoll() - { - netStatPollEnabled = false; - removeCallbacks(mPollNetStat); - Log.d(LOG_TAG, "[DataConnection] Stop poll NetStat"); - } - - private void - restartRadio() - { - Log.d(LOG_TAG, "************TURN OFF RADIO**************"); - cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF); - phone.mCM.setRadioPower(false, null); - /* Note: no need to call setRadioPower(true). Assuming the desired - * radio power state is still ON (as tracked by ServiceStateTracker), - * ServiceStateTracker will call setRadioPower when it receives the - * RADIO_STATE_CHANGED notification for the power off. And if the - * desired power state has changed in the interim, we don't want to - * override it with an unconditional power on. - */ - - int reset = Integer.parseInt(SystemProperties.get("net.ppp.reset-by-timeout", "0")); - SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1)); - } - - Runnable mPollNetStat = new Runnable() - { - - public void run() { - long sent, received; - long preTxPkts = -1, preRxPkts = -1; - - Activity newActivity; - - preTxPkts = txPkts; - preRxPkts = rxPkts; - - try { - txPkts = netstat.getMobileTxPackets(); - rxPkts = netstat.getMobileRxPackets(); - } catch (RemoteException e) { - txPkts = 0; - rxPkts = 0; - } - - //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts)); - - if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) { - sent = txPkts - preTxPkts; - received = rxPkts - preRxPkts; - - if ( sent > 0 && received > 0 ) { - sentSinceLastRecv = 0; - newActivity = Activity.DATAINANDOUT; - mPdpResetCount = 0; - } else if (sent > 0 && received == 0) { - if (phone.mCT.state == Phone.State.IDLE) { - sentSinceLastRecv += sent; - } else { - sentSinceLastRecv = 0; - } - newActivity = Activity.DATAOUT; - } else if (sent == 0 && received > 0) { - sentSinceLastRecv = 0; - newActivity = Activity.DATAIN; - mPdpResetCount = 0; - } else if (sent == 0 && received == 0) { - newActivity = Activity.NONE; - } else { - sentSinceLastRecv = 0; - newActivity = Activity.NONE; - } - - if (activity != newActivity && mIsScreenOn) { - activity = newActivity; - phone.notifyDataActivity(); - } - } - - int watchdogTrigger = Settings.Gservices.getInt(mResolver, - Settings.Gservices.PDP_WATCHDOG_TRIGGER_PACKET_COUNT, NUMBER_SENT_PACKETS_OF_HANG); - - if (sentSinceLastRecv >= watchdogTrigger) { - // we already have NUMBER_SENT_PACKETS sent without ack - if (mNoRecvPollCount == 0) { - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_RADIO_RESET_COUNTDOWN_TRIGGERED, - sentSinceLastRecv); - } - - int noRecvPollLimit = Settings.Gservices.getInt(mResolver, - Settings.Gservices.PDP_WATCHDOG_ERROR_POLL_COUNT, NO_RECV_POLL_LIMIT); - - if (mNoRecvPollCount < noRecvPollLimit) { - // It's possible the PDP context went down and we weren't notified. - // Start polling the context list in an attempt to recover. - if (DBG) log("no DATAIN in a while; polling PDP"); - phone.mCM.getPDPContextList(obtainMessage(EVENT_GET_PDP_LIST_COMPLETE)); - - mNoRecvPollCount++; - - // Slow down the poll interval to let things happen - netStatPollPeriod = Settings.Gservices.getInt(mResolver, - Settings.Gservices.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS, POLL_NETSTAT_SLOW_MILLIS); - } else { - if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) + - " pkts since last received"); - // We've exceeded the threshold. Run ping test as a final check; - // it will proceed with recovery if ping fails. - stopNetStatPoll(); - Thread pingTest = new Thread() { - public void run() { - runPingTest(); - } - }; - mPingTestActive = true; - pingTest.start(); - } - } else { - mNoRecvPollCount = 0; - if (mIsScreenOn) { - netStatPollPeriod = Settings.Gservices.getInt(mResolver, - Settings.Gservices.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS); - } else { - netStatPollPeriod = Settings.Gservices.getInt(mResolver, - Settings.Gservices.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS, - POLL_NETSTAT_SCREEN_OFF_MILLIS); - } - } - - if (netStatPollEnabled) { - mDataConnectionTracker.postDelayed(this, netStatPollPeriod); - } - } - }; - - private void runPingTest () { - int status = -1; - try { - String address = Settings.Gservices.getString(mResolver, - Settings.Gservices.PDP_WATCHDOG_PING_ADDRESS); - int deadline = Settings.Gservices.getInt(mResolver, - Settings.Gservices.PDP_WATCHDOG_PING_DEADLINE, DEFAULT_PING_DEADLINE); - if (DBG) log("pinging " + address + " for " + deadline + "s"); - if (address != null && !NULL_IP.equals(address)) { - Process p = Runtime.getRuntime() - .exec("ping -c 1 -i 1 -w "+ deadline + " " + address); - status = p.waitFor(); - } - } catch (IOException e) { - Log.w(LOG_TAG, "ping failed: IOException"); - } catch (Exception e) { - Log.w(LOG_TAG, "exception trying to ping"); - } - - if (status == 0) { - // ping succeeded. False alarm. Reset netStatPoll. - // ("-1" for this event indicates a false alarm) - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_PDP_RESET, -1); - mPdpResetCount = 0; - sendMessage(obtainMessage(EVENT_START_NETSTAT_POLL)); - } else { - // ping failed. Proceed with recovery. - sendMessage(obtainMessage(EVENT_START_RECOVERY)); - } - } - - /** - * Returns true if the last fail cause is something that - * seems like it deserves an error notification. - * Transient errors are ignored - */ - private boolean - shouldPostNotification(PdpConnection.PdpFailCause cause) - { - boolean shouldPost = true; - // TODO CHECK - // if (dataLink != null) { - // shouldPost = dataLink.getLastLinkExitCode() != DataLink.EXIT_OPEN_FAILED; - //} - return (shouldPost && cause != PdpConnection.PdpFailCause.UNKNOWN); - } - - /** - * Return true if data connection need to be setup after disconnected due to - * reason. - * - * @param reason the reason why data is disconnected - * @return true if try setup data connection is need for this reason - */ - private boolean retryAfterDisconnected(String reason) { - boolean retry = true; - - if ( Phone.REASON_RADIO_TURNED_OFF.equals(reason) || - Phone.REASON_DATA_DISABLED.equals(reason) ) { - retry = false; - } - return retry; - } - - private void reconnectAfterFail(PdpFailCause lastFailCauseCode, String reason) { - if (state == State.FAILED) { - Log.d(LOG_TAG, "PDP activate failed. Scheduling next attempt for " - + (nextReconnectDelay / 1000) + "s"); - - AlarmManager am = - (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); - Intent intent = new Intent(INTENT_RECONNECT_ALARM); - intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason); - mReconnectIntent = PendingIntent.getBroadcast( - phone.getContext(), 0, intent, 0); - am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + nextReconnectDelay, - mReconnectIntent); - - // double it for next time - nextReconnectDelay *= 2; - if (nextReconnectDelay > RECONNECT_DELAY_MAX_MILLIS) { - nextReconnectDelay = RECONNECT_DELAY_MAX_MILLIS; - } - - if (!shouldPostNotification(lastFailCauseCode)) { - Log.d(LOG_TAG,"NOT Posting GPRS Unavailable notification " - + "-- likely transient error"); - } else { - notifyNoData(lastFailCauseCode); - } - } - } - - private void notifyNoData(PdpConnection.PdpFailCause lastFailCauseCode) { - setState(State.FAILED); - } - - - private void log(String s) { - Log.d(LOG_TAG, "[DataConnectionTracker] " + s); - } - - //***** Overridden from Handler - public void - handleMessage (Message msg) - { - AsyncResult ar; - String reason = null; - - switch (msg.what) { - case EVENT_RECORDS_LOADED: - createAllApnList(); - if (state == State.FAILED) { - cleanUpConnection(false, null); - } - sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA)); - break; - - case EVENT_ENABLE_NEW_APN: - // TODO: To support simultaneous PDP contexts, this should really only call - // cleanUpConnection if it needs to free up a PdpConnection. - reason = Phone.REASON_APN_SWITCHED; - cleanUpConnection(true, reason); - break; - - case EVENT_TRY_SETUP_DATA: - trySetupData(reason); - break; - - case EVENT_RESTORE_DEFAULT_APN: - if (DBG) Log.d(LOG_TAG, "Restore default APN"); - setEnabled(Phone.APN_TYPE_MMS, false); - if (!isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { - cleanUpConnection(true, Phone.REASON_RESTORE_DEFAULT_APN); - mRequestedApnType = Phone.APN_TYPE_DEFAULT; - } - break; - - case EVENT_ROAMING_OFF: - trySetupData(Phone.REASON_ROAMING_OFF); - break; - - case EVENT_GPRS_DETACHED: - onGprsDetached(); - break; - - case EVENT_GPRS_ATTACHED: - onGprsAttached(); - break; - - case EVENT_ROAMING_ON: - if (getDataOnRoamingEnabled()) { - trySetupData(Phone.REASON_ROAMING_ON); - } else { - if (DBG) log("Tear down data connection on roaming."); - cleanUpConnection(true, Phone.REASON_ROAMING_ON); - } - break; - - case EVENT_RADIO_AVAILABLE: - if (phone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - setState(State.CONNECTED); - phone.notifyDataConnection(null); - - - Log.i(LOG_TAG, "We're on the simulator; assuming data is connected"); - } - - if (state != State.IDLE) { - cleanUpConnection(true, null); - } - break; - - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: - // Make sure our reconnect delay starts at the initial value - // next time the radio comes on - nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS; - - if (phone.getSimulatedRadioControl() != null) { - // Assume data is connected on the simulator - // FIXME this can be improved - Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless"); - } else { - if (DBG) log("Radio is off and clean up all connection"); - // TODO: Should we reset mRequestedApnType to "default"? - cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF); - } - break; - - case EVENT_DATA_SETUP_COMPLETE: - ar = (AsyncResult) msg.obj; - if (ar.userObj instanceof String) { - reason = (String) ar.userObj; - } - - if (ar.exception == null) { - // everything is setup - - // arg1 contains CID for this PDP context - cidActive = msg.arg1; - /* - * We may have switched away from the default PDP context - * in order to enable a "special" APN (e.g., for MMS - * traffic). Set a timer to switch back and/or disable the - * special APN, so that a negligient application doesn't - * permanently prevent data connectivity. What we are - * protecting against here is not malicious apps, but - * rather an app that inadvertantly fails to reset to the - * default APN, or that dies before doing so. - */ - if (dataEnabled[APN_MMS_ID]) { - removeMessages(EVENT_RESTORE_DEFAULT_APN); - sendMessageDelayed( - obtainMessage(EVENT_RESTORE_DEFAULT_APN), - getRestoreDefaultApnDelay()); - } - if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { - SystemProperties.set("gsm.defaultpdpcontext.active", "true"); - } else { - SystemProperties.set("gsm.defaultpdpcontext.active", "false"); - } - notifyDefaultData(reason); - - // TODO: For simultaneous PDP support, we need to build another - // trigger another TRY_SETUP_DATA for the next APN type. (Note - // that the existing connection may service that type, in which - // case we should try the next type, etc. - } else { - PdpConnection.PdpFailCause cause; - cause = (PdpConnection.PdpFailCause) (ar.result); - if(DBG) - log("PDP setup failed " + cause); - // Log this failure to the Event Logs. - if (cause == PdpConnection.PdpFailCause.BAD_APN || - cause == PdpConnection.PdpFailCause.BAD_PAP_SECRET || - cause == PdpConnection.PdpFailCause.BARRED || - cause == PdpConnection.PdpFailCause.RADIO_ERROR_RETRY || - cause == PdpConnection.PdpFailCause.SUSPENED_TEMPORARY || - cause == PdpConnection.PdpFailCause.UNKNOWN || - cause == PdpConnection.PdpFailCause.USER_AUTHENTICATION) { - int cid = -1; - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - if (loc != null) cid = loc.getCid(); - - EventLog.List val = new EventLog.List( - cause.ordinal(), cid, - TelephonyManager.getDefault().getNetworkType()); - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_RADIO_PDP_SETUP_FAIL, val); - } - // No try for permanent failure - if (cause.isPermanentFail()) { - notifyNoData(cause); - } - - if (tryNextApn(cause)) { - waitingApns.remove(0); - if (waitingApns.isEmpty()) { - // No more to try, start delayed retry - startDelayedRetry(cause, reason); - } else { - // we still have more apns to try - setState(State.SCANNING); - trySetupData(reason); - } - } else { - startDelayedRetry(cause, reason); - } - } - break; - - case EVENT_DISCONNECT_DONE: - if(DBG) log("EVENT_DISCONNECT_DONE"); - ar = (AsyncResult) msg.obj; - if (ar.userObj instanceof String) { - reason = (String) ar.userObj; - } - setState(State.IDLE); - phone.notifyDataConnection(reason); - mActiveApn = null; - if ( retryAfterDisconnected(reason) ) { - trySetupData(reason); - } - break; - - case EVENT_PDP_STATE_CHANGED: - ar = (AsyncResult) msg.obj; - - onPdpStateChanged(ar, false); - break; - - case EVENT_GET_PDP_LIST_COMPLETE: - ar = (AsyncResult) msg.obj; - - onPdpStateChanged(ar, true); - break; - - case EVENT_POLL_PDP: - /* See comment in startPeriodicPdpPoll */ - ar = (AsyncResult) msg.obj; - - if (!(state == State.CONNECTED)) { - // not connected; don't poll anymore - break; - } - - phone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE)); - - sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), - POLL_PDP_MILLIS); - break; - - case EVENT_VOICE_CALL_STARTED: - if (state == State.CONNECTED && - !phone.mSST.isConcurrentVoiceAndData()) { - stopNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); - } - break; - - case EVENT_VOICE_CALL_ENDED: - if (state == State.CONNECTED) { - if (!phone.mSST.isConcurrentVoiceAndData()) { - startNetStatPoll(); - phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); - } else { - // clean slate after call end. - resetPollStats(); - } - } else { - // in case data setup was attempted when we were on a voice call - trySetupData(Phone.REASON_VOICE_CALL_ENDED); - } - break; - - case EVENT_START_NETSTAT_POLL: - mPingTestActive = false; - startNetStatPoll(); - break; - - case EVENT_START_RECOVERY: - mPingTestActive = false; - doRecovery(); - break; - - case EVENT_APN_CHANGED: - onApnChanged(); - break; - } - } - - private boolean tryNextApn(PdpFailCause cause) { - return (cause != PdpFailCause.RADIO_NOT_AVIALABLE) - && (cause != PdpFailCause.RADIO_OFF) - && (cause != PdpFailCause.RADIO_ERROR_RETRY) - && (cause != PdpFailCause.NO_SIGNAL) - && (cause != PdpFailCause.SIM_LOCKED); - } - - private int getRestoreDefaultApnDelay() { - String restoreApnDelayStr = SystemProperties.get(APN_RESTORE_DELAY_PROP_NAME); - - if (restoreApnDelayStr != null && restoreApnDelayStr.length() != 0) { - try { - return Integer.valueOf(restoreApnDelayStr); - } catch (NumberFormatException e) { - } - } - return RESTORE_DEFAULT_APN_DELAY; - } - - /** - * Based on the sim operator numeric, create a list for all possible pdps - * with all apns associated with that pdp - * - * - */ - private void createAllApnList() { - allApns = new ArrayList<ApnSetting>(); - String operator = phone.mSIMRecords.getSIMOperatorNumeric(); - - if (operator != null) { - String selection = "numeric = '" + operator + "'"; - - Cursor cursor = phone.getContext().getContentResolver().query( - Telephony.Carriers.CONTENT_URI, null, selection, null, null); - - if (cursor != null) { - if (cursor.getCount() > 0) { - allApns = createApnList(cursor); - // TODO: Figure out where this fits in. This basically just - // writes the pap-secrets file. No longer tied to PdpConnection - // object. Not used on current platform (no ppp). - //PdpConnection pdp = pdpList.get(pdp_name); - //if (pdp != null && pdp.dataLink != null) { - // pdp.dataLink.setPasswordInfo(cursor); - //} - } - cursor.close(); - } - } - - if (allApns.isEmpty()) { - if (DBG) log("No APN found for carrier: " + operator); - notifyNoData(PdpConnection.PdpFailCause.BAD_APN); - } - } - - private void createAllPdpList() { - pdpList = new ArrayList<PdpConnection>(); - PdpConnection pdp; - - for (int i = 0; i < PDP_CONNECTION_POOL_SIZE; i++) { - pdp = new PdpConnection(phone); - pdpList.add(pdp); - } - } - - /** - * - * @return waitingApns list to be used to create PDP - * error when waitingApns.isEmpty() - */ - private ArrayList<ApnSetting> buildWaitingApns() { - ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>(); - - if (allApns != null) { - for (ApnSetting apn : allApns) { - if (apn.canHandleType(mRequestedApnType)) { - apnList.add(apn); - } - } - } - return apnList; - } - - /** - * Get next apn in waitingApns - * @return the first apn found in waitingApns, null if none - */ - private ApnSetting getNextApn() { - ArrayList<ApnSetting> list = waitingApns; - ApnSetting apn = null; - - if (list != null) { - if (!list.isEmpty()) { - apn = list.get(0); - } - } - return apn; - } - - private String apnListToString (ArrayList<ApnSetting> apns) { - StringBuilder result = new StringBuilder(); - for (int i = 0, size = apns.size(); i < size; i++) { - result.append('[') - .append(apns.get(i).toString()) - .append(']'); - } - return result.toString(); - } - - private void startDelayedRetry(PdpConnection.PdpFailCause cause, String reason) { - notifyNoData(cause); - if (mRequestedApnType != Phone.APN_TYPE_DEFAULT) { - sendMessage(obtainMessage(EVENT_RESTORE_DEFAULT_APN)); - } - else { - reconnectAfterFail(cause, reason); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/DataLink.java b/telephony/java/com/android/internal/telephony/gsm/DataLink.java deleted file mode 100644 index b822ab4..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/DataLink.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2006 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.os.Handler; -import android.os.Registrant; - -/** - * Base class representing the data link layer (eg, PPP). - * - * {@hide} - */ -abstract class DataLink extends Handler implements DataLinkInterface { - - /** Registrant for link status change notifications. */ - Registrant mLinkChangeRegistrant; - - protected DataConnectionTracker dataConnection; - - DataLink(DataConnectionTracker dc) { - dataConnection = dc; - } - - public void setOnLinkChange(Handler h, int what, Object obj) { - mLinkChangeRegistrant = new Registrant(h, what, obj); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/DataLinkInterface.java b/telephony/java/com/android/internal/telephony/gsm/DataLinkInterface.java deleted file mode 100644 index bca63f2..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/DataLinkInterface.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2006 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.database.Cursor; -import android.os.Handler; - -/** - * Data link interface. - * - * {@hide} - */ -interface DataLinkInterface { - /** - * Link state enumeration. - * - */ - enum LinkState { - LINK_UNKNOWN, - LINK_UP, - LINK_DOWN, - LINK_EXITED - } - - /** Normal exit */ - final static int EXIT_OK = 0; - /** Open failed */ - final static int EXIT_OPEN_FAILED = 7; - - /** - * Sets the handler for link state change events. - * - * @param h Handler - * @param what User-defined message code - * @param obj User object - */ - void setOnLinkChange(Handler h, int what, Object obj); - - /** - * Sets up the data link. - */ - void connect(); - - /** - * Tears down the data link. - */ - void disconnect(); - - /** - * Returns the exit code for a data link failure. - * - * @return exit code - */ - int getLastLinkExitCode(); - - /** - * Sets password information that may be required by the data link - * (eg, PAP secrets). - * - * @param cursor cursor to carriers table - */ - void setPasswordInfo(Cursor cursor); -} diff --git a/telephony/java/com/android/internal/telephony/gsm/DriverCall.java b/telephony/java/com/android/internal/telephony/gsm/DriverCall.java deleted file mode 100644 index 178e661..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/DriverCall.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -import android.util.Log; -import java.lang.Comparable; -import android.telephony.PhoneNumberUtils; - -/** - * {@hide} - */ -public class DriverCall implements Comparable -{ - static final String LOG_TAG = "GSM"; - - public enum State { - ACTIVE, - HOLDING, - DIALING, // MO call only - ALERTING, // MO call only - INCOMING, // MT call only - WAITING; // MT call only - // If you add a state, make sure to look for the switch() - // statements that use this enum - }; - - public int index; - public boolean isMT; - public State state; // May be null if unavail - public boolean isMpty; - public String number; - public int TOA; - public boolean isVoice; - public int als; - - /** returns null on error */ - static DriverCall - fromCLCCLine(String line) - { - DriverCall ret = new DriverCall(); - - //+CLCC: 1,0,2,0,0,\"+18005551212\",145 - // index,isMT,state,mode,isMpty(,number,TOA)? - ATResponseParser p = new ATResponseParser(line); - - try { - ret.index = p.nextInt(); - ret.isMT = p.nextBoolean(); - ret.state = stateFromCLCC(p.nextInt()); - - ret.isVoice = (0 == p.nextInt()); - ret.isMpty = p.nextBoolean(); - - if (p.hasMore()) { - // Some lame implementations return strings - // like "NOT AVAILABLE" in the CLCC line - ret.number = PhoneNumberUtils.extractNetworkPortion( - p.nextString()); - - if (ret.number.length() == 0) { - ret.number = null; - } - - ret.TOA = p.nextInt(); - - // Make sure there's a leading + on addresses with a TOA - // of 145 - - ret.number = PhoneNumberUtils.stringFromStringAndTOA( - ret.number, ret.TOA); - - } - } catch (ATParseEx ex) { - Log.e(LOG_TAG,"Invalid CLCC line: '" + line + "'"); - return null; - } - - return ret; - } - - public - DriverCall() - { - } - - public String - toString() - { - return "id=" + index + "," - + (isMT ? "mt" : "mo") + "," - + state + "," - + (isVoice ? "voice" : "no_voc") + "," - + (isMpty ? "conf" : "norm") + "," - + TOA + "," + als; - } - - public static State - stateFromCLCC(int state) throws ATParseEx - { - switch(state) { - case 0: return State.ACTIVE; - case 1: return State.HOLDING; - case 2: return State.DIALING; - case 3: return State.ALERTING; - case 4: return State.INCOMING; - case 5: return State.WAITING; - default: - throw new ATParseEx("illegal call state " + state); - } - } - - //***** Comparable Implementation - - /** For sorting by index */ - public int - compareTo (Object o) - { - DriverCall dc; - - dc = (DriverCall)o; - - if (index < dc.index) { - return -1; - } else if (index == dc.index) { - return 0; - } else { /*index > dc.index*/ - return 1; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/EncodeException.java b/telephony/java/com/android/internal/telephony/gsm/EncodeException.java deleted file mode 100644 index d546cef..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/EncodeException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class EncodeException extends Exception -{ - public EncodeException() - { - super(); - } - - public EncodeException(String s) - { - super(s); - } - - public EncodeException(char c) - { - super("Unencodable char: '" + c + "'"); - } -} - diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMCall.java b/telephony/java/com/android/internal/telephony/gsm/GSMCall.java deleted file mode 100644 index 7179bb7..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/GSMCall.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -import java.util.ArrayList; -import java.util.List; - -/** - * {@hide} - */ -class GSMCall extends Call -{ - /*************************** Instance Variables **************************/ - - /*package*/ ArrayList<Connection> connections = new ArrayList<Connection>(); - /*package*/ State state = State.IDLE; - /*package*/ CallTracker owner; - - /***************************** Class Methods *****************************/ - - static State - stateFromDCState (DriverCall.State dcState) - { - switch (dcState) { - case ACTIVE: return State.ACTIVE; - case HOLDING: return State.HOLDING; - case DIALING: return State.DIALING; - case ALERTING: return State.ALERTING; - case INCOMING: return State.INCOMING; - case WAITING: return State.WAITING; - default: throw new RuntimeException ("illegal call state:" + dcState); - } - } - - - /****************************** Constructors *****************************/ - /*package*/ - GSMCall (CallTracker owner) - { - this.owner = owner; - } - - /************************** Overridden from Call *************************/ - - public List<Connection> - getConnections() - { - // FIXME should return Collections.unmodifiableList(); - return connections; - } - - public State - getState() - { - return state; - } - - public Phone - getPhone() - { - //TODO - return null; - } - - public boolean - isMultiparty() - { - return connections.size() > 1; - } - - /** Please note: if this is the foreground call and a - * background call exists, the background call will be resumed - * because an AT+CHLD=1 will be sent - */ - public void - hangup() throws CallStateException - { - owner.hangup(this); - } - - public String - toString() - { - return state.toString(); - } - - //***** Called from GSMConnection - - /*package*/ void - attach(GSMConnection conn, DriverCall dc) - { - connections.add(conn); - - state = stateFromDCState (dc.state); - } - - /*package*/ void - attachFake(GSMConnection conn, State state) - { - connections.add(conn); - - this.state = state; - } - - /** - * Called by GSMConnection when it has disconnected - */ - void - connectionDisconnected(GSMConnection conn) - { - if (state != State.DISCONNECTED) { - /* If only disconnected connections remain, we are disconnected*/ - - boolean hasOnlyDisconnectedConnections = true; - - for (int i = 0, s = connections.size() ; i < s; i ++) { - if (connections.get(i).getState() - != State.DISCONNECTED - ) { - hasOnlyDisconnectedConnections = false; - break; - } - } - - if (hasOnlyDisconnectedConnections) { - state = State.DISCONNECTED; - } - } - } - - - /*package*/ void - detach(GSMConnection conn) - { - connections.remove(conn); - - if (connections.size() == 0) { - state = State.IDLE; - } - } - - /*package*/ boolean - update (GSMConnection conn, DriverCall dc) - { - State newState; - boolean changed = false; - - newState = stateFromDCState(dc.state); - - if (newState != state) { - state = newState; - changed = true; - } - - return changed; - } - - /** - * @return true if there's no space in this call for additional - * connections to be added via "conference" - */ - /*package*/ boolean - isFull() - { - return connections.size() == CallTracker.MAX_CONNECTIONS_PER_CALL; - } - - //***** Called from CallTracker - - - /** - * Called when this Call is being hung up locally (eg, user pressed "end") - * Note that at this point, the hangup request has been dispatched to the radio - * but no response has yet been received so update() has not yet been called - */ - void - onHangupLocal() - { - for (int i = 0, s = connections.size() - ; i < s; i++ - ) { - GSMConnection cn = (GSMConnection)connections.get(i); - - cn.onHangupLocal(); - } - } - - /** - * Called when it's time to clean up disconnected Connection objects - */ - void - clearDisconnected() - { - for (int i = connections.size() - 1 ; i >= 0 ; i--) { - GSMConnection cn = (GSMConnection)connections.get(i); - - if (cn.getState() == State.DISCONNECTED) { - connections.remove(i); - } - } - - if (connections.size() == 0) { - state = State.IDLE; - } - } -} - diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMConnection.java b/telephony/java/com/android/internal/telephony/gsm/GSMConnection.java deleted file mode 100644 index a503766..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/GSMConnection.java +++ /dev/null @@ -1,749 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -import android.content.Context; -import android.os.Handler; -import android.os.PowerManager; -import android.os.Registrant; -import android.os.Looper; -import android.os.Message; -import android.os.AsyncResult; -import android.os.SystemClock; -import android.util.Log; -import android.util.Config; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; - -/** - * {@hide} - */ -public class GSMConnection extends Connection { - static final String LOG_TAG = "GSM"; - - //***** Instance Variables - - CallTracker owner; - GSMCall parent; - - String address; // MAY BE NULL!!! - String dialString; // outgoing calls only - String postDialString; // outgoing calls only - boolean isIncoming; - boolean disconnected; - - int index; // index in CallTracker.connections[], -1 if unassigned - // The GSM index is 1 + this - - /* - * These time/timespan values are based on System.currentTimeMillis(), - * i.e., "wall clock" time. - */ - long createTime; - long connectTime; - long disconnectTime; - - /* - * These time/timespan values are based on SystemClock.elapsedRealTime(), - * i.e., time since boot. They are appropriate for comparison and - * calculating deltas. - */ - long connectTimeReal; - long duration; - long holdingStartTime; // The time when the Connection last transitioned - // into HOLDING - - int nextPostDialChar; // index into postDialString - - DisconnectCause cause = DisconnectCause.NOT_DISCONNECTED; - PostDialState postDialState = PostDialState.NOT_STARTED; - - Handler h; - - private PowerManager.WakeLock mPartialWakeLock; - - //***** Event Constants - static final int EVENT_DTMF_DONE = 1; - static final int EVENT_PAUSE_DONE = 2; - static final int EVENT_NEXT_POST_DIAL = 3; - static final int EVENT_WAKE_LOCK_TIMEOUT = 4; - - //***** Constants - static final int PAUSE_DELAY_FIRST_MILLIS = 100; - static final int PAUSE_DELAY_MILLIS = 3 * 1000; - static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000; - - //***** Inner Classes - - class MyHandler extends Handler { - MyHandler(Looper l) {super(l);} - - public void - handleMessage(Message msg) - { - switch (msg.what) { - case EVENT_NEXT_POST_DIAL: - case EVENT_DTMF_DONE: - case EVENT_PAUSE_DONE: - processNextPostDialChar(); - break; - case EVENT_WAKE_LOCK_TIMEOUT: - releaseWakeLock(); - break; - } - } - } - - //***** Constructors - - /** This is probably an MT call that we first saw in a CLCC response */ - /*package*/ - GSMConnection (Context context, DriverCall dc, CallTracker ct, int index) - { - createWakeLock(context); - acquireWakeLock(); - - owner = ct; - h = new MyHandler(owner.getLooper()); - - address = dc.number; - - isIncoming = dc.isMT; - createTime = System.currentTimeMillis(); - - this.index = index; - - parent = parentFromDCState (dc.state); - parent.attach(this, dc); - } - - /** This is an MO call, created when dialing */ - /*package*/ - GSMConnection (Context context, String dialString, CallTracker ct, GSMCall parent) - { - createWakeLock(context); - acquireWakeLock(); - - owner = ct; - h = new MyHandler(owner.getLooper()); - - this.dialString = dialString; - - this.address = PhoneNumberUtils.extractNetworkPortion(dialString); - this.postDialString = PhoneNumberUtils.extractPostDialPortion(dialString); - - index = -1; - - isIncoming = false; - createTime = System.currentTimeMillis(); - - this.parent = parent; - parent.attachFake(this, Call.State.DIALING); - } - - static boolean - equalsHandlesNulls (Object a, Object b) - { - return (a == null) ? (b == null) : a.equals (b); - } - - /*package*/ boolean - compareTo(DriverCall c) - { - // On mobile originated (MO) calls, the phone number may have changed - // due to a SIM Toolkit call control modification. - // - // We assume we know when MO calls are created (since we created them) - // and therefore don't need to compare the phone number anyway. - if (! (isIncoming || c.isMT)) return true; - - // ... but we can compare phone numbers on MT calls, and we have - // no control over when they begin, so we might as well - - String cAddress = PhoneNumberUtils.stringFromStringAndTOA(c.number, c.TOA); - return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress); - } - - public String - toString() - { - return (isIncoming ? "incoming" : "outgoing"); - } - - public String getAddress() - { - return address; - } - - - public Call getCall() - { - return parent; - } - - public long getCreateTime() - { - return createTime; - } - - public long getConnectTime() - { - return connectTime; - } - - public long getDisconnectTime() - { - return disconnectTime; - } - - public long getDurationMillis() - { - if (connectTimeReal == 0) { - return 0; - } else if (duration == 0) { - return SystemClock.elapsedRealtime() - connectTimeReal; - } else { - return duration; - } - } - - public long getHoldDurationMillis() - { - if (getState() != Call.State.HOLDING) { - // If not holding, return 0 - return 0; - } else { - return SystemClock.elapsedRealtime() - holdingStartTime; - } - } - - public DisconnectCause getDisconnectCause() - { - return cause; - } - - public boolean isIncoming() - { - return isIncoming; - } - - public Call.State getState() - { - if (disconnected) { - return Call.State.DISCONNECTED; - } else { - return super.getState(); - } - } - - public void hangup() throws CallStateException - { - if (!disconnected) { - owner.hangup(this); - } else { - throw new CallStateException ("disconnected"); - } - } - - public void separate() throws CallStateException - { - if (!disconnected) { - owner.separate(this); - } else { - throw new CallStateException ("disconnected"); - } - } - - public PostDialState getPostDialState() - { - return postDialState; - } - - public void proceedAfterWaitChar() - { - if (postDialState != PostDialState.WAIT) { - Log.w(LOG_TAG, "Connection.proceedAfterWaitChar(): Expected " - + "getPostDialState() to be WAIT but was " + postDialState); - return; - } - - setPostDialState(PostDialState.STARTED); - - processNextPostDialChar(); - } - - public void proceedAfterWildChar(String str) { - if (postDialState != PostDialState.WILD) { - Log.w(LOG_TAG, "Connection.proceedAfterWaitChar(): Expected " - + "getPostDialState() to be WILD but was " + postDialState); - return; - } - - setPostDialState(PostDialState.STARTED); - - if (false) { - boolean playedTone = false; - int len = (str != null ? str.length() : 0); - - for (int i=0; i<len; i++) { - char c = str.charAt(i); - Message msg = null; - - if (i == len-1) { - msg = h.obtainMessage(EVENT_DTMF_DONE); - } - - if (PhoneNumberUtils.is12Key(c)) { - owner.cm.sendDtmf(c, msg); - playedTone = true; - } - } - - if (!playedTone) { - processNextPostDialChar(); - } - } else { - // make a new postDialString, with the wild char replacement string - // at the beginning, followed by the remaining postDialString. - - StringBuilder buf = new StringBuilder(str); - buf.append(postDialString.substring(nextPostDialChar)); - postDialString = buf.toString(); - nextPostDialChar = 0; - if (Phone.DEBUG_PHONE) { - log("proceedAfterWildChar: new postDialString is " + - postDialString); - } - - processNextPostDialChar(); - } - } - - public void cancelPostDial() - { - setPostDialState(PostDialState.CANCELLED); - } - - /** - * Called when this Connection is being hung up locally (eg, user pressed "end") - * Note that at this point, the hangup request has been dispatched to the radio - * but no response has yet been received so update() has not yet been called - */ - void - onHangupLocal() - { - cause = DisconnectCause.LOCAL; - } - - DisconnectCause - disconnectCauseFromCode(int causeCode) - { - /** - * See 22.001 Annex F.4 for mapping of cause codes - * to local tones - */ - - switch (causeCode) { - case CallFailCause.USER_BUSY: - return DisconnectCause.BUSY; - - case CallFailCause.NO_CIRCUIT_AVAIL: - case CallFailCause.TEMPORARY_FAILURE: - case CallFailCause.SWITCHING_CONGESTION: - case CallFailCause.CHANNEL_NOT_AVAIL: - case CallFailCause.QOS_NOT_AVAIL: - case CallFailCause.BEARER_NOT_AVAIL: - return DisconnectCause.CONGESTION; - - case CallFailCause.ACM_LIMIT_EXCEEDED: - return DisconnectCause.LIMIT_EXCEEDED; - - case CallFailCause.CALL_BARRED: - return DisconnectCause.CALL_BARRED; - - case CallFailCause.FDN_BLOCKED: - return DisconnectCause.FDN_BLOCKED; - - case CallFailCause.ERROR_UNSPECIFIED: - case CallFailCause.NORMAL_CLEARING: - default: - GSMPhone phone = owner.phone; - int serviceState = phone.getServiceState().getState(); - if (serviceState == ServiceState.STATE_POWER_OFF) { - return DisconnectCause.POWER_OFF; - } else if (serviceState == ServiceState.STATE_OUT_OF_SERVICE - || serviceState == ServiceState.STATE_EMERGENCY_ONLY ) { - return DisconnectCause.OUT_OF_SERVICE; - } else if (phone.getSimCard().getState() != GsmSimCard.State.READY) { - return DisconnectCause.SIM_ERROR; - } else { - return DisconnectCause.NORMAL; - } - } - } - - /*package*/ void - onRemoteDisconnect(int causeCode) - { - onDisconnect(disconnectCauseFromCode(causeCode)); - } - - /** Called when the radio indicates the connection has been disconnected */ - /*package*/ void - onDisconnect(DisconnectCause cause) - { - this.cause = cause; - - if (!disconnected) { - index = -1; - - disconnectTime = System.currentTimeMillis(); - duration = SystemClock.elapsedRealtime() - connectTimeReal; - disconnected = true; - - if (Config.LOGD) Log.d(LOG_TAG, - "[GSMConn] onDisconnect: cause=" + cause); - - owner.phone.notifyDisconnect(this); - - if (parent != null) { - parent.connectionDisconnected(this); - } - } - releaseWakeLock(); - } - - // Returns true if state has changed, false if nothing changed - /*package*/ boolean - update (DriverCall dc) { - GSMCall newParent; - boolean changed = false; - boolean wasConnectingInOrOut = isConnectingInOrOut(); - boolean wasHolding = (getState() == Call.State.HOLDING); - - newParent = parentFromDCState(dc.state); - - if (!equalsHandlesNulls(address, dc.number)) { - if (Phone.DEBUG_PHONE) log("update: phone # changed!"); - address = dc.number; - changed = true; - } - - if (newParent != parent) { - if (parent != null) { - parent.detach(this); - } - newParent.attach(this, dc); - parent = newParent; - changed = true; - } else { - boolean parentStateChange; - parentStateChange = parent.update (this, dc); - changed = changed || parentStateChange; - } - - /** Some state-transition events */ - - if (Phone.DEBUG_PHONE) log( - "update: parent=" + parent + - ", hasNewParent=" + (newParent != parent) + - ", wasConnectingInOrOut=" + wasConnectingInOrOut + - ", wasHolding=" + wasHolding + - ", isConnectingInOrOut=" + isConnectingInOrOut() + - ", changed=" + changed); - - - if (wasConnectingInOrOut && !isConnectingInOrOut()) { - onConnectedInOrOut(); - } - - if (changed && !wasHolding && (getState() == Call.State.HOLDING)) { - // We've transitioned into HOLDING - onStartedHolding(); - } - - return changed; - } - - /** - * Called when this Connection is in the foregroundCall - * when a dial is initiated. - * We know we're ACTIVE, and we know we're going to end up - * HOLDING in the backgroundCall - */ - void - fakeHoldBeforeDial() - { - if (parent != null) { - parent.detach(this); - } - - parent = owner.backgroundCall; - parent.attachFake(this, Call.State.HOLDING); - - onStartedHolding(); - } - - /*package*/ int - getGSMIndex() throws CallStateException { - if (index >= 0) { - return index + 1; - } else { - throw new CallStateException ("GSM index not yet assigned"); - } - } - - /** - * An incoming or outgoing call has connected - */ - void - onConnectedInOrOut() { - connectTime = System.currentTimeMillis(); - connectTimeReal = SystemClock.elapsedRealtime(); - duration = 0; - - // bug #678474: incoming call interpreted as missed call, even though - // it sounds like the user has picked up the call. - if (Phone.DEBUG_PHONE) { - log("onConnectedInOrOut: connectTime=" + connectTime); - } - - if (!isIncoming) { - // outgoing calls only - processNextPostDialChar(); - } - releaseWakeLock(); - } - - private void - onStartedHolding() { - holdingStartTime = SystemClock.elapsedRealtime(); - } - /** - * Performs the appropriate action for a post-dial char, but does not - * notify application. returns false if the character is invalid and - * should be ignored - */ - private boolean - processPostDialChar(char c) - { - if (PhoneNumberUtils.is12Key(c)) { - owner.cm.sendDtmf(c, h.obtainMessage(EVENT_DTMF_DONE)); - } else if (c == PhoneNumberUtils.PAUSE) { - // From TS 22.101: - - // "The first occurrence of the "DTMF Control Digits Separator" - // shall be used by the ME to distinguish between the addressing - // digits (i.e. the phone number) and the DTMF digits...." - - if (nextPostDialChar == 1) { - // The first occurrence. - // We don't need to pause here, but wait for just a bit anyway - h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE), - PAUSE_DELAY_FIRST_MILLIS); - } else { - // It continues... - // "Upon subsequent occurrences of the separator, the UE shall - // pause again for 3 seconds (\u00B1 20 %) before sending any - // further DTMF digits." - h.sendMessageDelayed(h.obtainMessage(EVENT_PAUSE_DONE), - PAUSE_DELAY_MILLIS); - } - } else if (c == PhoneNumberUtils.WAIT) { - setPostDialState(PostDialState.WAIT); - } else if (c == PhoneNumberUtils.WILD) { - setPostDialState(PostDialState.WILD); - } else { - return false; - } - - return true; - } - - public String - getRemainingPostDialString() - { - if (postDialState == PostDialState.CANCELLED - || postDialState == PostDialState.COMPLETE - || postDialString == null - || postDialString.length() <= nextPostDialChar - ) { - return ""; - } - - return postDialString.substring(nextPostDialChar); - } - - @Override - protected void finalize() - { - /** - * It is understood that This finializer is not guaranteed - * to be called and the release lock call is here just in - * case there is some path that doesn't call onDisconnect - * and or onConnectedInOrOut. - */ - if (mPartialWakeLock.isHeld()) { - Log.e(LOG_TAG, "[GSMConn] UNEXPECTED; mPartialWakeLock is held when finalizing."); - } - releaseWakeLock(); - } - - private void - processNextPostDialChar() - { - char c = 0; - Registrant postDialHandler; - - if (postDialState == PostDialState.CANCELLED) { - //Log.v("GSM", "##### processNextPostDialChar: postDialState == CANCELLED, bail"); - return; - } - - if (postDialString == null || - postDialString.length() <= nextPostDialChar) { - setPostDialState(PostDialState.COMPLETE); - - // notifyMessage.arg1 is 0 on complete - c = 0; - } else { - boolean isValid; - - setPostDialState(PostDialState.STARTED); - - c = postDialString.charAt(nextPostDialChar++); - - isValid = processPostDialChar(c); - - if (!isValid) { - // Will call processNextPostDialChar - h.obtainMessage(EVENT_NEXT_POST_DIAL).sendToTarget(); - // Don't notify application - Log.e("GSM", "processNextPostDialChar: c=" + c + " isn't valid!"); - return; - } - } - - postDialHandler = owner.phone.mPostDialHandler; - - Message notifyMessage; - - if (postDialHandler != null && (notifyMessage = postDialHandler.messageForRegistrant()) != null) { - // The AsyncResult.result is the Connection object - PostDialState state = postDialState; - AsyncResult ar = AsyncResult.forMessage(notifyMessage); - ar.result = this; - ar.userObj = state; - - // arg1 is the character that was/is being processed - notifyMessage.arg1 = c; - - //Log.v("GSM", "##### processNextPostDialChar: send msg to postDialHandler, arg1=" + c); - notifyMessage.sendToTarget(); - } - /* - else { - if (postDialHandler == null) - Log.v("GSM", "##### processNextPostDialChar: postDialHandler is NULL!"); - else - Log.v("GSM", "##### processNextPostDialChar: postDialHandler.messageForRegistrant() returned NULL!"); - } - */ - } - - - /** "connecting" means "has never been ACTIVE" for both incoming - * and outgoing calls - */ - private boolean - isConnectingInOrOut() - { - return parent == null || parent == owner.ringingCall - || parent.state == Call.State.DIALING - || parent.state == Call.State.ALERTING; - } - - private GSMCall - parentFromDCState (DriverCall.State state) - { - switch (state) { - case ACTIVE: - case DIALING: - case ALERTING: - return owner.foregroundCall; - //break; - - case HOLDING: - return owner.backgroundCall; - //break; - - case INCOMING: - case WAITING: - return owner.ringingCall; - //break; - - default: - throw new RuntimeException("illegal call state: " + state); - } - } - - /** - * Set post dial state and acquire wake lock while switching to "started" - * state, the wake lock will be released if state switches out of "started" - * state or after WAKE_LOCK_TIMEOUT_MILLIS. - * @param s new PostDialState - */ - private void setPostDialState(PostDialState s) { - if (postDialState != PostDialState.STARTED - && s == PostDialState.STARTED) { - acquireWakeLock(); - Message msg = h.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT); - h.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT_MILLIS); - } else if (postDialState == PostDialState.STARTED - && s != PostDialState.STARTED) { - h.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); - releaseWakeLock(); - } - postDialState = s; - } - - private void - createWakeLock(Context context) { - PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); - } - - private void - acquireWakeLock() { - log("acquireWakeLock"); - mPartialWakeLock.acquire(); - } - - private void - releaseWakeLock() { - synchronized(mPartialWakeLock) { - if (mPartialWakeLock.isHeld()) { - log("releaseWakeLock"); - mPartialWakeLock.release(); - } - } - } - - private void log(String msg) { - Log.d(LOG_TAG, "[GSMConn] " + msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java deleted file mode 100644 index 4ad65fc..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ /dev/null @@ -1,1635 +0,0 @@ -/* - * Copyright (C) 2006 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 static com.android.internal.telephony.TelephonyProperties.PROPERTY_BASEBAND_VERSION; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_ACTION_DISABLE; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_ACTION_ENABLE; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_ACTION_ERASURE; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_ACTION_REGISTRATION; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_REASON_ALL; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_REASON_ALL_CONDITIONAL; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_REASON_BUSY; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_REASON_NOT_REACHABLE; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_REASON_NO_REPLY; -import static com.android.internal.telephony.gsm.CommandsInterface.CF_REASON_UNCONDITIONAL; -import static com.android.internal.telephony.gsm.CommandsInterface.SERVICE_CLASS_VOICE; -import android.content.ContentValues; -import android.content.Context; -import android.content.SharedPreferences; -import android.database.SQLException; -import android.net.Uri; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemProperties; -import android.preference.PreferenceManager; -import android.provider.Telephony; -import android.telephony.CellLocation; -import android.telephony.PhoneNumberUtils; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.Log; - -import com.android.internal.telephony.Call; -import com.android.internal.telephony.CallStateException; -import com.android.internal.telephony.Connection; -import com.android.internal.telephony.MmiCode; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneBase; -import com.android.internal.telephony.PhoneNotifier; -import com.android.internal.telephony.PhoneSubInfo; -import com.android.internal.telephony.SimCard; -import com.android.internal.telephony.gsm.SimException; -import com.android.internal.telephony.gsm.stk.StkService; -import com.android.internal.telephony.test.SimulatedRadioControl; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; - -/** - * {@hide} - */ -public class GSMPhone extends PhoneBase { - // NOTE that LOG_TAG here is "GSM", which means that log messages - // from this file will go into the radio log rather than the main - // log. (Use "adb logcat -b radio" to see them.) - static final String LOG_TAG = "GSM"; - private static final boolean LOCAL_DEBUG = false; - - // Key used to read and write the saved network selection value - public static final String NETWORK_SELECTION_KEY = "network_selection_key"; - // Key used to read/write "disable data connection on boot" pref (used for testing) - public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key"; - // Key used to read/write current ciphering state - public static final String CIPHERING_KEY = "ciphering_key"; - // Key used to read/write current CLIR setting - public static final String CLIR_KEY = "clir_key"; - // Key used to read/write voice mail number - public static final String VM_NUMBER = "vm_number_key"; - // Key used to read/write the SIM IMSI used for storing the voice mail - public static final String VM_SIM_IMSI = "vm_sim_imsi_key"; - // Key used to read/write "disable DNS server check" pref (used for testing) - public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key"; - - //***** Instance Variables - - CallTracker mCT; - ServiceStateTracker mSST; - CommandsInterface mCM; - SMSDispatcher mSMS; - DataConnectionTracker mDataConnection; - SIMFileHandler mSIMFileHandler; - SIMRecords mSIMRecords; - GsmSimCard mSimCard; - StkService mStkService; - MyHandler h; - ArrayList <GsmMmiCode> mPendingMMIs = new ArrayList<GsmMmiCode>(); - SimPhoneBookInterfaceManager mSimPhoneBookIntManager; - SimSmsInterfaceManager mSimSmsIntManager; - PhoneSubInfo mSubInfo; - boolean mDnsCheckDisabled = false; - - - Registrant mPostDialHandler; - - /** List of Registrants to receive Supplementary Service Notifications. */ - RegistrantList mSsnRegistrants = new RegistrantList(); - - Thread debugPortThread; - ServerSocket debugSocket; - - private int mReportedRadioResets; - private int mReportedAttemptedConnects; - private int mReportedSuccessfulConnects; - - private String mImei; - private String mImeiSv; - private String mVmNumber; - - //***** Event Constants - - static final int EVENT_RADIO_AVAILABLE = 1; - /** Supplemnetary Service Notification received. */ - static final int EVENT_SSN = 2; - static final int EVENT_SIM_RECORDS_LOADED = 3; - static final int EVENT_MMI_DONE = 4; - static final int EVENT_RADIO_ON = 5; - static final int EVENT_GET_BASEBAND_VERSION_DONE = 6; - static final int EVENT_USSD = 7; - static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8; - static final int EVENT_GET_IMEI_DONE = 9; - static final int EVENT_GET_IMEISV_DONE = 10; - static final int EVENT_GET_SIM_STATUS_DONE = 11; - static final int EVENT_SET_CALL_FORWARD_DONE = 12; - static final int EVENT_GET_CALL_FORWARD_DONE = 13; - static final int EVENT_CALL_RING = 14; - // Used to intercept the carriere selection calls so that - // we can save the values. - static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 15; - static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 16; - static final int EVENT_SET_CLIR_COMPLETE = 17; - static final int EVENT_REGISTERED_TO_NETWORK = 18; - static final int EVENT_SET_VM_NUMBER_DONE = 19; - - //***** Constructors - - public - GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier) - { - this(context,ci,notifier, false); - } - - public - GSMPhone (Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode) - { - super(notifier, context, unitTestMode); - - h = new MyHandler(); - mCM = ci; - - if (ci instanceof SimulatedRadioControl) { - mSimulatedRadioControl = (SimulatedRadioControl) ci; - } - - mCT = new CallTracker(this); - mSST = new ServiceStateTracker (this); - mSMS = new SMSDispatcher(this); - mSIMFileHandler = new SIMFileHandler(this); - mSIMRecords = new SIMRecords(this); - mDataConnection = new DataConnectionTracker (this); - mSimCard = new GsmSimCard(this); - if (!unitTestMode) { - mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this); - mSimSmsIntManager = new SimSmsInterfaceManager(this); - mSubInfo = new PhoneSubInfo(this); - } - mStkService = StkService.getInstance(mCM, mSIMRecords, mContext, - mSIMFileHandler, mSimCard); - - mCM.registerForAvailable(h, EVENT_RADIO_AVAILABLE, null); - mSIMRecords.registerForRecordsLoaded(h, EVENT_SIM_RECORDS_LOADED, null); - mCM.registerForOffOrNotAvailable(h, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, - null); - mCM.registerForOn(h, EVENT_RADIO_ON, null); - mCM.setOnUSSD(h, EVENT_USSD, null); - mCM.setOnSuppServiceNotification(h, EVENT_SSN, null); - mCM.setOnCallRing(h, EVENT_CALL_RING, null); - mSST.registerForNetworkAttach(h, EVENT_REGISTERED_TO_NETWORK, null); - - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); - mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); - - if (false) { - try { - //debugSocket = new LocalServerSocket("com.android.internal.telephony.debug"); - debugSocket = new ServerSocket(); - debugSocket.setReuseAddress(true); - debugSocket.bind (new InetSocketAddress("127.0.0.1", 6666)); - - debugPortThread - = new Thread( - new Runnable() { - public void run() { - for(;;) { - try { - Socket sock; - sock = debugSocket.accept(); - Log.i(LOG_TAG, "New connection; resetting radio"); - mCM.resetRadio(null); - sock.close(); - } catch (IOException ex) { - Log.w(LOG_TAG, - "Exception accepting socket", ex); - } - } - } - }, - "GSMPhone debug"); - - debugPortThread.start(); - - } catch (IOException ex) { - Log.w(LOG_TAG, "Failure to open com.android.internal.telephony.debug socket", ex); - } - } - } - - //***** Overridden from Phone - - public ServiceState - getServiceState() - { - return mSST.ss; - } - - public CellLocation getCellLocation() { - return mSST.cellLoc; - } - - public Phone.State - getState() - { - return mCT.state; - } - - public String - getPhoneName() - { - return "GSM"; - } - - public String[] getActiveApnTypes() { - return mDataConnection.getActiveApnTypes(); - } - - public String getActiveApn() { - return mDataConnection.getActiveApnString(); - } - - public int - getSignalStrengthASU() - { - return mSST.rssi == 99 ? -1 : mSST.rssi; - } - - public boolean - getMessageWaitingIndicator() - { - return mSIMRecords.getVoiceMessageWaiting(); - } - - public boolean - getCallForwardingIndicator() { - return mSIMRecords.getVoiceCallForwardingFlag(); - } - - public List<? extends MmiCode> - getPendingMmiCodes() - { - return mPendingMMIs; - } - - public DataState getDataConnectionState() { - DataState ret = DataState.DISCONNECTED; - - if ((SystemProperties.get("adb.connected", "").length() > 0) - && (SystemProperties.get("android.net.use-adb-networking", "") - .length() > 0)) { - // We're connected to an ADB host and we have USB networking - // turned on. No matter what the radio state is, - // we report data connected - - ret = DataState.CONNECTED; - } else if (mSST.getCurrentGprsState() - != ServiceState.STATE_IN_SERVICE) { - // If we're out of service, open TCP sockets may still work - // but no data will flow - ret = DataState.DISCONNECTED; - } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */ - switch (mDataConnection.state) { - case FAILED: - case IDLE: - ret = DataState.DISCONNECTED; - break; - - case CONNECTED: - case DISCONNECTING: - if ( mCT.state != Phone.State.IDLE - && !mSST.isConcurrentVoiceAndData()) { - ret = DataState.SUSPENDED; - } else { - ret = DataState.CONNECTED; - } - break; - - case INITING: - case CONNECTING: - case SCANNING: - ret = DataState.CONNECTING; - break; - } - } - - return ret; - } - - public DataActivityState getDataActivityState() { - DataActivityState ret = DataActivityState.NONE; - - if (mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE) { - switch (mDataConnection.activity) { - - case DATAIN: - ret = DataActivityState.DATAIN; - break; - - case DATAOUT: - ret = DataActivityState.DATAOUT; - break; - - case DATAINANDOUT: - ret = DataActivityState.DATAINANDOUT; - break; - } - } - - return ret; - } - - /** - * Notify any interested party of a Phone state change. - */ - /*package*/ void notifyPhoneStateChanged() { - mNotifier.notifyPhoneState(this); - } - - /** - * Notifies registrants (ie, activities in the Phone app) about - * changes to call state (including Phone and Connection changes). - */ - /*package*/ void - notifyCallStateChanged() - { - /* we'd love it if this was package-scoped*/ - super.notifyCallStateChangedP(); - } - - /*package*/ void - notifyNewRingingConnection(Connection c) - { - /* we'd love it if this was package-scoped*/ - super.notifyNewRingingConnectionP(c); - } - - /** - * Notifiy registrants of a RING event. - */ - void notifyIncomingRing() { - AsyncResult ar = new AsyncResult(null, this, null); - mIncomingRingRegistrants.notifyRegistrants(ar); - } - - /*package*/ void - notifyDisconnect(Connection cn) - { - mDisconnectRegistrants.notifyResult(cn); - } - - void notifyUnknownConnection() { - mUnknownConnectionRegistrants.notifyResult(this); - } - - void notifySuppServiceFailed(SuppService code) { - mSuppServiceFailedRegistrants.notifyResult(code); - } - - /*package*/ void - notifyServiceStateChanged(ServiceState ss) - { - super.notifyServiceStateChangedP(ss); - } - - /*package*/ - void notifyLocationChanged() { - mNotifier.notifyCellLocation(this); - } - - /*package*/ void - notifySignalStrength() - { - mNotifier.notifySignalStrength(this); - } - - /*package*/ void - notifyDataConnection(String reason) { - mNotifier.notifyDataConnection(this, reason); - } - - /*package*/ void - notifyDataConnectionFailed(String reason) { - mNotifier.notifyDataConnectionFailed(this, reason); - } - - /*package*/ void - notifyDataActivity() { - mNotifier.notifyDataActivity(this); - } - - /*package*/ void - updateMessageWaitingIndicator(boolean mwi) - { - // this also calls notifyMessageWaitingIndicator() - mSIMRecords.setVoiceMessageWaiting(1, mwi ? -1 : 0); - } - - /*package*/ void - notifyMessageWaitingIndicator() - { - mNotifier.notifyMessageWaitingChanged(this); - } - - /*package*/ void - notifyCallForwardingIndicator() { - mNotifier.notifyCallForwardingChanged(this); - } - - /** - * Set a system property, unless we're in unit test mode - */ - - /*package*/ void - setSystemProperty(String property, String value) - { - if(getUnitTestMode()) { - return; - } - SystemProperties.set(property, value); - } - - public void registerForSuppServiceNotification( - Handler h, int what, Object obj) { - mSsnRegistrants.addUnique(h, what, obj); - if (mSsnRegistrants.size() == 1) mCM.setSuppServiceNotifications(true, null); - } - - public void unregisterForSuppServiceNotification(Handler h) { - mSsnRegistrants.remove(h); - if (mSsnRegistrants.size() == 0) mCM.setSuppServiceNotifications(false, null); - } - - public void - acceptCall() throws CallStateException - { - mCT.acceptCall(); - } - - public void - rejectCall() throws CallStateException - { - mCT.rejectCall(); - } - - public void - switchHoldingAndActive() throws CallStateException - { - mCT.switchWaitingOrHoldingAndActive(); - } - - - public boolean canConference() - { - return mCT.canConference(); - } - - public boolean canDial() - { - return mCT.canDial(); - } - - public void conference() throws CallStateException - { - mCT.conference(); - } - - public void clearDisconnected() - { - - mCT.clearDisconnected(); - } - - public boolean canTransfer() - { - return mCT.canTransfer(); - } - - public void explicitCallTransfer() throws CallStateException - { - mCT.explicitCallTransfer(); - } - - public Call - getForegroundCall() - { - return mCT.foregroundCall; - } - - public Call - getBackgroundCall() - { - return mCT.backgroundCall; - } - - public Call - getRingingCall() - { - return mCT.ringingCall; - } - - private boolean handleCallDeflectionIncallSupplementaryService( - String dialString) throws CallStateException { - if (dialString.length() > 1) { - return false; - } - - if (getRingingCall().getState() != Call.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 0: rejectCall"); - try { - mCT.rejectCall(); - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "reject failed", e); - notifySuppServiceFailed(Phone.SuppService.REJECT); - } - } else if (getBackgroundCall().getState() != Call.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 0: hangupWaitingOrBackground"); - mCT.hangupWaitingOrBackground(); - } - - return true; - } - - private boolean handleCallWaitingIncallSupplementaryService( - String dialString) throws CallStateException { - int len = dialString.length(); - - if (len > 2) { - return false; - } - - GSMCall call = (GSMCall) getForegroundCall(); - - try { - if (len > 1) { - char ch = dialString.charAt(1); - int callIndex = ch - '0'; - - if (callIndex >= 1 && callIndex <= CallTracker.MAX_CONNECTIONS) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 1: hangupConnectionByIndex " + - callIndex); - mCT.hangupConnectionByIndex(call, callIndex); - } - } else { - if (call.getState() != Call.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 1: hangup foreground"); - //mCT.hangupForegroundResumeBackground(); - mCT.hangup(call); - } else { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 1: switchWaitingOrHoldingAndActive"); - mCT.switchWaitingOrHoldingAndActive(); - } - } - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "hangup failed", e); - notifySuppServiceFailed(Phone.SuppService.HANGUP); - } - - return true; - } - - private boolean handleCallHoldIncallSupplementaryService(String dialString) - throws CallStateException { - int len = dialString.length(); - - if (len > 2) { - return false; - } - - GSMCall call = (GSMCall) getForegroundCall(); - - if (len > 1) { - try { - char ch = dialString.charAt(1); - int callIndex = ch - '0'; - GSMConnection conn = mCT.getConnectionByIndex(call, callIndex); - - // gsm index starts at 1, up to 5 connections in a call, - if (conn != null && callIndex >= 1 && callIndex <= CallTracker.MAX_CONNECTIONS) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 2: separate call "+ - callIndex); - mCT.separate(conn); - } else { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "separate: invalid call index "+ - callIndex); - notifySuppServiceFailed(Phone.SuppService.SEPARATE); - } - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "separate failed", e); - notifySuppServiceFailed(Phone.SuppService.SEPARATE); - } - } else { - try { - if (getRingingCall().getState() != Call.State.IDLE) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 2: accept ringing call"); - mCT.acceptCall(); - } else { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "MmiCode 2: switchWaitingOrHoldingAndActive"); - mCT.switchWaitingOrHoldingAndActive(); - } - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "switch failed", e); - notifySuppServiceFailed(Phone.SuppService.SWITCH); - } - } - - return true; - } - - private boolean handleMultipartyIncallSupplementaryService( - String dialString) throws CallStateException { - if (dialString.length() > 1) { - return false; - } - - if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 3: merge calls"); - try { - conference(); - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "conference failed", e); - notifySuppServiceFailed(Phone.SuppService.CONFERENCE); - } - return true; - } - - private boolean handleEctIncallSupplementaryService(String dialString) - throws CallStateException { - - int len = dialString.length(); - - if (len != 1) { - return false; - } - - if (LOCAL_DEBUG) Log.d(LOG_TAG, "MmiCode 4: explicit call transfer"); - try { - explicitCallTransfer(); - } catch (CallStateException e) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "transfer failed", e); - notifySuppServiceFailed(Phone.SuppService.TRANSFER); - } - return true; - } - - private boolean handleCcbsIncallSupplementaryService(String dialString) - throws CallStateException { - if (dialString.length() > 1) { - return false; - } - - Log.i(LOG_TAG, "MmiCode 5: CCBS not supported!"); - // Treat it as an "unknown" service. - notifySuppServiceFailed(Phone.SuppService.UNKNOWN); - return true; - } - - public boolean handleInCallMmiCommands(String dialString) - throws CallStateException { - if (!isInCall()) { - return false; - } - - if (TextUtils.isEmpty(dialString)) { - return false; - } - - boolean result = false; - char ch = dialString.charAt(0); - switch (ch) { - case '0': - result = handleCallDeflectionIncallSupplementaryService( - dialString); - break; - case '1': - result = handleCallWaitingIncallSupplementaryService( - dialString); - break; - case '2': - result = handleCallHoldIncallSupplementaryService(dialString); - break; - case '3': - result = handleMultipartyIncallSupplementaryService(dialString); - break; - case '4': - result = handleEctIncallSupplementaryService(dialString); - break; - case '5': - result = handleCcbsIncallSupplementaryService(dialString); - break; - default: - break; - } - - return result; - } - - boolean isInCall() { - Call.State foregroundCallState = getForegroundCall().getState(); - Call.State backgroundCallState = getBackgroundCall().getState(); - Call.State ringingCallState = getRingingCall().getState(); - - return (foregroundCallState.isAlive() || - backgroundCallState.isAlive() || - ringingCallState.isAlive()); - } - - public Connection - dial (String dialString) throws CallStateException { - // Need to make sure dialString gets parsed properly - String newDialString = PhoneNumberUtils.stripSeparators(dialString); - - // handle in-call MMI first if applicable - if (handleInCallMmiCommands(newDialString)) { - return null; - } - - // Only look at the Network portion for mmi - String networkPortion = PhoneNumberUtils.extractNetworkPortion(newDialString); - GsmMmiCode mmi = GsmMmiCode.newFromDialString(networkPortion, this); - if (LOCAL_DEBUG) Log.d(LOG_TAG, - "dialing w/ mmi '" + mmi + "'..."); - - if (mmi == null) { - return mCT.dial(newDialString); - } else if (mmi.isTemporaryModeCLIR()) { - return mCT.dial(mmi.dialingNumber, mmi.getCLIRMode()); - } else { - mPendingMMIs.add(mmi); - mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); - mmi.processCode(); - - // FIXME should this return null or something else? - return null; - } - } - - public boolean handlePinMmi(String dialString) { - GsmMmiCode mmi = GsmMmiCode.newFromDialString(dialString, this); - - if (mmi != null && mmi.isPinCommand()) { - mPendingMMIs.add(mmi); - mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); - mmi.processCode(); - return true; - } - - return false; - } - - public void sendUssdResponse(String ussdMessge) { - GsmMmiCode mmi = GsmMmiCode.newFromUssdUserInput(ussdMessge, this); - mPendingMMIs.add(mmi); - mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null)); - mmi.sendUssd(ussdMessge); - } - - public void - sendDtmf(char c) { - if (!PhoneNumberUtils.is12Key(c)) { - Log.e(LOG_TAG, - "sendDtmf called with invalid character '" + c + "'"); - } else { - if (mCT.state == Phone.State.OFFHOOK) { - mCM.sendDtmf(c, null); - } - } - } - - public void - startDtmf(char c) { - if (!PhoneNumberUtils.is12Key(c)) { - Log.e(LOG_TAG, - "startDtmf called with invalid character '" + c + "'"); - } else { - mCM.startDtmf(c, null); - } - } - - public void - stopDtmf() { - mCM.stopDtmf(null); - } - - public void - setRadioPower(boolean power) { - mSST.setRadioPower(power); - } - - private void storeVoiceMailNumber(String number) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putString(VM_NUMBER, number); - editor.commit(); - setVmSimImsi(getSubscriberId()); - } - - public String getVoiceMailNumber() { - // Read from the SIM. If its null, try reading from the shared preference area. - String number = mSIMRecords.getVoiceMailNumber(); - if (TextUtils.isEmpty(number)) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - number = sp.getString(VM_NUMBER, null); - } - return number; - } - - private String getVmSimImsi() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - return sp.getString(VM_SIM_IMSI, null); - } - - private void setVmSimImsi(String imsi) { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putString(VM_SIM_IMSI, imsi); - editor.commit(); - } - - public String getVoiceMailAlphaTag() { - String ret; - - ret = mSIMRecords.getVoiceMailAlphaTag(); - - if (ret == null || ret.length() == 0) { - return mContext.getText( - com.android.internal.R.string.defaultVoiceMailAlphaTag).toString(); - } - - return ret; - } - - public String getDeviceId() { - return mImei; - } - - public String getDeviceSvn() { - return mImeiSv; - } - - public String getSubscriberId() { - return mSIMRecords.imsi; - } - - public String getSimSerialNumber() { - return mSIMRecords.iccid; - } - - public String getLine1Number() { - return mSIMRecords.getMsisdnNumber(); - } - - public String getLine1AlphaTag() { - String ret; - - ret = mSIMRecords.getMsisdnAlphaTag(); - - if (ret == null || ret.length() == 0) { - return mContext.getText( - com.android.internal.R.string.defaultMsisdnAlphaTag).toString(); - } - - return ret; - } - - public void setLine1Number(String alphaTag, String number, Message onComplete) { - mSIMRecords.setMsisdnNumber(alphaTag, number, onComplete); - } - - public void setVoiceMailNumber(String alphaTag, - String voiceMailNumber, - Message onComplete) { - - Message resp; - mVmNumber = voiceMailNumber; - resp = h.obtainMessage(EVENT_SET_VM_NUMBER_DONE, 0, 0, onComplete); - mSIMRecords.setVoiceMailNumber(alphaTag, mVmNumber, resp); - } - - private boolean isValidCommandInterfaceCFReason (int commandInterfaceCFReason) { - switch (commandInterfaceCFReason) { - case CF_REASON_UNCONDITIONAL: - case CF_REASON_BUSY: - case CF_REASON_NO_REPLY: - case CF_REASON_NOT_REACHABLE: - case CF_REASON_ALL: - case CF_REASON_ALL_CONDITIONAL: - return true; - default: - return false; - } - } - - private boolean isValidCommandInterfaceCFAction (int commandInterfaceCFAction) { - switch (commandInterfaceCFAction) { - case CF_ACTION_DISABLE: - case CF_ACTION_ENABLE: - case CF_ACTION_REGISTRATION: - case CF_ACTION_ERASURE: - return true; - default: - return false; - } - } - - private boolean isCfEnable(int action) { - return (action == CF_ACTION_ENABLE) || (action == CF_ACTION_REGISTRATION); - } - - public void getCallForwardingOption(int commandInterfaceCFReason, - Message onComplete) { - - if (isValidCommandInterfaceCFReason(commandInterfaceCFReason)) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "requesting call forwarding query."); - Message resp; - if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) { - resp = h.obtainMessage(EVENT_GET_CALL_FORWARD_DONE, onComplete); - } else { - resp = onComplete; - } - mCM.queryCallForwardStatus(commandInterfaceCFReason,0,null,resp); - } - } - - public void setCallForwardingOption(int commandInterfaceCFAction, - int commandInterfaceCFReason, - String dialingNumber, - int timerSeconds, - Message onComplete) { - - if ((isValidCommandInterfaceCFAction(commandInterfaceCFAction)) && - (isValidCommandInterfaceCFReason(commandInterfaceCFReason))) { - - Message resp; - if (commandInterfaceCFReason == CF_REASON_UNCONDITIONAL) { - resp = h.obtainMessage(EVENT_SET_CALL_FORWARD_DONE, - isCfEnable(commandInterfaceCFAction) ? 1 : 0, 0, onComplete); - } else { - resp = onComplete; - } - mCM.setCallForward(commandInterfaceCFAction, - commandInterfaceCFReason, - CommandsInterface.SERVICE_CLASS_VOICE, - dialingNumber, - timerSeconds, - resp); - } - } - - public void getOutgoingCallerIdDisplay(Message onComplete) { - mCM.getCLIR(onComplete); - } - - public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, - Message onComplete) { - mCM.setCLIR(commandInterfaceCLIRMode, - h.obtainMessage(EVENT_SET_CLIR_COMPLETE, commandInterfaceCLIRMode, 0, onComplete)); - } - - public void getCallWaiting(Message onComplete) { - mCM.queryCallWaiting(CommandsInterface.SERVICE_CLASS_VOICE, onComplete); - } - - public void setCallWaiting(boolean enable, Message onComplete) { - mCM.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete); - } - - public boolean - getSimRecordsLoaded() { - return mSIMRecords.getRecordsLoaded(); - } - - public SimCard - getSimCard() { - return mSimCard; - } - - public void - getAvailableNetworks(Message response) { - mCM.getAvailableNetworks(response); - } - - /** - * Small container class used to hold information relevant to - * the carrier selection process. operatorNumeric can be "" - * if we are looking for automatic selection. - */ - private static class NetworkSelectMessage { - public Message message; - public String operatorNumeric; - } - - public void - setNetworkSelectionModeAutomatic(Message response) { - // wrap the response message in our own message along with - // an empty string (to indicate automatic selection) for the - // operator's id. - NetworkSelectMessage nsm = new NetworkSelectMessage(); - nsm.message = response; - nsm.operatorNumeric = ""; - - // get the message - Message msg = h.obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm); - if (LOCAL_DEBUG) - Log.d(LOG_TAG, "wrapping and sending message to connect automatically"); - - mCM.setNetworkSelectionModeAutomatic(msg); - } - - public void - selectNetworkManually(com.android.internal.telephony.gsm.NetworkInfo network, - Message response) { - // wrap the response message in our own message along with - // the operator's id. - NetworkSelectMessage nsm = new NetworkSelectMessage(); - nsm.message = response; - nsm.operatorNumeric = network.operatorNumeric; - - // get the message - Message msg = h.obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); - - mCM.setNetworkSelectionModeManual(network.operatorNumeric, msg); - } - - /** - * Method to retrieve the saved operator id from the Shared Preferences - */ - private String getSavedNetworkSelection() { - // open the shared preferences and search with our key. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - return sp.getString(NETWORK_SELECTION_KEY, ""); - } - - /** - * Method to restore the previously saved operator id, or reset to - * automatic selection, all depending upon the value in the shared - * preferences. - */ - void restoreSavedNetworkSelection(Message response) { - // retrieve the operator id - String networkSelection = getSavedNetworkSelection(); - - // set to auto if the id is empty, otherwise select the network. - if (TextUtils.isEmpty(networkSelection)) { - mCM.setNetworkSelectionModeAutomatic(response); - } else { - mCM.setNetworkSelectionModeManual(networkSelection, response); - } - } - - public void - setPreferredNetworkType(int networkType, Message response) { - mCM.setPreferredNetworkType(networkType, response); - } - - public void - getPreferredNetworkType(Message response) { - mCM.getPreferredNetworkType(response); - } - - public void - getNeighboringCids(Message response) { - mCM.getNeighboringCids(response); - } - - public void setOnPostDialCharacter(Handler h, int what, Object obj) - { - mPostDialHandler = new Registrant(h, what, obj); - } - - - public void setMute(boolean muted) - { - mCT.setMute(muted); - } - - public boolean getMute() - { - return mCT.getMute(); - } - - - public void invokeOemRilRequestRaw(byte[] data, Message response) - { - mCM.invokeOemRilRequestRaw(data, response); - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) - { - mCM.invokeOemRilRequestStrings(strings, response); - } - - public void getPdpContextList(Message response) { - mCM.getPDPContextList(response); - } - - public List<PdpConnection> getCurrentPdpList () { - return mDataConnection.getAllPdps(); - } - - /** - * Disables the DNS check (i.e., allows "0.0.0.0"). - * Useful for lab testing environment. - * @param b true disables the check, false enables. - */ - public void disableDnsCheck(boolean b) { - mDnsCheckDisabled = b; - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); - editor.commit(); - } - - /** - * Returns true if the DNS check is currently disabled. - */ - public boolean isDnsCheckDisabled() { - return mDnsCheckDisabled; - } - - public void updateServiceLocation(Message response) { - mSST.getLacAndCid(response); - } - - public void enableLocationUpdates() { - mSST.enableLocationUpdates(); - } - - public void disableLocationUpdates() { - mSST.disableLocationUpdates(); - } - - public void setBandMode(int bandMode, Message response) { - mCM.setBandMode(bandMode, response); - } - - public void queryAvailableBandMode(Message response) { - mCM.queryAvailableBandMode(response); - } - - public boolean getDataRoamingEnabled() { - return mDataConnection.getDataOnRoamingEnabled(); - } - - public void setDataRoamingEnabled(boolean enable) { - mDataConnection.setDataOnRoamingEnabled(enable); - } - - public boolean enableDataConnectivity() { - return mDataConnection.setDataEnabled(true); - } - - public int enableApnType(String type) { - return mDataConnection.enableApnType(type); - } - - public int disableApnType(String type) { - return mDataConnection.disableApnType(type); - } - - public boolean disableDataConnectivity() { - return mDataConnection.setDataEnabled(false); - } - - public String getInterfaceName(String apnType) { - return mDataConnection.getInterfaceName(apnType); - } - - public String getIpAddress(String apnType) { - return mDataConnection.getIpAddress(apnType); - } - - public String getGateway(String apnType) { - return mDataConnection.getGateway(apnType); - } - - public String[] getDnsServers(String apnType) { - return mDataConnection.getDnsServers(apnType); - } - - /** - * The only circumstances under which we report that data connectivity is not - * possible are - * <ul> - * <li>Data roaming is disallowed and we are roaming.</li> - * <li>The current data state is {@code DISCONNECTED} for a reason other than - * having explicitly disabled connectivity. In other words, data is not available - * because the phone is out of coverage or some like reason.</li> - * </ul> - * @return {@code true} if data connectivity is possible, {@code false} otherwise. - */ - public boolean isDataConnectivityPossible() { - // TODO: Currently checks if any GPRS connection is active. Should it only - // check for "default"? - boolean noData = mDataConnection.getDataEnabled() && - getDataConnectionState() == DataState.DISCONNECTED; - return !noData && getSimCard().getState() == SimCard.State.READY && - getServiceState().getState() == ServiceState.STATE_IN_SERVICE && - (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming()); - } - - /** - * Removes the given MMI from the pending list and notifies - * registrants that it is complete. - * @param mmi MMI that is done - */ - /*package*/ void - onMMIDone(GsmMmiCode mmi) - { - /* Only notify complete if it's on the pending list. - * Otherwise, it's already been handled (eg, previously canceled). - * The exception is cancellation of an incoming USSD-REQUEST, which is - * not on the list. - */ - if (mPendingMMIs.remove(mmi) || mmi.isUssdRequest()) { - mMmiCompleteRegistrants.notifyRegistrants( - new AsyncResult(null, mmi, null)); - } - } - - - private void - onNetworkInitiatedUssd(GsmMmiCode mmi) - { - mMmiCompleteRegistrants.notifyRegistrants( - new AsyncResult(null, mmi, null)); - } - - - /** ussdMode is one of CommandsInterface.USSD_MODE_* */ - private void - onIncomingUSSD (int ussdMode, String ussdMessage) - { - boolean isUssdError; - boolean isUssdRequest; - - isUssdRequest - = (ussdMode == CommandsInterface.USSD_MODE_REQUEST); - - isUssdError - = (ussdMode != CommandsInterface.USSD_MODE_NOTIFY - && ussdMode != CommandsInterface.USSD_MODE_REQUEST); - - // See comments in GsmMmiCode.java - // USSD requests aren't finished until one - // of these two events happen - GsmMmiCode found = null; - for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) { - if(mPendingMMIs.get(i).isPendingUSSD()) { - found = mPendingMMIs.get(i); - break; - } - } - - if (found != null) { - // Complete pending USSD - - if (isUssdError) { - found.onUssdFinishedError(); - } else { - found.onUssdFinished(ussdMessage, isUssdRequest); - } - } else { // pending USSD not found - // The network may initiate its own USSD request - - // ignore everything that isnt a Notify or a Request - // also, discard if there is no message to present - if (!isUssdError && ussdMessage != null) { - GsmMmiCode mmi; - mmi = GsmMmiCode.newNetworkInitiatedUssd(ussdMessage, - isUssdRequest, - GSMPhone.this); - onNetworkInitiatedUssd(mmi); - } - } - } - - /** - * Make sure the network knows our preferred setting. - */ - private void syncClirSetting() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - int clirSetting = sp.getInt(CLIR_KEY, -1); - if (clirSetting >= 0) { - mCM.setCLIR(clirSetting, null); - } - } - - //***** Inner Classes - - class MyHandler extends Handler - { - MyHandler() - { - } - - MyHandler(Looper l) - { - super(l); - } - - public void - handleMessage (Message msg) - { - AsyncResult ar; - Message onComplete; - - switch (msg.what) { - case EVENT_RADIO_AVAILABLE: { - mCM.getBasebandVersion( - obtainMessage(EVENT_GET_BASEBAND_VERSION_DONE)); - - mCM.getIMEI(obtainMessage(EVENT_GET_IMEI_DONE)); - mCM.getIMEISV(obtainMessage(EVENT_GET_IMEISV_DONE)); - } - break; - - case EVENT_RADIO_ON: - break; - - case EVENT_REGISTERED_TO_NETWORK: - syncClirSetting(); - break; - - case EVENT_SIM_RECORDS_LOADED: - mSIMRecords.getSIMOperatorNumeric(); - - try { - //set the current field the telephony provider according to - //the SIM's operator - Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"); - ContentValues map = new ContentValues(); - map.put(Telephony.Carriers.NUMERIC, mSIMRecords.getSIMOperatorNumeric()); - mContext.getContentResolver().insert(uri, map); - } catch (SQLException e) { - Log.e(LOG_TAG, "Can't store current operator", e); - } - // Check if this is a different SIM than the previous one. If so unset the - // voice mail number. - String imsi = getVmSimImsi(); - if (imsi != null && !getSubscriberId().equals(imsi)) { - storeVoiceMailNumber(null); - setVmSimImsi(null); - } - - break; - - case EVENT_GET_BASEBAND_VERSION_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - if (LOCAL_DEBUG) Log.d(LOG_TAG, "Baseband version: " + ar.result); - setSystemProperty(PROPERTY_BASEBAND_VERSION, (String)ar.result); - break; - - case EVENT_GET_IMEI_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - mImei = (String)ar.result; - break; - - case EVENT_GET_IMEISV_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - mImeiSv = (String)ar.result; - break; - - - case EVENT_USSD: - ar = (AsyncResult)msg.obj; - - String[] ussdResult = (String[]) ar.result; - - if (ussdResult.length > 1) { - try { - onIncomingUSSD(Integer.parseInt(ussdResult[0]), ussdResult[1]); - } catch (NumberFormatException e) { - Log.w(LOG_TAG, "error parsing USSD"); - } - } - break; - - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: - // Some MMI requests (eg USSD) are not completed - // within the course of a CommandsInterface request - // If the radio shuts off or resets while one of these - // is pending, we need to clean up. - - for (int i = 0, s = mPendingMMIs.size() ; i < s; i++) { - if (mPendingMMIs.get(i).isPendingUSSD()) { - mPendingMMIs.get(i).onUssdFinishedError(); - } - } - break; - - case EVENT_SSN: - ar = (AsyncResult)msg.obj; - SuppServiceNotification not = (SuppServiceNotification) ar.result; - mSsnRegistrants.notifyRegistrants(ar); - break; - - case EVENT_SET_CALL_FORWARD_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - mSIMRecords.setVoiceCallForwardingFlag(1, msg.arg1 == 1); - } - onComplete = (Message) ar.userObj; - if (onComplete != null) { - AsyncResult.forMessage(onComplete, ar.result, ar.exception); - onComplete.sendToTarget(); - } - break; - - case EVENT_SET_VM_NUMBER_DONE: - ar = (AsyncResult)msg.obj; - if (SimVmNotSupportedException.class.isInstance(ar.exception)) { - storeVoiceMailNumber(mVmNumber); - ar.exception = null; - } - onComplete = (Message) ar.userObj; - if (onComplete != null) { - AsyncResult.forMessage(onComplete, ar.result, ar.exception); - onComplete.sendToTarget(); - } - break; - - - case EVENT_GET_CALL_FORWARD_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - handleCfuQueryResult((CallForwardInfo[])ar.result); - } - onComplete = (Message) ar.userObj; - if (onComplete != null) { - AsyncResult.forMessage(onComplete, ar.result, ar.exception); - onComplete.sendToTarget(); - } - break; - - case EVENT_CALL_RING: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - notifyIncomingRing(); - } - break; - - // handle the select network completion callbacks. - case EVENT_SET_NETWORK_MANUAL_COMPLETE: - case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE: - handleSetSelectNetwork((AsyncResult) msg.obj); - break; - - case EVENT_SET_CLIR_COMPLETE: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - saveClirSetting(msg.arg1); - } - onComplete = (Message) ar.userObj; - if (onComplete != null) { - AsyncResult.forMessage(onComplete, ar.result, ar.exception); - onComplete.sendToTarget(); - } - break; - } - } - } - - /** - * Used to track the settings upon completion of the network change. - */ - private void handleSetSelectNetwork(AsyncResult ar) { - // look for our wrapper within the asyncresult, skip the rest if it - // is null. - if (!(ar.userObj instanceof NetworkSelectMessage)) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "unexpected result from user object."); - return; - } - - NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj; - - // found the object, now we send off the message we had originally - // attached to the request. - if (nsm.message != null) { - if (LOCAL_DEBUG) Log.d(LOG_TAG, "sending original message to recipient"); - AsyncResult.forMessage(nsm.message, ar.result, ar.exception); - nsm.message.sendToTarget(); - } - - // open the shared preferences editor, and write the value. - // nsm.operatorNumeric is "" if we're in automatic.selection. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric); - - // commit and log the result. - if (! editor.commit()) { - Log.e(LOG_TAG, "failed to commit network selection preference"); - } - - } - - /** - * Saves CLIR setting so that we can re-apply it as necessary - * (in case the RIL resets it across reboots). - */ - /* package */ void saveClirSetting(int commandInterfaceCLIRMode) { - // open the shared preferences editor, and write the value. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(CLIR_KEY, commandInterfaceCLIRMode); - - // commit and log the result. - if (! editor.commit()) { - Log.e(LOG_TAG, "failed to commit CLIR preference"); - } - - } - - private void handleCfuQueryResult(CallForwardInfo[] infos) { - if (infos == null || infos.length == 0) { - // Assume the default is not active - // Set unconditional CFF in SIM to false - mSIMRecords.setVoiceCallForwardingFlag(1, false); - } else { - for (int i = 0, s = infos.length; i < s; i++) { - if ((infos[i].serviceClass & SERVICE_CLASS_VOICE) != 0) { - mSIMRecords.setVoiceCallForwardingFlag(1, (infos[i].status == 1)); - // should only have the one - break; - } - } - } - } - /** - * simulateDataConnection - * - * simulates various data connection states. This messes with - * DataConnectionTracker's internal states, but doesn't actually change - * the underlying radio connection states. - * - * @param state Phone.DataState enum. - */ - public void simulateDataConnection(Phone.DataState state) { - DataConnectionTracker.State dcState; - - switch (state) { - case CONNECTED: - dcState = DataConnectionTracker.State.CONNECTED; - break; - case SUSPENDED: - dcState = DataConnectionTracker.State.CONNECTED; - break; - case DISCONNECTED: - dcState = DataConnectionTracker.State.FAILED; - break; - default: - dcState = DataConnectionTracker.State.CONNECTING; - break; - } - - mDataConnection.setState(dcState); - notifyDataConnection(null); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmAlphabet.java b/telephony/java/com/android/internal/telephony/gsm/GsmAlphabet.java deleted file mode 100644 index 59a9422..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmAlphabet.java +++ /dev/null @@ -1,813 +0,0 @@ -/* - * Copyright (C) 2006 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.telephony.gsm.SmsMessage; -import android.util.SparseIntArray; - -import android.util.Log; - -/** - * This class implements the character set mapping between - * the GSM SMS 7-bit alphabet specifed in TS 23.038 6.2.1 - * and UTF-16 - * - * {@hide} - */ -public class GsmAlphabet -{ - static final String LOG_TAG = "GSM"; - - - - //***** Constants - - /** - * This escapes extended characters, and when present indicates that the - * following character should - * be looked up in the "extended" table - * - * gsmToChar(GSM_EXTENDED_ESCAPE) returns 0xffff - */ - - public static final byte GSM_EXTENDED_ESCAPE = 0x1B; - - - /** - * char to GSM alphabet char - * Returns ' ' in GSM alphabet if there's no possible match - * Returns GSM_EXTENDED_ESCAPE if this character is in the extended table - * In this case, you must call charToGsmExtended() for the value that - * should follow GSM_EXTENDED_ESCAPE in the GSM alphabet string - */ - public static int - charToGsm(char c) - { - try { - return charToGsm(c, false); - } catch (EncodeException ex) { - // this should never happen - return sGsmSpaceChar; - } - } - - /** - * char to GSM alphabet char - * @param throwException If true, throws EncodeException on invalid char. - * If false, returns GSM alphabet ' ' char. - * - * Returns GSM_EXTENDED_ESCAPE if this character is in the extended table - * In this case, you must call charToGsmExtended() for the value that - * should follow GSM_EXTENDED_ESCAPE in the GSM alphabet string - */ - - public static int - charToGsm(char c, boolean throwException) throws EncodeException - { - int ret; - - ret = charToGsm.get(c, -1); - - if (ret == -1) { - ret = charToGsmExtended.get(c, -1); - - if (ret == -1) { - if (throwException) { - throw new EncodeException(c); - } else { - return sGsmSpaceChar; - } - } else { - return GSM_EXTENDED_ESCAPE; - } - } - - return ret; - - } - - - /** - * char to extended GSM alphabet char - * - * Extended chars should be escaped with GSM_EXTENDED_ESCAPE - * - * Returns ' ' in GSM alphabet if there's no possible match - * - */ - public static int - charToGsmExtended(char c) - { - int ret; - - ret = charToGsmExtended.get(c, -1); - - if (ret == -1) { - return sGsmSpaceChar; - } - - return ret; - } - - /** - * Converts a character in the GSM alphabet into a char - * - * if GSM_EXTENDED_ESCAPE is passed, 0xffff is returned. In this case, - * the following character in the stream should be decoded with - * gsmExtendedToChar() - * - * If an unmappable value is passed (one greater than 127), ' ' is returned - */ - - public static char - gsmToChar(int gsmChar) - { - return (char)gsmToChar.get(gsmChar, ' '); - } - - /** - * Converts a character in the extended GSM alphabet into a char - * - * if GSM_EXTENDED_ESCAPE is passed, ' ' is returned since no second - * extension page has yet been defined (see Note 1 in table 6.2.1.1 of - * TS 23.038 v7.00) - * - * If an unmappable value is passed , ' ' is returned - */ - - public static char - gsmExtendedToChar(int gsmChar) - { - int ret; - - ret = gsmExtendedToChar.get(gsmChar, -1); - - if (ret == -1) { - return ' '; - } - - return (char)ret; - } - - /** - * Converts a String into a byte array containing the 7-bit packed - * GSM Alphabet representation of the string. If a header is provided, - * this is included in the returned byte array and padded to a septet - * boundary. - * - * Unencodable chars are encoded as spaces - * - * Byte 0 in the returned byte array is the count of septets used, - * including the header and header padding. The returned byte array is - * the minimum size required to store the packed septets. The returned - * array cannot contain more than 255 septets. - * - * @param data The text string to encode. - * @param header Optional header (includeing length byte) that precedes - * the encoded data, padded to septet boundary. - * @return Byte array containing header and encoded data. - */ - public static byte[] stringToGsm7BitPackedWithHeader(String data, byte[] header) - throws EncodeException { - - if (header == null || header.length == 0) { - return stringToGsm7BitPacked(data); - } - - int headerBits = header.length * 8; - int headerSeptets = headerBits / 7; - headerSeptets += (headerBits % 7) > 0 ? 1 : 0; - - int sz = data.length(); - int septetCount; - septetCount = countGsmSeptets(data, true) + headerSeptets; - - byte[] ret = stringToGsm7BitPacked(data, 0, septetCount, - (headerSeptets*7), true); - - // Paste in the header - System.arraycopy(header, 0, ret, 1, header.length); - return ret; - } - - /** - * Converts a String into a byte array containing - * the 7-bit packed GSM Alphabet representation of the string. - * - * Unencodable chars are encoded as spaces - * - * Byte 0 in the returned byte array is the count of septets used - * The returned byte array is the minimum size required to store - * the packed septets. The returned array cannot contain more than 255 - * septets. - * - * @param data the data string to endcode - * @throws EncodeException if String is too large to encode - */ - public static byte[] stringToGsm7BitPacked(String data) - throws EncodeException { - return stringToGsm7BitPacked(data, 0, -1, 0, true); - } - - /** - * Converts a String into a byte array containing - * the 7-bit packed GSM Alphabet representation of the string. - * - * Byte 0 in the returned byte array is the count of septets used - * The returned byte array is the minimum size required to store - * the packed septets. The returned array cannot contain more than 255 - * septets. - * - * @param data the text to convert to septets - * @param dataOffset the character offset in data to start the encoding from - * @param maxSeptets the maximum number of septets to convert, or -1 for no - * enforced maximum. - * @param startingBitOffset the number of padding bits to put before - * the start of the first septet at the begining of the array - * @param throwException If true, throws EncodeException on invalid char. - * If false, replaces unencodable char with GSM alphabet space char. - * - * @throws EncodeException if String is too large to encode - */ - public static byte[] stringToGsm7BitPacked(String data, int dataOffset, - int maxSeptets, int startingBitOffset, boolean throwException) - throws EncodeException { - - int sz = data.length(); - int septetCount; - if (maxSeptets == -1) { - septetCount = countGsmSeptets(data, true); - } else { - septetCount = maxSeptets; - } - - if(septetCount > 0xff) { - throw new EncodeException("Payload cannot exceed " + Short.MAX_VALUE - + " septets"); - } - - // Enough for all the septets and the length 2 byte prefix - byte[] ret = new byte[1 + (((septetCount * 7) + 7) / 8)]; - - int bitOffset = startingBitOffset; - int septets = startingBitOffset/7; - for (int i = dataOffset; i < sz && septets < septetCount; i++, bitOffset += 7) { - char c = data.charAt(i); - - int v = GsmAlphabet.charToGsm(c, throwException); - if (v == GSM_EXTENDED_ESCAPE) { - // Lookup the extended char - v = GsmAlphabet.charToGsmExtended(c); - - packSmsChar(ret, bitOffset, GSM_EXTENDED_ESCAPE); - bitOffset += 7; - septets++; - } - - packSmsChar(ret, bitOffset, v); - septets++; - } - - // See check for > 0xff above - ret[0] = (byte)septets; - - return ret; - } - - /** - * Pack a 7-bit char into its appropirate place in a byte array - * - * @param bitOffset the bit offset that the septet should be packed at - * (septet index * 7) - */ - private static void - packSmsChar(byte[] packedChars, int bitOffset, int value) - { - int byteOffset = bitOffset / 8; - int shift = bitOffset % 8; - - packedChars[++byteOffset] |= value << shift; - - if (shift > 1) { - packedChars[++byteOffset] = (byte)(value >> (8 - shift)); - } - } - - /** - * Convert a GSM alphabet 7 bit packed string (SMS string) into a - * {@link java.lang.String}. - * - * See TS 23.038 6.1.2.1 for SMS Character Packing - * - * @param pdu the raw data from the pdu - * @param offset the byte offset of - * @param lengthSeptets string length in septets, not bytes - * @return String representation or null on decoding exception - */ - public static String gsm7BitPackedToString(byte[] pdu, int offset, - int lengthSeptets) { - return gsm7BitPackedToString(pdu, offset, lengthSeptets, 0); - } - - /** - * Convert a GSM alphabet 7 bit packed string (SMS string) into a - * {@link java.lang.String}. - * - * See TS 23.038 6.1.2.1 for SMS Character Packing - * - * @param pdu the raw data from the pdu - * @param offset the byte offset of - * @param lengthSeptets string length in septets, not bytes - * @param numPaddingBits the number of padding bits before the start of the - * string in the first byte - * @return String representation or null on decoding exception - */ - public static String gsm7BitPackedToString(byte[] pdu, int offset, - int lengthSeptets, int numPaddingBits) - { - StringBuilder ret = new StringBuilder(lengthSeptets); - boolean prevCharWasEscape; - - try { - prevCharWasEscape = false; - - for (int i = 0 ; i < lengthSeptets ; i++) { - int bitOffset = (7 * i) + numPaddingBits; - - int byteOffset = bitOffset / 8; - int shift = bitOffset % 8; - int gsmVal; - - gsmVal = (0x7f & (pdu[offset + byteOffset] >> shift)); - - // if it crosses a byte boundry - if (shift > 1) { - // set msb bits to 0 - gsmVal &= 0x7f >> (shift - 1); - - gsmVal |= 0x7f & (pdu[offset + byteOffset + 1] << (8 - shift)); - } - - if (prevCharWasEscape) { - ret.append(GsmAlphabet.gsmExtendedToChar(gsmVal)); - prevCharWasEscape = false; - } else if (gsmVal == GSM_EXTENDED_ESCAPE) { - prevCharWasEscape = true; - } else { - ret.append(GsmAlphabet.gsmToChar(gsmVal)); - } - } - } catch (RuntimeException ex) { - Log.e(LOG_TAG, "Error GSM 7 bit packed: ", ex); - return null; - } - - return ret.toString(); - } - - - /** - * Convert a GSM alphabet string that's stored in 8-bit unpacked - * format (as it often appears in SIM records) into a String - * - * Field may be padded with trailing 0xff's. The decode stops - * at the first 0xff encountered. - */ - public static String - gsm8BitUnpackedToString(byte[] data, int offset, int length) - { - boolean prevWasEscape; - StringBuilder ret = new StringBuilder(length); - - prevWasEscape = false; - for (int i = offset ; i < offset + length ; i++) { - // Never underestimate the pain that can be caused - // by signed bytes - int c = data[i] & 0xff; - - if (c == 0xff) { - break; - } else if (c == GSM_EXTENDED_ESCAPE) { - if (prevWasEscape) { - // Two escape chars in a row - // We treat this as a space - // See Note 1 in table 6.2.1.1 of TS 23.038 v7.00 - ret.append(' '); - prevWasEscape = false; - } else { - prevWasEscape = true; - } - } else { - if (prevWasEscape) { - ret.append((char)gsmExtendedToChar.get(c, ' ')); - } else { - ret.append((char)gsmToChar.get(c, ' ')); - } - prevWasEscape = false; - } - } - - return ret.toString(); - } - - /** - * Convert a string into an 8-bit unpacked GSM alphabet byte - * array - */ - public static byte[] - stringToGsm8BitPacked(String s) - { - byte[] ret; - - int septets = 0; - - septets = countGsmSeptets(s); - - // Enough for all the septets and the length byte prefix - ret = new byte[septets]; - - stringToGsm8BitUnpackedField(s, ret, 0, ret.length); - - return ret; - } - - - /** - * Write a String into a GSM 8-bit unpacked field of - * @param length size at @param offset in @param dest - * - * Field is padded with 0xff's, string is truncated if necessary - */ - - public static void - stringToGsm8BitUnpackedField(String s, byte dest[], int offset, int length) - { - int outByteIndex = offset; - - // Septets are stored in byte-aligned octets - for (int i = 0, sz = s.length() - ; i < sz && (outByteIndex - offset) < length - ; i++ - ) { - char c = s.charAt(i); - - int v = GsmAlphabet.charToGsm(c); - - if (v == GSM_EXTENDED_ESCAPE) { - // make sure we can fit an escaped char - if (! (outByteIndex + 1 - offset < length)) { - break; - } - - dest[outByteIndex++] = GSM_EXTENDED_ESCAPE; - - v = GsmAlphabet.charToGsmExtended(c); - } - - dest[outByteIndex++] = (byte)v; - } - - // pad with 0xff's - while((outByteIndex - offset) < length) { - dest[outByteIndex++] = (byte)0xff; - } - } - - /** - * Returns the count of 7-bit GSM alphabet characters - * needed to represent this character. Counts unencodable char as 1 septet. - */ - public static int - countGsmSeptets(char c) - { - try { - return countGsmSeptets(c, false); - } catch (EncodeException ex) { - // This should never happen. - return 0; - } - } - - /** - * Returns the count of 7-bit GSM alphabet characters - * needed to represent this character - * @param throwsException If true, throws EncodeException if unencodable - * char. Otherwise, counts invalid char as 1 septet - */ - public static int - countGsmSeptets(char c, boolean throwsException) throws EncodeException - { - if (charToGsm.get(c, -1) != -1) { - return 1; - } - - if (charToGsmExtended.get(c, -1) != -1) { - return 2; - } - - if (throwsException) { - throw new EncodeException(c); - } else { - // count as a space char - return 1; - } - } - - /** - * Returns the count of 7-bit GSM alphabet characters - * needed to represent this string. Counts unencodable char as 1 septet. - */ - public static int - countGsmSeptets(String s) - { - try { - return countGsmSeptets(s, false); - } catch (EncodeException ex) { - // this should never happen - return 0; - } - } - - /** - * Returns the count of 7-bit GSM alphabet characters - * needed to represent this string. - * @param throwsException If true, throws EncodeException if unencodable - * char. Otherwise, counts invalid char as 1 septet - */ - public static int - countGsmSeptets(String s, boolean throwsException) throws EncodeException - { - int charIndex = 0; - int sz = s.length(); - int count = 0; - - while (charIndex < sz) { - count += countGsmSeptets(s.charAt(charIndex), throwsException); - charIndex++; - } - - return count; - } - - /** - * Returns the index into <code>s</code> of the first character - * after <code>limit</code> septets have been reached, starting at - * index <code>start</code>. This is used when dividing messages - * into units within the SMS message size limit. - * - * @param s source string - * @param start index of where to start counting septets - * @param limit maximum septets to include, - * e.g. <code>MAX_USER_DATA_SEPTETS</code> - * @return index of first character that won't fit, or the length - * of the entire string if everything fits - */ - public static int - findGsmSeptetLimitIndex(String s, int start, int limit) { - int accumulator = 0; - int size = s.length(); - - for (int i = start; i < size; i++) { - accumulator += countGsmSeptets(s.charAt(i)); - if (accumulator > limit) { - return i; - } - } - return size; - } - - /** - * Returns the index into <code>s</code> of the first character - * after <code>limit</code> octets have been reached, starting at - * index <code>start</code>. This is used when dividing messages - * in UCS2 encoding into units within the SMS message size limit. - * - * @param s source string - * @param start index of where to start counting septets - * @param limit maximum septets to include, - * e.g. <code>MAX_USER_DATA_BYTES</code> - * @return index of first character that won't fit, or the length - * of the entire string if everything fits - */ - public static int - findUCS2LimitIndex(String s, int start, int limit) { - int numCharToBeEncoded = s.length() - start; - return ((numCharToBeEncoded*2 > limit)? limit/2: numCharToBeEncoded) + start; - } - - /** - * Returns the index into <code>s</code> of the first character - * after <code>limit</code> septets/octets have been reached - * according to the <code>encodingType</code>, starting at - * index <code>start</code>. This is used when dividing messages - * units within the SMS message size limit. - * - * @param s source string - * @param start index of where to start counting septets - * @param limit maximum septets to include, - * e.g. <code>MAX_USER_DATA_BYTES</code> - * @return index of first character that won't fit, or the length - * of the entire string if everything fits - */ - public static int - findLimitIndex(String s, int start, int limit, int encodingType) throws EncodeException { - if (encodingType == SmsMessage.ENCODING_7BIT) { - return findGsmSeptetLimitIndex(s, start, limit); - } - else if (encodingType == SmsMessage.ENCODING_16BIT) { - return findUCS2LimitIndex(s, start, limit); - } - else { - throw new EncodeException("Unsupported encoding type: " + encodingType); - } - } - - // Set in the static initializer - private static int sGsmSpaceChar; - - private static final SparseIntArray charToGsm = new SparseIntArray(); - private static final SparseIntArray gsmToChar = new SparseIntArray(); - private static final SparseIntArray charToGsmExtended = new SparseIntArray(); - private static final SparseIntArray gsmExtendedToChar = new SparseIntArray(); - - static { - int i = 0; - - charToGsm.put('@', i++); - charToGsm.put('\u00a3', i++); - charToGsm.put('$', i++); - charToGsm.put('\u00a5', i++); - charToGsm.put('\u00e8', i++); - charToGsm.put('\u00e9', i++); - charToGsm.put('\u00f9', i++); - charToGsm.put('\u00ec', i++); - charToGsm.put('\u00f2', i++); - charToGsm.put('\u00c7', i++); - charToGsm.put('\n', i++); - charToGsm.put('\u00d8', i++); - charToGsm.put('\u00f8', i++); - charToGsm.put('\r', i++); - charToGsm.put('\u00c5', i++); - charToGsm.put('\u00e5', i++); - - charToGsm.put('\u0394', i++); - charToGsm.put('_', i++); - charToGsm.put('\u03a6', i++); - charToGsm.put('\u0393', i++); - charToGsm.put('\u039b', i++); - charToGsm.put('\u03a9', i++); - charToGsm.put('\u03a0', i++); - charToGsm.put('\u03a8', i++); - charToGsm.put('\u03a3', i++); - charToGsm.put('\u0398', i++); - charToGsm.put('\u039e', i++); - charToGsm.put('\uffff', i++); - charToGsm.put('\u00c6', i++); - charToGsm.put('\u00e6', i++); - charToGsm.put('\u00df', i++); - charToGsm.put('\u00c9', i++); - - charToGsm.put(' ', i++); - charToGsm.put('!', i++); - charToGsm.put('"', i++); - charToGsm.put('#', i++); - charToGsm.put('\u00a4', i++); - charToGsm.put('%', i++); - charToGsm.put('&', i++); - charToGsm.put('\'', i++); - charToGsm.put('(', i++); - charToGsm.put(')', i++); - charToGsm.put('*', i++); - charToGsm.put('+', i++); - charToGsm.put(',', i++); - charToGsm.put('-', i++); - charToGsm.put('.', i++); - charToGsm.put('/', i++); - - charToGsm.put('0', i++); - charToGsm.put('1', i++); - charToGsm.put('2', i++); - charToGsm.put('3', i++); - charToGsm.put('4', i++); - charToGsm.put('5', i++); - charToGsm.put('6', i++); - charToGsm.put('7', i++); - charToGsm.put('8', i++); - charToGsm.put('9', i++); - charToGsm.put(':', i++); - charToGsm.put(';', i++); - charToGsm.put('<', i++); - charToGsm.put('=', i++); - charToGsm.put('>', i++); - charToGsm.put('?', i++); - - charToGsm.put('\u00a1', i++); - charToGsm.put('A', i++); - charToGsm.put('B', i++); - charToGsm.put('C', i++); - charToGsm.put('D', i++); - charToGsm.put('E', i++); - charToGsm.put('F', i++); - charToGsm.put('G', i++); - charToGsm.put('H', i++); - charToGsm.put('I', i++); - charToGsm.put('J', i++); - charToGsm.put('K', i++); - charToGsm.put('L', i++); - charToGsm.put('M', i++); - charToGsm.put('N', i++); - charToGsm.put('O', i++); - - charToGsm.put('P', i++); - charToGsm.put('Q', i++); - charToGsm.put('R', i++); - charToGsm.put('S', i++); - charToGsm.put('T', i++); - charToGsm.put('U', i++); - charToGsm.put('V', i++); - charToGsm.put('W', i++); - charToGsm.put('X', i++); - charToGsm.put('Y', i++); - charToGsm.put('Z', i++); - charToGsm.put('\u00c4', i++); - charToGsm.put('\u00d6', i++); - charToGsm.put('\u0147', i++); - charToGsm.put('\u00dc', i++); - charToGsm.put('\u00a7', i++); - - charToGsm.put('\u00bf', i++); - charToGsm.put('a', i++); - charToGsm.put('b', i++); - charToGsm.put('c', i++); - charToGsm.put('d', i++); - charToGsm.put('e', i++); - charToGsm.put('f', i++); - charToGsm.put('g', i++); - charToGsm.put('h', i++); - charToGsm.put('i', i++); - charToGsm.put('j', i++); - charToGsm.put('k', i++); - charToGsm.put('l', i++); - charToGsm.put('m', i++); - charToGsm.put('n', i++); - charToGsm.put('o', i++); - - charToGsm.put('p', i++); - charToGsm.put('q', i++); - charToGsm.put('r', i++); - charToGsm.put('s', i++); - charToGsm.put('t', i++); - charToGsm.put('u', i++); - charToGsm.put('v', i++); - charToGsm.put('w', i++); - charToGsm.put('x', i++); - charToGsm.put('y', i++); - charToGsm.put('z', i++); - charToGsm.put('\u00e4', i++); - charToGsm.put('\u00f6', i++); - charToGsm.put('\u00f1', i++); - charToGsm.put('\u00fc', i++); - charToGsm.put('\u00e0', i++); - - - charToGsmExtended.put('\f', 10); - charToGsmExtended.put('^', 20); - charToGsmExtended.put('{', 40); - charToGsmExtended.put('}', 41); - charToGsmExtended.put('\\', 47); - charToGsmExtended.put('[', 60); - charToGsmExtended.put('~', 61); - charToGsmExtended.put(']', 62); - charToGsmExtended.put('|', 64); - charToGsmExtended.put('\u20ac', 101); - - int size = charToGsm.size(); - for (int j=0; j<size; j++) { - gsmToChar.put(charToGsm.valueAt(j), charToGsm.keyAt(j)); - } - - size = charToGsmExtended.size(); - for (int j=0; j<size; j++) { - gsmExtendedToChar.put(charToGsmExtended.valueAt(j), charToGsmExtended.keyAt(j)); - } - - - sGsmSpaceChar = charToGsm.get(' '); - } - - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java b/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java deleted file mode 100644 index ce6c186..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmMmiCode.java +++ /dev/null @@ -1,1256 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -import android.os.*; -import android.os.AsyncResult; -import android.util.Log; -import java.util.regex.Pattern; -import java.util.regex.Matcher; -import android.text.SpannableStringBuilder; -import android.text.TextUtils; -import android.telephony.PhoneNumberUtils; -import static com.android.internal.telephony.gsm.CommandsInterface.*; - -/** - * The motto for this file is: - * - * "NOTE: By using the # as a separator, most cases are expected to be unambiguous." - * -- TS 22.030 6.5.2 - * - * {@hide} - * - */ -public final class GsmMmiCode extends Handler implements MmiCode -{ - static final String LOG_TAG = "GSM"; - - //***** Constants - - // From TS 22.030 6.5.2 - static final String ACTION_ACTIVATE = "*"; - static final String ACTION_DEACTIVATE = "#"; - static final String ACTION_INTERROGATE = "*#"; - static final String ACTION_REGISTER = "**"; - static final String ACTION_ERASURE = "##"; - - // Supp Service cocdes from TS 22.030 Annex B - - //Called line presentation - static final String SC_CLIP = "30"; - static final String SC_CLIR = "31"; - - // Call Forwarding - static final String SC_CFU = "21"; - static final String SC_CFB = "67"; - static final String SC_CFNRy = "61"; - static final String SC_CFNR = "62"; - - static final String SC_CF_All = "002"; - static final String SC_CF_All_Conditional = "004"; - - // Call Waiting - static final String SC_WAIT = "43"; - - // Call Barring - static final String SC_BAOC = "33"; - static final String SC_BAOIC = "331"; - static final String SC_BAOICxH = "332"; - static final String SC_BAIC = "35"; - static final String SC_BAICr = "351"; - - static final String SC_BA_ALL = "330"; - static final String SC_BA_MO = "333"; - static final String SC_BA_MT = "353"; - - // Supp Service Password registration - static final String SC_PWD = "03"; - - // PIN/PIN2/PUK/PUK2 - static final String SC_PIN = "04"; - static final String SC_PIN2 = "042"; - static final String SC_PUK = "05"; - static final String SC_PUK2 = "052"; - - //***** Event Constants - - static final int EVENT_SET_COMPLETE = 1; - static final int EVENT_GET_CLIR_COMPLETE = 2; - static final int EVENT_QUERY_CF_COMPLETE = 3; - static final int EVENT_USSD_COMPLETE = 4; - static final int EVENT_QUERY_COMPLETE = 5; - static final int EVENT_SET_CFF_COMPLETE = 6; - static final int EVENT_USSD_CANCEL_COMPLETE = 7; - - //***** Instance Variables - - GSMPhone phone; - Context context; - - String action; // One of ACTION_* - String sc; // Service Code - String sia, sib, sic; // Service Info a,b,c - String poundString; // Entire MMI string up to and including # - String dialingNumber; - String pwd; // For password registration - - - /** Set to true in processCode, not at newFromDialString time */ - private boolean isPendingUSSD; - - private boolean isUssdRequest; - - State state = State.PENDING; - CharSequence message; - - //***** Class Variables - - - // See TS 22.030 6.5.2 "Structure of the MMI" - - static Pattern sPatternSuppService = Pattern.compile( - "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)"); -/* 1 2 3 4 5 6 7 8 9 10 11 12 - - 1 = Full string up to and including # - 2 = action (activation/interrogation/registration/erasure) - 3 = service code - 5 = SIA - 7 = SIB - 9 = SIC - 10 = dialing number -*/ - - static final int MATCH_GROUP_POUND_STRING = 1; - - static final int MATCH_GROUP_ACTION = 2; - //(activation/interrogation/registration/erasure) - - static final int MATCH_GROUP_SERVICE_CODE = 3; - static final int MATCH_GROUP_SIA = 5; - static final int MATCH_GROUP_SIB = 7; - static final int MATCH_GROUP_SIC = 9; - static final int MATCH_GROUP_PWD_CONFIRM = 11; - static final int MATCH_GROUP_DIALING_NUMBER = 12; - - - //***** Public Class methods - - /** - * Some dial strings in GSM are defined to do non-call setup - * things, such as modify or query supplementry service settings (eg, call - * forwarding). These are generally referred to as "MMI codes". - * We look to see if the dial string contains a valid MMI code (potentially - * with a dial string at the end as well) and return info here. - * - * If the dial string contains no MMI code, we return an instance with - * only "dialingNumber" set - * - * Please see flow chart in TS 22.030 6.5.3.2 - */ - - static GsmMmiCode - newFromDialString(String dialString, GSMPhone phone) - { - Matcher m; - GsmMmiCode ret = null; - - m = sPatternSuppService.matcher(dialString); - - // Is this formatted like a standard supplementary service code? - if (m.matches()) { - ret = new GsmMmiCode(phone); - ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING)); - ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION)); - ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE)); - ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA)); - ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB)); - ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC)); - ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM)); - ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER)); - - } else if (dialString.endsWith("#")) { - // TS 22.030 sec 6.5.3.2 - // "Entry of any characters defined in the 3GPP TS 23.038 [8] Default Alphabet - // (up to the maximum defined in 3GPP TS 24.080 [10]), followed by #SEND". - - ret = new GsmMmiCode(phone); - ret.poundString = dialString; - } else if (isShortCode(dialString, phone)) { - // this may be a short code, as defined in TS 22.030, 6.5.3.2 - ret = new GsmMmiCode(phone); - ret.dialingNumber = dialString; - } - - return ret; - } - - static GsmMmiCode - newNetworkInitiatedUssd (String ussdMessage, - boolean isUssdRequest, GSMPhone phone) - { - GsmMmiCode ret; - - ret = new GsmMmiCode(phone); - - ret.message = ussdMessage; - ret.isUssdRequest = isUssdRequest; - - // If it's a request, set to PENDING so that it's cancelable. - if (isUssdRequest) { - ret.isPendingUSSD = true; - ret.state = State.PENDING; - } else { - ret.state = State.COMPLETE; - } - - return ret; - } - - static GsmMmiCode newFromUssdUserInput(String ussdMessge, GSMPhone phone) { - GsmMmiCode ret = new GsmMmiCode(phone); - - ret.message = ussdMessge; - ret.state = State.PENDING; - ret.isPendingUSSD = true; - - return ret; - } - - //***** Private Class methods - - /** make empty strings be null. - * Regexp returns empty strings for empty groups - */ - private static String - makeEmptyNull (String s) - { - if (s != null && s.length() == 0) return null; - - return s; - } - - /** returns true of the string is empty or null */ - private static boolean - isEmptyOrNull(CharSequence s) - { - return s == null || (s.length() == 0); - } - - - private static int - scToCallForwardReason(String sc) - { - if (sc == null) { - throw new RuntimeException ("invalid call forward sc"); - } - - if (sc.equals(SC_CF_All)) { - return CommandsInterface.CF_REASON_ALL; - } else if (sc.equals(SC_CFU)) { - return CommandsInterface.CF_REASON_UNCONDITIONAL; - } else if (sc.equals(SC_CFB)) { - return CommandsInterface.CF_REASON_BUSY; - } else if (sc.equals(SC_CFNR)) { - return CommandsInterface.CF_REASON_NOT_REACHABLE; - } else if (sc.equals(SC_CFNRy)) { - return CommandsInterface.CF_REASON_NO_REPLY; - } else if (sc.equals(SC_CF_All_Conditional)) { - return CommandsInterface.CF_REASON_ALL_CONDITIONAL; - } else { - throw new RuntimeException ("invalid call forward sc"); - } - } - - private static int - siToServiceClass(String si) - { - if (si == null || si.length() == 0) { - return SERVICE_CLASS_NONE; - } else { - // NumberFormatException should cause MMI fail - int serviceCode = Integer.parseInt(si, 10); - - switch (serviceCode) { - case 10: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE; - case 11: return SERVICE_CLASS_VOICE; - case 12: return SERVICE_CLASS_SMS + SERVICE_CLASS_FAX; - case 13: return SERVICE_CLASS_FAX; - - case 16: return SERVICE_CLASS_SMS; - - case 19: return SERVICE_CLASS_FAX + SERVICE_CLASS_VOICE; -/* - Note for code 20: - From TS 22.030 Annex C: - "All GPRS bearer services" are not included in "All tele and bearer services" - and "All bearer services"." -....so SERVICE_CLASS_DATA, which (according to 27.007) includes GPRS -*/ - case 20: return SERVICE_CLASS_DATA_ASYNC + SERVICE_CLASS_DATA_SYNC; - - case 21: return SERVICE_CLASS_PAD + SERVICE_CLASS_DATA_ASYNC; - case 22: return SERVICE_CLASS_PACKET + SERVICE_CLASS_DATA_SYNC; - case 24: return SERVICE_CLASS_DATA_SYNC; - case 25: return SERVICE_CLASS_DATA_ASYNC; - case 26: return SERVICE_CLASS_DATA_SYNC + SERVICE_CLASS_VOICE; - case 99: return SERVICE_CLASS_PACKET; - - default: - throw new RuntimeException("unsupported MMI service code " + si); - } - } - } - - private static int - siToTime (String si) - { - if (si == null || si.length() == 0) { - return 0; - } else { - // NumberFormatException should cause MMI fail - return Integer.parseInt(si, 10); - } - } - - static boolean - isServiceCodeCallForwarding(String sc) - { - return sc != null && - (sc.equals(SC_CFU) - || sc.equals(SC_CFB) || sc.equals(SC_CFNRy) - || sc.equals(SC_CFNR) || sc.equals(SC_CF_All) - || sc.equals(SC_CF_All_Conditional)); - } - - static boolean - isServiceCodeCallBarring(String sc) - { - return sc != null && - (sc.equals(SC_BAOC) - || sc.equals(SC_BAOIC) - || sc.equals(SC_BAOICxH) - || sc.equals(SC_BAIC) - || sc.equals(SC_BAICr) - || sc.equals(SC_BA_ALL) - || sc.equals(SC_BA_MO) - || sc.equals(SC_BA_MT)); - } - - static String - scToBarringFacility(String sc) - { - if (sc == null) { - throw new RuntimeException ("invalid call barring sc"); - } - - if (sc.equals(SC_BAOC)) { - return CommandsInterface.CB_FACILITY_BAOC; - } else if (sc.equals(SC_BAOIC)) { - return CommandsInterface.CB_FACILITY_BAOIC; - } else if (sc.equals(SC_BAOICxH)) { - return CommandsInterface.CB_FACILITY_BAOICxH; - } else if (sc.equals(SC_BAIC)) { - return CommandsInterface.CB_FACILITY_BAIC; - } else if (sc.equals(SC_BAICr)) { - return CommandsInterface.CB_FACILITY_BAICr; - } else if (sc.equals(SC_BA_ALL)) { - return CommandsInterface.CB_FACILITY_BA_ALL; - } else if (sc.equals(SC_BA_MO)) { - return CommandsInterface.CB_FACILITY_BA_MO; - } else if (sc.equals(SC_BA_MT)) { - return CommandsInterface.CB_FACILITY_BA_MT; - } else { - throw new RuntimeException ("invalid call barring sc"); - } - } - - //***** Constructor - - GsmMmiCode (GSMPhone phone) - { - // The telephony unit-test cases may create GsmMmiCode's - // in secondary threads - super(phone.h.getLooper()); - this.phone = phone; - this.context = phone.getContext(); - } - - //***** MmiCode implementation - - public State - getState() - { - return state; - } - - public CharSequence - getMessage() - { - return message; - } - - // inherited javadoc suffices - public void - cancel() - { - // Complete or failed cannot be cancelled - if (state == State.COMPLETE || state == State.FAILED) { - return; - } - - state = State.CANCELLED; - - if (isPendingUSSD) { - /* - * There can only be one pending USSD session, so tell the radio to - * cancel it. - */ - phone.mCM.cancelPendingUssd(obtainMessage(EVENT_USSD_CANCEL_COMPLETE, this)); - - /* - * Don't call phone.onMMIDone here; wait for CANCEL_COMPLETE notice - * from RIL. - */ - } else { - // TODO in cases other than USSD, it would be nice to cancel - // the pending radio operation. This requires RIL cancellation - // support, which does not presently exist. - - phone.onMMIDone (this); - } - - - } - - public boolean isCancelable() { - /* Can only cancel pending USSD sessions. */ - return isPendingUSSD; - } - - //***** Instance Methods - - - /** Does this dial string contain a structured or unstructured MMI code? */ - boolean - isMMI() - { - return poundString != null; - } - - /* Is this a 1 or 2 digit "short code" as defined in TS 22.030 sec 6.5.3.2? */ - boolean - isShortCode() - { - return poundString == null - && dialingNumber != null && dialingNumber.length() <= 2; - - } - - /** - * Helper function for newFromDialString. Returns true if dialString appears to be a short code - * AND conditions are correct for it to be treated as such. - */ - static private boolean isShortCode(String dialString, GSMPhone phone) { - // Refer to TS 22.030 Figure 3.5.3.2: - // A 1 or 2 digit "short code" is treated as USSD if it is entered while on a call or - // does not satisfy the condition (exactly 2 digits && starts with '1'). - return ((dialString != null && dialString.length() <= 2) - && !PhoneNumberUtils.isEmergencyNumber(dialString) - && (phone.isInCall() - || !((dialString.length() == 2 && dialString.charAt(0) == '1') - /* While contrary to TS 22.030, there is strong precendence - * for treating "0" and "00" as call setup strings. - */ - || dialString.equals("0") - || dialString.equals("00")))); - } - /** - * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related - */ - boolean isPinCommand() { - return sc != null && (sc.equals(SC_PIN) || sc.equals(SC_PIN2) - || sc.equals(SC_PUK) || sc.equals(SC_PUK2)); - } - - /** - * *See TS 22.030 Annex B - * In temporary mode, to suppress CLIR for a single call, enter: - * " * 31 # <called number> SEND " - * In temporary mode, to invoke CLIR for a single call enter: - * " # 31 # <called number> SEND " - */ - - boolean - isTemporaryModeCLIR() - { - return sc != null && sc.equals(SC_CLIR) && dialingNumber != null - && (isActivate() || isDeactivate()); - } - - /** - * returns CommandsInterface.CLIR_* - * See also isTemporaryModeCLIR() - */ - int - getCLIRMode() - { - if (sc != null && sc.equals(SC_CLIR)) { - if (isActivate()) { - return CommandsInterface.CLIR_SUPPRESSION; - } else if (isDeactivate()) { - return CommandsInterface.CLIR_INVOCATION; - } - } - - return CommandsInterface.CLIR_DEFAULT; - } - - boolean isActivate() - { - return action != null && action.equals(ACTION_ACTIVATE); - } - - boolean isDeactivate() - { - return action != null && action.equals(ACTION_DEACTIVATE); - } - - boolean isInterrogate() - { - return action != null && action.equals(ACTION_INTERROGATE); - } - - boolean isRegister() - { - return action != null && action.equals(ACTION_REGISTER); - } - - boolean isErasure() - { - return action != null && action.equals(ACTION_ERASURE); - } - - /** - * Returns true if this is a USSD code that's been submitted to the - * network...eg, after processCode() is called - */ - public boolean isPendingUSSD() - { - return isPendingUSSD; - } - - public boolean isUssdRequest() { - return isUssdRequest; - } - - /** Process a MMI code or short code...anything that isn't a dialing number */ - void - processCode () - { - try { - if (isShortCode()) { - Log.d(LOG_TAG, "isShortCode"); - // These just get treated as USSD. - sendUssd(dialingNumber); - } else if (dialingNumber != null) { - // We should have no dialing numbers here - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } else if (sc != null && sc.equals(SC_CLIP)) { - Log.d(LOG_TAG, "is CLIP"); - if (isInterrogate()) { - phone.mCM.queryCLIP( - obtainMessage(EVENT_QUERY_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (sc != null && sc.equals(SC_CLIR)) { - Log.d(LOG_TAG, "is CLIR"); - if (isActivate()) { - phone.mCM.setCLIR(CommandsInterface.CLIR_INVOCATION, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (isDeactivate()) { - phone.mCM.setCLIR(CommandsInterface.CLIR_SUPPRESSION, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (isInterrogate()) { - phone.mCM.getCLIR( - obtainMessage(EVENT_GET_CLIR_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (isServiceCodeCallForwarding(sc)) { - Log.d(LOG_TAG, "is CF"); - - String dialingNumber = sia; - int serviceClass = siToServiceClass(sib); - int reason = scToCallForwardReason(sc); - int time = siToTime(sic); - - if (isInterrogate()) { - phone.mCM.queryCallForwardStatus( - reason, serviceClass, dialingNumber, - obtainMessage(EVENT_QUERY_CF_COMPLETE, this)); - } else { - int cfAction; - - if (isActivate()) { - cfAction = CommandsInterface.CF_ACTION_ENABLE; - } else if (isDeactivate()) { - cfAction = CommandsInterface.CF_ACTION_DISABLE; - } else if (isRegister()) { - cfAction = CommandsInterface.CF_ACTION_REGISTRATION; - } else if (isErasure()) { - cfAction = CommandsInterface.CF_ACTION_ERASURE; - } else { - throw new RuntimeException ("invalid action"); - } - - int isSettingUnconditionalVoice = - ((reason == CommandsInterface.CF_REASON_UNCONDITIONAL) && - (((serviceClass & CommandsInterface.SERVICE_CLASS_VOICE) != 0) || - (serviceClass == CommandsInterface.SERVICE_CLASS_NONE))) ? 1 : 0; - - int isEnableDesired = - ((cfAction == CommandsInterface.CF_ACTION_ENABLE) || - (cfAction == CommandsInterface.CF_ACTION_REGISTRATION)) ? 1 : 0; - - Log.d(LOG_TAG, "is CF setCallForward"); - phone.mCM.setCallForward(cfAction, reason, serviceClass, - dialingNumber, time, obtainMessage( - EVENT_SET_CFF_COMPLETE, - isSettingUnconditionalVoice, - isEnableDesired, this)); - } - } else if (isServiceCodeCallBarring(sc)) { - // sia = password - // sib = basic service group - - String password = sia; - int serviceClass = siToServiceClass(sib); - String facility = scToBarringFacility(sc); - - if (isInterrogate()) { - phone.mCM.queryFacilityLock(facility, password, - serviceClass, obtainMessage(EVENT_QUERY_COMPLETE, this)); - } else if (isActivate() || isDeactivate()) { - phone.mCM.setFacilityLock(facility, isActivate(), password, - serviceClass, obtainMessage(EVENT_SET_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - - } else if (sc != null && sc.equals(SC_PWD)) { - // sia = fac - // sib = old pwd - // sic = new pwd - // pwd = new pwd - String facility; - String oldPwd = sib; - String newPwd = sic; - if (isActivate() || isRegister()) { - // Even though ACTIVATE is acceptable, this is really termed a REGISTER - action = ACTION_REGISTER; - - if (sia == null) { - // If sc was not specified, treat it as BA_ALL. - facility = CommandsInterface.CB_FACILITY_BA_ALL; - } else { - facility = scToBarringFacility(sia); - } - if (newPwd.equals(pwd)) { - phone.mCM.changeBarringPassword(facility, oldPwd, - newPwd, obtainMessage(EVENT_SET_COMPLETE, this)); - } else { - // password mismatch; return error - handlePasswordError(com.android.internal.R.string.passwordIncorrect); - } - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - - } else if (sc != null && sc.equals(SC_WAIT)) { - // sia = basic service group - int serviceClass = siToServiceClass(sia); - - if (isActivate() || isDeactivate()) { - phone.mCM.setCallWaiting(isActivate(), serviceClass, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (isInterrogate()) { - phone.mCM.queryCallWaiting(serviceClass, - obtainMessage(EVENT_QUERY_COMPLETE, this)); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (isPinCommand()) { - // sia = old PIN or PUK - // sib = new PIN - // sic = new PIN - String oldPinOrPuk = sia; - String newPin = sib; - int pinLen = newPin.length(); - if (isRegister()) { - if (!newPin.equals(sic)) { - // password mismatch; return error - handlePasswordError(com.android.internal.R.string.mismatchPin); - } else if (pinLen < 4 || pinLen > 8 ) { - // invalid length - handlePasswordError(com.android.internal.R.string.invalidPin); - } else if (sc.equals(SC_PIN) && - phone.mSimCard.getState() == SimCard.State.PUK_REQUIRED ) { - // Sim is puk-locked - handlePasswordError(com.android.internal.R.string.needPuk); - } else { - // pre-checks OK - if (sc.equals(SC_PIN)) { - phone.mCM.changeSimPin(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (sc.equals(SC_PIN2)) { - phone.mCM.changeSimPin2(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (sc.equals(SC_PUK)) { - phone.mCM.supplySimPuk(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } else if (sc.equals(SC_PUK2)) { - phone.mCM.supplySimPuk2(oldPinOrPuk, newPin, - obtainMessage(EVENT_SET_COMPLETE, this)); - } - } - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } else if (poundString != null) { - sendUssd(poundString); - } else { - throw new RuntimeException ("Invalid or Unsupported MMI Code"); - } - } catch (RuntimeException exc) { - state = State.FAILED; - message = context.getText(com.android.internal.R.string.mmiError); - phone.onMMIDone(this); - } - } - - private void handlePasswordError(int res) { - state = State.FAILED; - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - sb.append(context.getText(res)); - message = sb; - phone.onMMIDone(this); - } - - /** - * Called from GSMPhone - * - * An unsolicited USSD NOTIFY or REQUEST has come in matching - * up with this pending USSD request - * - * Note: If REQUEST, this exchange is complete, but the session remains - * active (ie, the network expects user input). - */ - void - onUssdFinished(String ussdMessage, boolean isUssdRequest) - { - if (state == State.PENDING) { - if (ussdMessage == null) { - message = context.getText(com.android.internal.R.string.mmiComplete); - } else { - message = ussdMessage; - } - this.isUssdRequest = isUssdRequest; - // If it's a request, leave it PENDING so that it's cancelable. - if (!isUssdRequest) { - state = State.COMPLETE; - } - - phone.onMMIDone(this); - } - } - - /** - * Called from GSMPhone - * - * The radio has reset, and this is still pending - */ - - void - onUssdFinishedError() - { - if (state == State.PENDING) { - state = State.FAILED; - message = context.getText(com.android.internal.R.string.mmiError); - - phone.onMMIDone(this); - } - } - - void sendUssd(String ussdMessage) { - // Treat this as a USSD string - isPendingUSSD = true; - - // Note that unlike most everything else, the USSD complete - // response does not complete this MMI code...we wait for - // an unsolicited USSD "Notify" or "Request". - // The matching up of this is doene in GSMPhone. - - phone.mCM.sendUSSD(ussdMessage, - obtainMessage(EVENT_USSD_COMPLETE, this)); - } - - /** Called from GSMPhone.handleMessage; not a Handler subclass */ - public void - handleMessage (Message msg) - { - AsyncResult ar; - - switch (msg.what) { - case EVENT_SET_COMPLETE: - ar = (AsyncResult) (msg.obj); - - onSetComplete(ar); - break; - - case EVENT_SET_CFF_COMPLETE: - ar = (AsyncResult) (msg.obj); - - /* - * msg.arg1 = 1 means to set unconditional voice call forwarding - * msg.arg2 = 1 means to enable voice call forwarding - */ - if ((ar.exception == null) && (msg.arg1 == 1)) { - boolean cffEnabled = (msg.arg2 == 1); - phone.mSIMRecords.setVoiceCallForwardingFlag(1, cffEnabled); - } - - onSetComplete(ar); - break; - - case EVENT_GET_CLIR_COMPLETE: - ar = (AsyncResult) (msg.obj); - onGetClirComplete(ar); - break; - - case EVENT_QUERY_CF_COMPLETE: - ar = (AsyncResult) (msg.obj); - onQueryCfComplete(ar); - break; - - case EVENT_QUERY_COMPLETE: - ar = (AsyncResult) (msg.obj); - onQueryComplete(ar); - break; - - case EVENT_USSD_COMPLETE: - ar = (AsyncResult) (msg.obj); - - if (ar.exception != null) { - state = State.FAILED; - message = context.getText( - com.android.internal.R.string.mmiError); - - phone.onMMIDone(this); - } - - // Note that unlike most everything else, the USSD complete - // response does not complete this MMI code...we wait for - // an unsolicited USSD "Notify" or "Request". - // The matching up of this is done in GSMPhone. - - break; - - case EVENT_USSD_CANCEL_COMPLETE: - phone.onMMIDone(this); - break; - } - } - //***** Private instance methods - - private CharSequence getScString() { - if (sc != null) { - if (isServiceCodeCallBarring(sc)) { - return context.getText(com.android.internal.R.string.BaMmi); - } else if (isServiceCodeCallForwarding(sc)) { - return context.getText(com.android.internal.R.string.CfMmi); - } else if (sc.equals(SC_CLIP)) { - return context.getText(com.android.internal.R.string.ClipMmi); - } else if (sc.equals(SC_CLIR)) { - return context.getText(com.android.internal.R.string.ClirMmi); - } else if (sc.equals(SC_PWD)) { - return context.getText(com.android.internal.R.string.PwdMmi); - } else if (sc.equals(SC_WAIT)) { - return context.getText(com.android.internal.R.string.CwMmi); - } else if (isPinCommand()) { - return context.getText(com.android.internal.R.string.PinMmi); - } - } - - return ""; - } - - private void - onSetComplete(AsyncResult ar){ - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - if (ar.exception instanceof CommandException) { - CommandException.Error err = ((CommandException)(ar.exception)).getCommandError(); - if (err == CommandException.Error.PASSWORD_INCORRECT) { - if (isPinCommand()) { - // look specifically for the PUK commands and adjust - // the message accordingly. - if (sc.equals(SC_PUK) || sc.equals(SC_PUK2)) { - sb.append(context.getText( - com.android.internal.R.string.badPuk)); - } else { - sb.append(context.getText( - com.android.internal.R.string.badPin)); - } - } else { - sb.append(context.getText( - com.android.internal.R.string.passwordIncorrect)); - } - } else if (err == CommandException.Error.SIM_PUK2) { - sb.append(context.getText( - com.android.internal.R.string.badPin)); - sb.append("\n"); - sb.append(context.getText( - com.android.internal.R.string.needPuk2)); - } else { - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - } else { - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - } else if (isActivate()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceEnabled)); - // Record CLIR setting - if (sc.equals(SC_CLIR)) { - phone.saveClirSetting(CommandsInterface.CLIR_INVOCATION); - } - } else if (isDeactivate()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceDisabled)); - // Record CLIR setting - if (sc.equals(SC_CLIR)) { - phone.saveClirSetting(CommandsInterface.CLIR_SUPPRESSION); - } - } else if (isRegister()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceRegistered)); - } else if (isErasure()) { - state = State.COMPLETE; - sb.append(context.getText( - com.android.internal.R.string.serviceErased)); - } else { - state = State.FAILED; - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - } - - message = sb; - phone.onMMIDone(this); - } - - private void - onGetClirComplete(AsyncResult ar) - { - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); - } else { - int clirArgs[]; - - clirArgs = (int[])ar.result; - - // the 'm' parameter from TS 27.007 7.7 - switch (clirArgs[1]) { - case 0: // CLIR not provisioned - sb.append(context.getText( - com.android.internal.R.string.serviceNotProvisioned)); - state = State.COMPLETE; - break; - - case 1: // CLIR provisioned in permanent mode - sb.append(context.getText( - com.android.internal.R.string.CLIRPermanent)); - state = State.COMPLETE; - break; - - case 2: // unknown (e.g. no network, etc.) - sb.append(context.getText( - com.android.internal.R.string.mmiError)); - state = State.FAILED; - break; - - case 3: // CLIR temporary mode presentation restricted - - // the 'n' parameter from TS 27.007 7.7 - switch (clirArgs[0]) { - default: - case 0: // Default - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOnNextCallOn)); - break; - case 1: // CLIR invocation - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOnNextCallOn)); - break; - case 2: // CLIR suppression - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOnNextCallOff)); - break; - } - state = State.COMPLETE; - break; - - case 4: // CLIR temporary mode presentation allowed - // the 'n' parameter from TS 27.007 7.7 - switch (clirArgs[0]) { - default: - case 0: // Default - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOffNextCallOff)); - break; - case 1: // CLIR invocation - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOffNextCallOn)); - break; - case 2: // CLIR suppression - sb.append(context.getText( - com.android.internal.R.string.CLIRDefaultOffNextCallOff)); - break; - } - - state = State.COMPLETE; - break; - } - } - - message = sb; - phone.onMMIDone(this); - } - - /** - * @param serviceClass 1 bit of the service class bit vectory - * @return String to be used for call forward query MMI response text. - * Returns null if unrecognized - */ - - private CharSequence - serviceClassToCFString (int serviceClass) - { - switch (serviceClass) { - case SERVICE_CLASS_VOICE: return context.getText(com.android.internal.R.string.serviceClassVoice); - case SERVICE_CLASS_DATA: return context.getText(com.android.internal.R.string.serviceClassData); - case SERVICE_CLASS_FAX: return context.getText(com.android.internal.R.string.serviceClassFAX); - case SERVICE_CLASS_SMS: return context.getText(com.android.internal.R.string.serviceClassSMS); - case SERVICE_CLASS_DATA_SYNC: return context.getText(com.android.internal.R.string.serviceClassDataSync); - case SERVICE_CLASS_DATA_ASYNC: return context.getText(com.android.internal.R.string.serviceClassDataAsync); - case SERVICE_CLASS_PACKET: return context.getText(com.android.internal.R.string.serviceClassPacket); - case SERVICE_CLASS_PAD: return context.getText(com.android.internal.R.string.serviceClassPAD); - - default: - return null; - } - } - - - /** one CallForwardInfo + serviceClassMask -> one line of text */ - private CharSequence - makeCFQueryResultMessage(CallForwardInfo info, int serviceClassMask) - { - CharSequence template; - String sources[] = {"{0}", "{1}", "{2}"}; - CharSequence destinations[] = new CharSequence[3]; - boolean needTimeTemplate; - - // CF_REASON_NO_REPLY also has a time value associated with - // it. All others don't. - - needTimeTemplate = - (info.reason == CommandsInterface.CF_REASON_NO_REPLY); - - if (info.status == 1) { - if (needTimeTemplate) { - template = context.getText( - com.android.internal.R.string.cfTemplateForwardedTime); - } else { - template = context.getText( - com.android.internal.R.string.cfTemplateForwarded); - } - } else if (info.status == 0 && isEmptyOrNull(info.number)) { - template = context.getText( - com.android.internal.R.string.cfTemplateNotForwarded); - } else { /* (info.status == 0) && !isEmptyOrNull(info.number) */ - // A call forward record that is not active but contains - // a phone number is considered "registered" - - if (needTimeTemplate) { - template = context.getText( - com.android.internal.R.string.cfTemplateRegisteredTime); - } else { - template = context.getText( - com.android.internal.R.string.cfTemplateRegistered); - } - } - - // In the template (from strings.xmls) - // {0} is one of "bearerServiceCode*" - // {1} is dialing number - // {2} is time in seconds - - destinations[0] = serviceClassToCFString(info.serviceClass & serviceClassMask); - destinations[1] = PhoneNumberUtils.stringFromStringAndTOA(info.number, info.toa); - destinations[2] = Integer.toString(info.timeSeconds); - - if (info.reason == CommandsInterface.CF_REASON_UNCONDITIONAL && - (info.serviceClass & serviceClassMask) - == CommandsInterface.SERVICE_CLASS_VOICE) { - boolean cffEnabled = (info.status == 1); - phone.mSIMRecords.setVoiceCallForwardingFlag(1, cffEnabled); - } - - return TextUtils.replace(template, sources, destinations); - } - - - private void - onQueryCfComplete(AsyncResult ar) - { - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); - } else { - CallForwardInfo infos[]; - - infos = (CallForwardInfo[]) ar.result; - - if (infos.length == 0) { - // Assume the default is not active - sb.append(context.getText(com.android.internal.R.string.serviceDisabled)); - - // Set unconditional CFF in SIM to false - phone.mSIMRecords.setVoiceCallForwardingFlag(1, false); - } else { - - SpannableStringBuilder tb = new SpannableStringBuilder(); - - // Each bit in the service class gets its own result line - // The service classes may be split up over multiple - // CallForwardInfos. So, for each service classs, find out - // which CallForwardInfo represents it and then build - // the response text based on that - - for (int serviceClassMask = 1 - ; serviceClassMask <= SERVICE_CLASS_MAX - ; serviceClassMask <<= 1 - ) { - for (int i = 0, s = infos.length; i < s ; i++) { - if ((serviceClassMask & infos[i].serviceClass) != 0) { - tb.append(makeCFQueryResultMessage(infos[i], - serviceClassMask)); - tb.append("\n"); - } - } - } - sb.append(tb); - } - - state = State.COMPLETE; - } - - message = sb; - phone.onMMIDone(this); - - } - - private void - onQueryComplete(AsyncResult ar) - { - StringBuilder sb = new StringBuilder(getScString()); - sb.append("\n"); - - if (ar.exception != null) { - state = State.FAILED; - sb.append(context.getText(com.android.internal.R.string.mmiError)); - } else { - int[] ints = (int[])ar.result; - - if (ints.length != 0) { - if (ints[0] == 0) { - sb.append(context.getText(com.android.internal.R.string.serviceDisabled)); - } else if (sc.equals(SC_WAIT)) { - // Call Waiting includes additional data in the response. - sb.append(createQueryCallWaitingResultMessage(ints[1])); - } else if (isServiceCodeCallBarring(sc) || (ints[0] == 1)) { - // ints[0] for Call Barring is a bit vector of services - // for all other services, treat it as a boolean - sb.append(context.getText(com.android.internal.R.string.serviceEnabled)); - } else { - sb.append(context.getText(com.android.internal.R.string.mmiError)); - } - } else { - sb.append(context.getText(com.android.internal.R.string.mmiError)); - } - state = State.COMPLETE; - } - - message = sb; - phone.onMMIDone(this); - } - - private CharSequence - createQueryCallWaitingResultMessage(int serviceClass) - { - StringBuilder sb = new StringBuilder(context.getText(com.android.internal.R.string.serviceEnabledFor)); - - for (int classMask = 1 - ; classMask <= SERVICE_CLASS_MAX - ; classMask <<= 1 - ) { - if ((classMask & serviceClass) != 0) { - sb.append("\n"); - sb.append(serviceClassToCFString(classMask & serviceClass)); - } - } - return sb; - } - - /*** - * TODO: It would be nice to have a method here that can take in a dialstring and - * figure out if there is an MMI code embedded within it. This code would replace - * some of the string parsing functionality in the Phone App's - * SpecialCharSequenceMgr class. - */ - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSimCard.java b/telephony/java/com/android/internal/telephony/gsm/GsmSimCard.java deleted file mode 100644 index 0859806..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSimCard.java +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (C) 2006 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.os.AsyncResult; -import android.os.RemoteException; -import android.os.Handler; -import android.os.Message; -import android.os.Registrant; -import android.os.RegistrantList; -import android.util.Log; -import com.android.internal.telephony.SimCard; -import com.android.internal.telephony.TelephonyProperties; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.TelephonyIntents; -import android.content.Intent; -import android.content.res.Configuration; -import android.app.ActivityManagerNative; - -import static android.Manifest.permission.READ_PHONE_STATE; - -/** - * {@hide} - */ -public final class GsmSimCard extends Handler implements SimCard { - static final String LOG_TAG="GSM"; - - //***** Instance Variables - private static final boolean DBG = true; - - private GSMPhone phone; - private CommandsInterface.SimStatus status = null; - private boolean mSimPinLocked = true; // Default to locked - private boolean mSimFdnEnabled = false; // Default to disabled. - // Will be updated when SIM_READY. - private boolean mDesiredPinLocked; - private boolean mDesiredFdnEnabled; - - //***** Constants - - // FIXME I hope this doesn't conflict with the Dialer's notifications - static final int NOTIFICATION_ID_SIM_STATUS = 33456; - - //***** Event Constants - - static final int EVENT_SIM_LOCKED_OR_ABSENT = 1; - static final int EVENT_GET_SIM_STATUS_DONE = 2; - static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 3; - static final int EVENT_PINPUK_DONE = 4; - static final int EVENT_REPOLL_STATUS_DONE = 5; - static final int EVENT_SIM_READY = 6; - static final int EVENT_QUERY_FACILITY_LOCK_DONE = 7; - static final int EVENT_CHANGE_FACILITY_LOCK_DONE = 8; - static final int EVENT_CHANGE_SIM_PASSWORD_DONE = 9; - static final int EVENT_QUERY_FACILITY_FDN_DONE = 10; - static final int EVENT_CHANGE_FACILITY_FDN_DONE = 11; - - - //***** Constructor - - GsmSimCard(GSMPhone phone) - { - this.phone = phone; - - phone.mCM.registerForSIMLockedOrAbsent( - this, EVENT_SIM_LOCKED_OR_ABSENT, null); - - phone.mCM.registerForOffOrNotAvailable( - this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - - phone.mCM.registerForSIMReady( - this, EVENT_SIM_READY, null); - - updateStateProperty(); - } - - //***** SimCard implementation - - public State - getState() - { - if (status == null) { - switch(phone.mCM.getRadioState()) { - /* This switch block must not return anything in - * State.isLocked() or State.ABSENT. - * If it does, handleSimStatus() may break - */ - case RADIO_OFF: - case RADIO_UNAVAILABLE: - case SIM_NOT_READY: - return State.UNKNOWN; - case SIM_LOCKED_OR_ABSENT: - //this should be transient-only - return State.UNKNOWN; - case SIM_READY: - return State.READY; - } - } else { - switch (status) { - case SIM_ABSENT: return State.ABSENT; - case SIM_NOT_READY: return State.UNKNOWN; - case SIM_READY: return State.READY; - case SIM_PIN: return State.PIN_REQUIRED; - case SIM_PUK: return State.PUK_REQUIRED; - case SIM_NETWORK_PERSONALIZATION: return State.NETWORK_LOCKED; - } - } - - Log.e(LOG_TAG, "GsmSimCard.getState(): case should never be reached"); - return State.UNKNOWN; - } - - private RegistrantList absentRegistrants = new RegistrantList(); - private RegistrantList pinLockedRegistrants = new RegistrantList(); - private RegistrantList networkLockedRegistrants = new RegistrantList(); - - - public void registerForAbsent(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - absentRegistrants.add(r); - - if (getState() == State.ABSENT) { - r.notifyRegistrant(); - } - } - - public void unregisterForAbsent(Handler h) { - absentRegistrants.remove(h); - } - - public void registerForNetworkLocked(Handler h, int what, Object obj) { - Registrant r = new Registrant (h, what, obj); - - networkLockedRegistrants.add(r); - - if (getState() == State.NETWORK_LOCKED) { - r.notifyRegistrant(); - } - } - - public void unregisterForNetworkLocked(Handler h) { - networkLockedRegistrants.remove(h); - } - - public void registerForLocked(Handler h, int what, Object obj) - { - Registrant r = new Registrant (h, what, obj); - - pinLockedRegistrants.add(r); - - if (getState().isPinLocked()) { - r.notifyRegistrant(); - } - } - - public void unregisterForLocked(Handler h) - { - pinLockedRegistrants.remove(h); - } - - - public void supplyPin (String pin, Message onComplete) - { - phone.mCM.supplySimPin(pin, - obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - public void supplyPuk (String puk, String newPin, Message onComplete) - { - phone.mCM.supplySimPuk(puk, newPin, - obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - public void supplyPin2 (String pin2, Message onComplete) - { - phone.mCM.supplySimPin2(pin2, - obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - public void supplyPuk2 (String puk2, String newPin2, Message onComplete) - { - phone.mCM.supplySimPuk2(puk2, newPin2, - obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - public void supplyNetworkDepersonalization (String pin, Message onComplete) - { - if(DBG) log("Network Despersonalization: " + pin); - phone.mCM.supplyNetworkDepersonalization(pin, - obtainMessage(EVENT_PINPUK_DONE, onComplete)); - } - - public boolean getSimLockEnabled() { - return mSimPinLocked; - } - - public boolean getSimFdnEnabled() { - return mSimFdnEnabled; - } - - public void setSimLockEnabled (boolean enabled, - String password, Message onComplete) { - int serviceClassX; - serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + - CommandsInterface.SERVICE_CLASS_DATA + - CommandsInterface.SERVICE_CLASS_FAX; - - mDesiredPinLocked = enabled; - - phone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_SIM, - enabled, password, serviceClassX, - obtainMessage(EVENT_CHANGE_FACILITY_LOCK_DONE, onComplete)); - } - - public void setSimFdnEnabled (boolean enabled, - String password, Message onComplete) { - int serviceClassX; - serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + - CommandsInterface.SERVICE_CLASS_DATA + - CommandsInterface.SERVICE_CLASS_FAX + - CommandsInterface.SERVICE_CLASS_SMS; - - mDesiredFdnEnabled = enabled; - - phone.mCM.setFacilityLock(CommandsInterface.CB_FACILITY_BA_FD, - enabled, password, serviceClassX, - obtainMessage(EVENT_CHANGE_FACILITY_FDN_DONE, onComplete)); - } - - public void changeSimLockPassword(String oldPassword, String newPassword, - Message onComplete) { - if(DBG) log("Change Pin1 old: " + oldPassword + " new: " + newPassword); - phone.mCM.changeSimPin(oldPassword, newPassword, - obtainMessage(EVENT_CHANGE_SIM_PASSWORD_DONE, onComplete)); - - } - - public void changeSimFdnPassword(String oldPassword, String newPassword, - Message onComplete) { - if(DBG) log("Change Pin2 old: " + oldPassword + " new: " + newPassword); - phone.mCM.changeSimPin2(oldPassword, newPassword, - obtainMessage(EVENT_CHANGE_SIM_PASSWORD_DONE, onComplete)); - - } - - public String getServiceProviderName () { - return phone.mSIMRecords.getServiceProvideName(); - } - - //***** Handler implementation - @Override - public void handleMessage(Message msg){ - AsyncResult ar; - int serviceClassX; - - serviceClassX = CommandsInterface.SERVICE_CLASS_VOICE + - CommandsInterface.SERVICE_CLASS_DATA + - CommandsInterface.SERVICE_CLASS_FAX; - - switch (msg.what) { - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: - status = null; - updateStateProperty(); - broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_SIM_NOT_READY, null); - break; - case EVENT_SIM_READY: - //TODO: put facility read in SIM_READY now, maybe in REG_NW - phone.mCM.getSimStatus(obtainMessage(EVENT_GET_SIM_STATUS_DONE)); - phone.mCM.queryFacilityLock ( - CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX, - obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE)); - phone.mCM.queryFacilityLock ( - CommandsInterface.CB_FACILITY_BA_FD, "", serviceClassX, - obtainMessage(EVENT_QUERY_FACILITY_FDN_DONE)); - break; - case EVENT_SIM_LOCKED_OR_ABSENT: - phone.mCM.getSimStatus(obtainMessage(EVENT_GET_SIM_STATUS_DONE)); - phone.mCM.queryFacilityLock ( - CommandsInterface.CB_FACILITY_BA_SIM, "", serviceClassX, - obtainMessage(EVENT_QUERY_FACILITY_LOCK_DONE)); - break; - case EVENT_GET_SIM_STATUS_DONE: - ar = (AsyncResult)msg.obj; - - getSimStatusDone(ar); - break; - case EVENT_PINPUK_DONE: - // a PIN/PUK/PIN2/PUK2/Network Personalization - // request has completed. ar.userObj is the response Message - // Repoll before returning - ar = (AsyncResult)msg.obj; - // TODO should abstract these exceptions - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - phone.mCM.getSimStatus( - obtainMessage(EVENT_REPOLL_STATUS_DONE, ar.userObj)); - break; - case EVENT_REPOLL_STATUS_DONE: - // Finished repolling status after PIN operation - // ar.userObj is the response messaeg - // ar.userObj.obj is already an AsyncResult with an - // appropriate exception filled in if applicable - - ar = (AsyncResult)msg.obj; - getSimStatusDone(ar); - ((Message)ar.userObj).sendToTarget(); - break; - case EVENT_QUERY_FACILITY_LOCK_DONE: - ar = (AsyncResult)msg.obj; - onQueryFacilityLock(ar); - break; - case EVENT_QUERY_FACILITY_FDN_DONE: - ar = (AsyncResult)msg.obj; - onQueryFdnEnabled(ar); - break; - case EVENT_CHANGE_FACILITY_LOCK_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - mSimPinLocked = mDesiredPinLocked; - if (DBG) log( "EVENT_CHANGE_FACILITY_LOCK_DONE: " + - "mSimPinLocked= " + mSimPinLocked); - } else { - Log.e(LOG_TAG, "Error change facility lock with exception " - + ar.exception); - } - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - ((Message)ar.userObj).sendToTarget(); - break; - case EVENT_CHANGE_FACILITY_FDN_DONE: - ar = (AsyncResult)msg.obj; - - if (ar.exception == null) { - mSimFdnEnabled = mDesiredFdnEnabled; - if (DBG) log("EVENT_CHANGE_FACILITY_FDN_DONE: " + - "mSimFdnEnabled=" + mSimFdnEnabled); - } else { - Log.e(LOG_TAG, "Error change facility fdn with exception " - + ar.exception); - } - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - ((Message)ar.userObj).sendToTarget(); - break; - case EVENT_CHANGE_SIM_PASSWORD_DONE: - ar = (AsyncResult)msg.obj; - if(ar.exception != null) { - Log.e(LOG_TAG, "Error in change sim password with exception" - + ar.exception); - } - AsyncResult.forMessage(((Message)ar.userObj)).exception - = ar.exception; - ((Message)ar.userObj).sendToTarget(); - break; - default: - Log.e(LOG_TAG, "[GsmSimCard] Unknown Event " + msg.what); - } - } - - - //***** Private methods - - /** - * Interperate EVENT_QUERY_FACILITY_LOCK_DONE - * @param ar is asyncResult of Query_Facility_Locked - */ - private void onQueryFacilityLock(AsyncResult ar) { - if(ar.exception != null) { - if (DBG) log("Error in querying facility lock:" + ar.exception); - return; - } - - int[] ints = (int[])ar.result; - if(ints.length != 0) { - mSimPinLocked = (0!=ints[0]); - if(DBG) log("Query facility lock : " + mSimPinLocked); - } else { - Log.e(LOG_TAG, "[GsmSimCard] Bogus facility lock response"); - } - } - - /** - * Interperate EVENT_QUERY_FACILITY_LOCK_DONE - * @param ar is asyncResult of Query_Facility_Locked - */ - private void onQueryFdnEnabled(AsyncResult ar) { - if(ar.exception != null) { - if(DBG) log("Error in querying facility lock:" + ar.exception); - return; - } - - int[] ints = (int[])ar.result; - if(ints.length != 0) { - mSimFdnEnabled = (0!=ints[0]); - if(DBG) log("Query facility lock : " + mSimFdnEnabled); - } else { - Log.e(LOG_TAG, "[GsmSimCard] Bogus facility lock response"); - } - } - - private void - getSimStatusDone(AsyncResult ar) { - if (ar.exception != null) { - Log.e(LOG_TAG,"Error getting SIM status. " - + "RIL_REQUEST_GET_SIM_STATUS should " - + "never return an error", ar.exception); - return; - } - - CommandsInterface.SimStatus newStatus - = (CommandsInterface.SimStatus) ar.result; - - handleSimStatus(newStatus); - } - - private void - handleSimStatus(CommandsInterface.SimStatus newStatus) { - boolean transitionedIntoPinLocked; - boolean transitionedIntoAbsent; - boolean transitionedIntoNetworkLocked; - - SimCard.State oldState, newState; - - oldState = getState(); - status = newStatus; - newState = getState(); - - updateStateProperty(); - - transitionedIntoPinLocked = ( - (oldState != State.PIN_REQUIRED && newState == State.PIN_REQUIRED) - || (oldState != State.PUK_REQUIRED && newState == State.PUK_REQUIRED)); - transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT); - transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED - && newState == State.NETWORK_LOCKED); - - if (transitionedIntoPinLocked) { - if(DBG) log("Notify SIM pin or puk locked."); - pinLockedRegistrants.notifyRegistrants(); - broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_SIM_LOCKED, - (newState == State.PIN_REQUIRED) ? - INTENT_VALUE_LOCKED_ON_PIN : INTENT_VALUE_LOCKED_ON_PUK); - } else if (transitionedIntoAbsent) { - if(DBG) log("Notify SIM missing."); - absentRegistrants.notifyRegistrants(); - broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_SIM_ABSENT, null); - } else if (transitionedIntoNetworkLocked) { - if(DBG) log("Notify SIM network locked."); - networkLockedRegistrants.notifyRegistrants(); - broadcastSimStateChangedIntent(SimCard.INTENT_VALUE_SIM_LOCKED, - INTENT_VALUE_LOCKED_NETWORK); - } - } - - public void broadcastSimStateChangedIntent(String value, String reason) { - Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED); - intent.putExtra(Phone.PHONE_NAME_KEY, phone.getPhoneName()); - intent.putExtra(SimCard.INTENT_KEY_SIM_STATE, value); - intent.putExtra(SimCard.INTENT_KEY_LOCKED_REASON, reason); - if(DBG) log("Broadcasting intent SIM_STATE_CHANGED_ACTION " + value - + " reason " + reason); - ActivityManagerNative.broadcastStickyIntent(intent, READ_PHONE_STATE); - } - - public void updateImsiConfiguration(String imsi) { - if (imsi.length() >= 6) { - Configuration config = new Configuration(); - config.mcc = ((imsi.charAt(0)-'0')*100) - + ((imsi.charAt(1)-'0')*10) - + (imsi.charAt(2)-'0'); - config.mnc = ((imsi.charAt(3)-'0')*100) - + ((imsi.charAt(4)-'0')*10) - + (imsi.charAt(5)-'0'); - try { - ActivityManagerNative.getDefault().updateConfiguration(config); - } catch (RemoteException e) { - } - } - } - - private void - updateStateProperty() { - phone.setSystemProperty( - TelephonyProperties.PROPERTY_SIM_STATE, - getState().toString()); - } - - private void log(String msg) { - Log.d(LOG_TAG, "[GsmSimCard] " + msg); - } -} - diff --git a/telephony/java/com/android/internal/telephony/gsm/ISimPhoneBook.aidl b/telephony/java/com/android/internal/telephony/gsm/ISimPhoneBook.aidl deleted file mode 100644 index 77033a7..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/ISimPhoneBook.aidl +++ /dev/null @@ -1,101 +0,0 @@ -/* -** 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 com.android.internal.telephony.gsm.AdnRecord; - -import java.util.List; - -/** Interface for applications to access the SIM phone book. - * - * <p>The following code snippet demonstrates a static method to - * retrieve the ISimPhoneBook interface from Android:</p> - * <pre>private static ISimPhoneBook getSimPhoneBookInterface() - throws DeadObjectException { - IServiceManager sm = ServiceManagerNative.getDefault(); - ISimPhoneBook spb; - spb = ISimPhoneBook.Stub.asInterface(sm.getService("simphonebook")); - return spb; -} - * </pre> - */ - -interface ISimPhoneBook { - - /** - * Loads the AdnRecords in efid and returns them as a - * List of AdnRecords - * - * @param efid the EF id of a ADN-like SIM - * @return List of AdnRecord - */ - List<AdnRecord> getAdnRecordsInEf(int efid); - - /** - * Replace oldAdn with newAdn in ADN-like record in EF - * - * getAdnRecordsInEf must be called at least once before this function, - * otherwise an error will be returned - * - * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN - * @param oldTag adn tag to be replaced - * @param oldPhoneNumber adn number to be replaced - * Set both oldTag and oldPhoneNubmer to "" means to replace an - * empty record, aka, insert new record - * @param newTag adn tag to be stored - * @param newPhoneNumber adn number ot be stored - * Set both newTag and newPhoneNubmer to "" means to replace the old - * record with empty one, aka, delete old record - * @param pin2 required to update EF_FDN, otherwise must be null - * @return true for success - */ - boolean updateAdnRecordsInEfBySearch(int efid, - String oldTag, String oldPhoneNumber, - String newTag, String newPhoneNumber, - String pin2); - - /** - * Update an ADN-like EF record by record index - * - * This is useful for iteration the whole ADN file, such as write the whole - * phone book or erase/format the whole phonebook - * - * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN - * @param newTag adn tag to be stored - * @param newPhoneNumber adn number to be stored - * Set both newTag and newPhoneNubmer to "" means to replace the old - * record with empty one, aka, delete old record - * @param index is 1-based adn record index to be updated - * @param pin2 required to update EF_FDN, otherwise must be null - * @return true for success - */ - boolean updateAdnRecordsInEfByIndex(int efid, String newTag, - String newPhoneNumber, int index, - String pin2); - - /** - * Get the max munber of records in efid - * - * @param efid the EF id of a ADN-like SIM - * @return int[3] array - * recordSizes[0] is the single record length - * recordSizes[1] is the total length of the EF file - * recordSizes[2] is the number of records in the EF file - */ - int[] getAdnRecordsSize(int efid); - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/ISms.aidl b/telephony/java/com/android/internal/telephony/gsm/ISms.aidl deleted file mode 100644 index 904a54e..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/ISms.aidl +++ /dev/null @@ -1,115 +0,0 @@ -/* -** 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.app.PendingIntent; -import com.android.internal.telephony.gsm.SmsRawData; - -/** Interface for applications to access the SIM phone book. - * - * <p>The following code snippet demonstrates a static method to - * retrieve the ISimSms interface from Android:</p> - * <pre>private static ISimSms getSimSmsInterface() - throws DeadObjectException { - IServiceManager sm = ServiceManagerNative.getDefault(); - ISimSms ss; - ss = ISimSms.Stub.asInterface(sm.getService("isms")); - return ss; -} - * </pre> - */ - -interface ISms { - /** - * Retrieves all messages currently stored on SIM. - * - * @return list of SmsRawData of all sms on SIM - */ - List<SmsRawData> getAllMessagesFromSimEf(); - - /** - * Update the specified message on the SIM. - * - * @param messageIndex record index of message to update - * @param newStatus new message status (STATUS_ON_SIM_READ, - * STATUS_ON_SIM_UNREAD, STATUS_ON_SIM_SENT, - * STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE) - * @param pdu the raw PDU to store - * @return success or not - * - */ - boolean updateMessageOnSimEf(int messageIndex, int newStatus, - in byte[] pdu); - - /** - * Copy a raw SMS PDU to the SIM. - * - * @param pdu the raw PDU to store - * @param status message status (STATUS_ON_SIM_READ, STATUS_ON_SIM_UNREAD, - * STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT) - * @return success or not - * - */ - boolean copyMessageToSimEf(int status, in byte[] pdu, in byte[] smsc); - - /** - * Send a SMS - * - * @param smsc the SMSC to send the message through, or NULL for the - * defatult SMSC - * @param pdu the raw PDU to send - * @param sentIntent if not NULL this <code>Intent</code> is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * @param deliveryIntent if not NULL this <code>Intent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - void sendRawPdu(in byte[] smsc, in byte[] pdu, in PendingIntent sentIntent, - in PendingIntent deliveryIntent); - - /** - * Send a multi-part text based SMS. - * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param parts an <code>ArrayList</code> of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * @param deliveryIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been delivered - * to the recipient. The raw pdu of the status report is in the - * extended data ("pdu"). - */ - void sendMultipartText(in String destinationAddress, in String scAddress, - in List<String> parts, in List<PendingIntent> sentIntents, - in List<PendingIntent> deliveryIntents); - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/MccTable.java b/telephony/java/com/android/internal/telephony/gsm/MccTable.java deleted file mode 100644 index bb17cc4..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/MccTable.java +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (C) 2006 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 java.util.ArrayList; -import java.util.Collections; - -/** - * Mobile Country Code - * - * {@hide} - */ -public final class MccTable -{ - static ArrayList<MccEntry> table; - - static class MccEntry implements Comparable<MccEntry> - { - int mcc; - String iso; - int smallestDigitsMnc; - String timezone; - String language; - - MccEntry(int mnc, String iso, int smallestDigitsMCC) { - this(mnc, iso, smallestDigitsMCC, null); - } - - MccEntry(int mnc, String iso, int smallestDigitsMCC, String timezone) { - this(mnc, iso, smallestDigitsMCC, timezone, null); - } - - MccEntry(int mnc, String iso, int smallestDigitsMCC, String timezone, String language) { - this.mcc = mnc; - this.iso = iso; - this.smallestDigitsMnc = smallestDigitsMCC; - this.timezone = timezone; - this.language = language; - } - - public int compareTo(MccEntry o) - { - return mcc - o.mcc; - } - } - - private static MccEntry - entryForMcc(int mcc) - { - int index; - - MccEntry m; - - m = new MccEntry(mcc, null, 0); - - index = Collections.binarySearch(table, m); - - if (index < 0) { - return null; - } else { - return table.get(index); - } - } - - /** - * Returns a default time zone ID for the given MCC. - * @param mcc Mobile Country Code - * @return default TimeZone ID, or null if not specified - */ - /* package */ static String defaultTimeZoneForMcc(int mcc) { - MccEntry entry; - - entry = entryForMcc(mcc); - - if (entry == null) { - return null; - } else { - return entry.timezone; - } - } - - /** - * Given a GSM Mobile Country Code, returns - * an ISO two-character country code if available. - * Returns "" if unavailable. - */ - public static String - countryCodeForMcc(int mcc) - { - MccEntry entry; - - entry = entryForMcc(mcc); - - if (entry == null) { - return ""; - } else { - return entry.iso; - } - } - - /** - * Given a GSM Mobile Country Code, returns - * an ISO 2-3 character language code if available. - * Returns null if unavailable. - */ - /* package */ static String defaultLanguageForMcc(int mcc) { - MccEntry entry; - - entry = entryForMcc(mcc); - - if (entry == null) { - return null; - } else { - return entry.language; - } - } - - /** - * Given a GSM Mobile Country Code, returns - * the smallest number of digits that M if available. - * Returns "" if unavailable. - */ - public static int - smallestDigitsMccForMnc(int mcc) - { - MccEntry entry; - - entry = entryForMcc(mcc); - - if (entry == null) { - return 2; - } else { - return entry.smallestDigitsMnc; - } - } - - static { - table = new ArrayList<MccEntry>(240); - - - /* - * The table below is built from two resources: - * - * 1) ITU "Mobile Network Code (MNC) for the international - * identification plan for mobile terminals and mobile users" - * which is available as an annex to the ITU operational bulletin - * available here: http://www.itu.int/itu-t/bulletin/annex.html - * - * 2) The ISO 3166 country codes list, available here: - * http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html - * - * This table has not been verified. - * - * FIXME(mkf) this should be stored in a more efficient representation - */ - - table.add(new MccEntry(202,"gr",2)); //Greece - table.add(new MccEntry(204,"nl",2,"Europe/Amsterdam")); //Netherlands (Kingdom of the) - table.add(new MccEntry(206,"be",2)); //Belgium - table.add(new MccEntry(208,"fr",2,"Europe/Paris","fr")); //France - table.add(new MccEntry(212,"mc",2)); //Monaco (Principality of) - table.add(new MccEntry(213,"ad",2)); //Andorra (Principality of) - table.add(new MccEntry(214,"es",2,"Europe/Madrid","es")); //Spain - table.add(new MccEntry(216,"hu",2)); //Hungary (Republic of) - table.add(new MccEntry(218,"ba",2)); //Bosnia and Herzegovina - table.add(new MccEntry(219,"hr",2)); //Croatia (Republic of) - table.add(new MccEntry(220,"rs",2)); //Serbia and Montenegro - table.add(new MccEntry(222,"it",2,"Europe/Rome","it")); //Italy - table.add(new MccEntry(225,"va",2,"Europe/Rome","it")); //Vatican City State - table.add(new MccEntry(226,"ro",2)); //Romania - table.add(new MccEntry(228,"ch",2)); //Switzerland (Confederation of) - table.add(new MccEntry(230,"cz",2,"Europe/Prague")); //Czech Republic - table.add(new MccEntry(231,"sk",2)); //Slovak Republic - table.add(new MccEntry(232,"at",2,"Europe/Vienna","de")); //Austria - table.add(new MccEntry(234,"gb",2,"Europe/London","en")); //United Kingdom of Great Britain and Northern Ireland - table.add(new MccEntry(235,"gb",2,"Europe/London","en")); //United Kingdom of Great Britain and Northern Ireland - table.add(new MccEntry(238,"dk",2)); //Denmark - table.add(new MccEntry(240,"se",2)); //Sweden - table.add(new MccEntry(242,"no",2)); //Norway - table.add(new MccEntry(244,"fi",2)); //Finland - table.add(new MccEntry(246,"lt",2)); //Lithuania (Republic of) - table.add(new MccEntry(247,"lv",2)); //Latvia (Republic of) - table.add(new MccEntry(248,"ee",2)); //Estonia (Republic of) - table.add(new MccEntry(250,"ru",2)); //Russian Federation - table.add(new MccEntry(255,"ua",2)); //Ukraine - table.add(new MccEntry(257,"by",2)); //Belarus (Republic of) - table.add(new MccEntry(259,"md",2)); //Moldova (Republic of) - table.add(new MccEntry(260,"pl",2,"Europe/Warsaw")); //Poland (Republic of) - table.add(new MccEntry(262,"de",2,"Europe/Berlin","de")); //Germany (Federal Republic of) - table.add(new MccEntry(266,"gi",2)); //Gibraltar - table.add(new MccEntry(268,"pt",2)); //Portugal - table.add(new MccEntry(270,"lu",2)); //Luxembourg - table.add(new MccEntry(272,"ie",2)); //Ireland - table.add(new MccEntry(274,"is",2)); //Iceland - table.add(new MccEntry(276,"al",2)); //Albania (Republic of) - table.add(new MccEntry(278,"mt",2)); //Malta - table.add(new MccEntry(280,"cy",2)); //Cyprus (Republic of) - table.add(new MccEntry(282,"ge",2)); //Georgia - table.add(new MccEntry(283,"am",2)); //Armenia (Republic of) - table.add(new MccEntry(284,"bg",2)); //Bulgaria (Republic of) - table.add(new MccEntry(286,"tr",2)); //Turkey - table.add(new MccEntry(288,"fo",2)); //Faroe Islands - table.add(new MccEntry(290,"gl",2)); //Greenland (Denmark) - table.add(new MccEntry(292,"sm",2)); //San Marino (Republic of) - table.add(new MccEntry(293,"sl",2)); //Slovenia (Republic of) - table.add(new MccEntry(294,"mk",2)); //The Former Yugoslav Republic of Macedonia - table.add(new MccEntry(295,"li",2)); //Liechtenstein (Principality of) - table.add(new MccEntry(302,"ca",2)); //Canada - table.add(new MccEntry(308,"pm",2)); //Saint Pierre and Miquelon (Collectivit territoriale de la Rpublique franaise) - table.add(new MccEntry(310,"us",3,"","en")); //United States of America - table.add(new MccEntry(311,"us",3,"","en")); //United States of America - table.add(new MccEntry(312,"us",3,"","en")); //United States of America - table.add(new MccEntry(313,"us",3,"","en")); //United States of America - table.add(new MccEntry(314,"us",3,"","en")); //United States of America - table.add(new MccEntry(315,"us",3,"","en")); //United States of America - table.add(new MccEntry(316,"us",3,"","en")); //United States of America - table.add(new MccEntry(330,"pr",2)); //Puerto Rico - table.add(new MccEntry(332,"vi",2)); //United States Virgin Islands - table.add(new MccEntry(334,"mx",3)); //Mexico - table.add(new MccEntry(338,"jm",3)); //Jamaica - table.add(new MccEntry(340,"gp",2)); //Guadeloupe (French Department of) - table.add(new MccEntry(342,"bb",3)); //Barbados - table.add(new MccEntry(344,"ag",3)); //Antigua and Barbuda - table.add(new MccEntry(346,"ky",3)); //Cayman Islands - table.add(new MccEntry(348,"vg",3)); //British Virgin Islands - table.add(new MccEntry(350,"bm",2)); //Bermuda - table.add(new MccEntry(352,"gd",2)); //Grenada - table.add(new MccEntry(354,"ms",2)); //Montserrat - table.add(new MccEntry(356,"kn",2)); //Saint Kitts and Nevis - table.add(new MccEntry(358,"lc",2)); //Saint Lucia - table.add(new MccEntry(360,"vc",2)); //Saint Vincent and the Grenadines - table.add(new MccEntry(362,"nl",2)); //Netherlands Antilles - table.add(new MccEntry(363,"aw",2)); //Aruba - table.add(new MccEntry(364,"bs",2)); //Bahamas (Commonwealth of the) - table.add(new MccEntry(365,"ai",3)); //Anguilla - table.add(new MccEntry(366,"dm",2)); //Dominica (Commonwealth of) - table.add(new MccEntry(368,"cu",2)); //Cuba - table.add(new MccEntry(370,"do",2)); //Dominican Republic - table.add(new MccEntry(372,"ht",2)); //Haiti (Republic of) - table.add(new MccEntry(374,"tt",2)); //Trinidad and Tobago - table.add(new MccEntry(376,"tc",2)); //Turks and Caicos Islands - table.add(new MccEntry(400,"az",2)); //Azerbaijani Republic - table.add(new MccEntry(401,"kz",2)); //Kazakhstan (Republic of) - table.add(new MccEntry(402,"bt",2)); //Bhutan (Kingdom of) - table.add(new MccEntry(404,"in",2)); //India (Republic of) - table.add(new MccEntry(405,"in",2)); //India (Republic of) - table.add(new MccEntry(410,"pk",2)); //Pakistan (Islamic Republic of) - table.add(new MccEntry(412,"af",2)); //Afghanistan - table.add(new MccEntry(413,"lk",2)); //Sri Lanka (Democratic Socialist Republic of) - table.add(new MccEntry(414,"mm",2)); //Myanmar (Union of) - table.add(new MccEntry(415,"lb",2)); //Lebanon - table.add(new MccEntry(416,"jo",2)); //Jordan (Hashemite Kingdom of) - table.add(new MccEntry(417,"sy",2)); //Syrian Arab Republic - table.add(new MccEntry(418,"iq",2)); //Iraq (Republic of) - table.add(new MccEntry(419,"kw",2)); //Kuwait (State of) - table.add(new MccEntry(420,"sa",2)); //Saudi Arabia (Kingdom of) - table.add(new MccEntry(421,"ye",2)); //Yemen (Republic of) - table.add(new MccEntry(422,"om",2)); //Oman (Sultanate of) - table.add(new MccEntry(424,"ae",2)); //United Arab Emirates - table.add(new MccEntry(425,"il",2)); //Israel (State of) - table.add(new MccEntry(426,"bh",2)); //Bahrain (Kingdom of) - table.add(new MccEntry(427,"qa",2)); //Qatar (State of) - table.add(new MccEntry(428,"mn",2)); //Mongolia - table.add(new MccEntry(429,"np",2)); //Nepal - table.add(new MccEntry(430,"ae",2)); //United Arab Emirates - table.add(new MccEntry(431,"ae",2)); //United Arab Emirates - table.add(new MccEntry(432,"ir",2)); //Iran (Islamic Republic of) - table.add(new MccEntry(434,"uz",2)); //Uzbekistan (Republic of) - table.add(new MccEntry(436,"tj",2)); //Tajikistan (Republic of) - table.add(new MccEntry(437,"kg",2)); //Kyrgyz Republic - table.add(new MccEntry(438,"tm",2)); //Turkmenistan - table.add(new MccEntry(440,"jp",2,"Asia/Tokyo","ja")); //Japan - table.add(new MccEntry(441,"jp",2,"Asia/Tokyo","ja")); //Japan - table.add(new MccEntry(450,"kr",2)); //Korea (Republic of) - table.add(new MccEntry(452,"vn",2)); //Viet Nam (Socialist Republic of) - table.add(new MccEntry(454,"hk",2)); //"Hong Kong, China" - table.add(new MccEntry(455,"mo",2)); //"Macao, China" - table.add(new MccEntry(456,"kh",2)); //Cambodia (Kingdom of) - table.add(new MccEntry(457,"la",2)); //Lao People's Democratic Republic - table.add(new MccEntry(460,"cn",2)); //China (People's Republic of) - table.add(new MccEntry(461,"cn",2)); //China (People's Republic of) - table.add(new MccEntry(466,"tw",2)); //"Taiwan, China" - table.add(new MccEntry(467,"kp",2)); //Democratic People's Republic of Korea - table.add(new MccEntry(470,"bd",2)); //Bangladesh (People's Republic of) - table.add(new MccEntry(472,"mv",2)); //Maldives (Republic of) - table.add(new MccEntry(502,"my",2)); //Malaysia - table.add(new MccEntry(505,"au",2,"Australia/Sydney","en")); //Australia - table.add(new MccEntry(510,"id",2)); //Indonesia (Republic of) - table.add(new MccEntry(514,"tl",2)); //Democratic Republic of Timor-Leste - table.add(new MccEntry(515,"ph",2)); //Philippines (Republic of the) - table.add(new MccEntry(520,"th",2)); //Thailand - table.add(new MccEntry(525,"sg",2,"Singapore","en")); //Singapore (Republic of) - table.add(new MccEntry(528,"bn",2)); //Brunei Darussalam - table.add(new MccEntry(530,"nz",2)); //New Zealand - table.add(new MccEntry(534,"mp",2)); //Northern Mariana Islands (Commonwealth of the) - table.add(new MccEntry(535,"gu",2)); //Guam - table.add(new MccEntry(536,"nr",2)); //Nauru (Republic of) - table.add(new MccEntry(537,"pg",2)); //Papua New Guinea - table.add(new MccEntry(539,"to",2)); //Tonga (Kingdom of) - table.add(new MccEntry(540,"sb",2)); //Solomon Islands - table.add(new MccEntry(541,"vu",2)); //Vanuatu (Republic of) - table.add(new MccEntry(542,"fj",2)); //Fiji (Republic of) - table.add(new MccEntry(543,"wf",2)); //Wallis and Futuna (Territoire franais d'outre-mer) - table.add(new MccEntry(544,"as",2)); //American Samoa - table.add(new MccEntry(545,"ki",2)); //Kiribati (Republic of) - table.add(new MccEntry(546,"nc",2)); //New Caledonia (Territoire franais d'outre-mer) - table.add(new MccEntry(547,"pf",2)); //French Polynesia (Territoire franais d'outre-mer) - table.add(new MccEntry(548,"ck",2)); //Cook Islands - table.add(new MccEntry(549,"ws",2)); //Samoa (Independent State of) - table.add(new MccEntry(550,"fm",2)); //Micronesia (Federated States of) - table.add(new MccEntry(551,"mh",2)); //Marshall Islands (Republic of the) - table.add(new MccEntry(552,"pw",2)); //Palau (Republic of) - table.add(new MccEntry(602,"eg",2)); //Egypt (Arab Republic of) - table.add(new MccEntry(603,"dz",2)); //Algeria (People's Democratic Republic of) - table.add(new MccEntry(604,"ma",2)); //Morocco (Kingdom of) - table.add(new MccEntry(605,"tn",2)); //Tunisia - table.add(new MccEntry(606,"ly",2)); //Libya (Socialist People's Libyan Arab Jamahiriya) - table.add(new MccEntry(607,"gm",2)); //Gambia (Republic of the) - table.add(new MccEntry(608,"sn",2)); //Senegal (Republic of) - table.add(new MccEntry(609,"mr",2)); //Mauritania (Islamic Republic of) - table.add(new MccEntry(610,"ml",2)); //Mali (Republic of) - table.add(new MccEntry(611,"gn",2)); //Guinea (Republic of) - table.add(new MccEntry(612,"ci",2)); //Cte d'Ivoire (Republic of) - table.add(new MccEntry(613,"bf",2)); //Burkina Faso - table.add(new MccEntry(614,"ne",2)); //Niger (Republic of the) - table.add(new MccEntry(615,"tg",2)); //Togolese Republic - table.add(new MccEntry(616,"bj",2)); //Benin (Republic of) - table.add(new MccEntry(617,"mu",2)); //Mauritius (Republic of) - table.add(new MccEntry(618,"lr",2)); //Liberia (Republic of) - table.add(new MccEntry(619,"sl",2)); //Sierra Leone - table.add(new MccEntry(620,"gh",2)); //Ghana - table.add(new MccEntry(621,"ng",2)); //Nigeria (Federal Republic of) - table.add(new MccEntry(622,"td",2)); //Chad (Republic of) - table.add(new MccEntry(623,"cf",2)); //Central African Republic - table.add(new MccEntry(624,"cm",2)); //Cameroon (Republic of) - table.add(new MccEntry(625,"cv",2)); //Cape Verde (Republic of) - table.add(new MccEntry(626,"st",2)); //Sao Tome and Principe (Democratic Republic of) - table.add(new MccEntry(627,"gq",2)); //Equatorial Guinea (Republic of) - table.add(new MccEntry(628,"ga",2)); //Gabonese Republic - table.add(new MccEntry(629,"cg",2)); //Congo (Republic of the) - table.add(new MccEntry(630,"cg",2)); //Democratic Republic of the Congo - table.add(new MccEntry(631,"ao",2)); //Angola (Republic of) - table.add(new MccEntry(632,"gw",2)); //Guinea-Bissau (Republic of) - table.add(new MccEntry(633,"sc",2)); //Seychelles (Republic of) - table.add(new MccEntry(634,"sd",2)); //Sudan (Republic of the) - table.add(new MccEntry(635,"rw",2)); //Rwanda (Republic of) - table.add(new MccEntry(636,"et",2)); //Ethiopia (Federal Democratic Republic of) - table.add(new MccEntry(637,"so",2)); //Somali Democratic Republic - table.add(new MccEntry(638,"dj",2)); //Djibouti (Republic of) - table.add(new MccEntry(639,"ke",2)); //Kenya (Republic of) - table.add(new MccEntry(640,"tz",2)); //Tanzania (United Republic of) - table.add(new MccEntry(641,"ug",2)); //Uganda (Republic of) - table.add(new MccEntry(642,"bi",2)); //Burundi (Republic of) - table.add(new MccEntry(643,"mz",2)); //Mozambique (Republic of) - table.add(new MccEntry(645,"zm",2)); //Zambia (Republic of) - table.add(new MccEntry(646,"mg",2)); //Madagascar (Republic of) - table.add(new MccEntry(647,"re",2)); //Reunion (French Department of) - table.add(new MccEntry(648,"zw",2)); //Zimbabwe (Republic of) - table.add(new MccEntry(649,"na",2)); //Namibia (Republic of) - table.add(new MccEntry(650,"mw",2)); //Malawi - table.add(new MccEntry(651,"ls",2)); //Lesotho (Kingdom of) - table.add(new MccEntry(652,"bw",2)); //Botswana (Republic of) - table.add(new MccEntry(653,"sz",2)); //Swaziland (Kingdom of) - table.add(new MccEntry(654,"km",2)); //Comoros (Union of the) - table.add(new MccEntry(655,"za",2)); //South Africa (Republic of) - table.add(new MccEntry(657,"er",2)); //Eritrea - table.add(new MccEntry(702,"bz",2)); //Belize - table.add(new MccEntry(704,"gt",2)); //Guatemala (Republic of) - table.add(new MccEntry(706,"sv",2)); //El Salvador (Republic of) - table.add(new MccEntry(708,"hn",3)); //Honduras (Republic of) - table.add(new MccEntry(710,"ni",2)); //Nicaragua - table.add(new MccEntry(712,"cr",2)); //Costa Rica - table.add(new MccEntry(714,"pa",2)); //Panama (Republic of) - table.add(new MccEntry(716,"pe",2)); //Peru - table.add(new MccEntry(722,"ar",3)); //Argentine Republic - table.add(new MccEntry(724,"br",2)); //Brazil (Federative Republic of) - table.add(new MccEntry(730,"cl",2)); //Chile - table.add(new MccEntry(732,"co",3)); //Colombia (Republic of) - table.add(new MccEntry(734,"ve",2)); //Venezuela (Bolivarian Republic of) - table.add(new MccEntry(736,"bo",2)); //Bolivia (Republic of) - table.add(new MccEntry(738,"gy",2)); //Guyana - table.add(new MccEntry(740,"ec",2)); //Ecuador - table.add(new MccEntry(742,"gf",2)); //French Guiana (French Department of) - table.add(new MccEntry(744,"py",2)); //Paraguay (Republic of) - table.add(new MccEntry(746,"sr",2)); //Suriname (Republic of) - table.add(new MccEntry(748,"uy",2)); //Uruguay (Eastern Republic of) - table.add(new MccEntry(750,"fk",2)); //Falkland Islands (Malvinas) - //table.add(new MccEntry(901,"",2)); //"International Mobile, shared code" - - Collections.sort(table); - } -} - diff --git a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl b/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl deleted file mode 100644 index c600530..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.aidl +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2008 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; - -/** - * Used to indicate that the NetworkInfo object is parcelable to aidl. - * This is a simple effort to make NetworkInfo parcelable rather than - * trying to make the conventional containing object (AsyncResult), - * implement parcelable. This functionality is needed for the - * NetworkQueryService to fix 1128695 - */ -parcelable NetworkInfo; diff --git a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java b/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java deleted file mode 100644 index bebf9ba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/NetworkInfo.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2006 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.os.Parcel; -import android.os.Parcelable; - -/** - * {@hide} - */ -public class NetworkInfo implements Parcelable -{ - public enum State { - UNKNOWN, - AVAILABLE, - CURRENT, - FORBIDDEN; - } - - String operatorAlphaLong; - String operatorAlphaShort; - String operatorNumeric; - - State state = State.UNKNOWN; - - - public String - getOperatorAlphaLong() - { - return operatorAlphaLong; - } - - public String - getOperatorAlphaShort() - { - return operatorAlphaShort; - } - - public String - getOperatorNumeric() - { - return operatorNumeric; - } - - public State - getState() - { - return state; - } - - NetworkInfo(String operatorAlphaLong, - String operatorAlphaShort, - String operatorNumeric, - State state) - { - - this.operatorAlphaLong = operatorAlphaLong; - this.operatorAlphaShort = operatorAlphaShort; - this.operatorNumeric = operatorNumeric; - - this.state = state; - } - - - NetworkInfo(String operatorAlphaLong, - String operatorAlphaShort, - String operatorNumeric, - String stateString) - { - this (operatorAlphaLong, operatorAlphaShort, - operatorNumeric, rilStateToState(stateString)); - } - - /** - * See state strings defined in ril.h RIL_REQUEST_QUERY_AVAILABLE_NETWORKS - */ - private static State rilStateToState(String s) - { - if (s.equals("unknown")) { - return State.UNKNOWN; - } else if (s.equals("available")) { - return State.AVAILABLE; - } else if (s.equals("current")) { - return State.CURRENT; - } else if (s.equals("forbidden")) { - return State.FORBIDDEN; - } else { - throw new RuntimeException( - "RIL impl error: Invalid network state '" + s + "'"); - } - } - - - public String toString() - { - return "NetworkInfo " + operatorAlphaLong - + "/" + operatorAlphaShort - + "/" + operatorNumeric - + "/" + state; - } - - /** - * Parcelable interface implemented below. - * This is a simple effort to make NetworkInfo parcelable rather than - * trying to make the conventional containing object (AsyncResult), - * implement parcelable. This functionality is needed for the - * NetworkQueryService to fix 1128695. - */ - - public int describeContents() { - return 0; - } - - /** - * Implement the Parcelable interface. - * Method to serialize a NetworkInfo object. - */ - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(operatorAlphaLong); - dest.writeString(operatorAlphaShort); - dest.writeString(operatorNumeric); - dest.writeSerializable(state); - } - - /** - * Implement the Parcelable interface - * Method to deserialize a NetworkInfo object, or an array thereof. - */ - public static final Creator<NetworkInfo> CREATOR = - new Creator<NetworkInfo>() { - public NetworkInfo createFromParcel(Parcel in) { - NetworkInfo netInfo = new NetworkInfo( - in.readString(), /*operatorAlphaLong*/ - in.readString(), /*operatorAlphaShort*/ - in.readString(), /*operatorNumeric*/ - (State) in.readSerializable()); /*state*/ - return netInfo; - } - - public NetworkInfo[] newArray(int size) { - return new NetworkInfo[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java b/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java deleted file mode 100644 index d5d481a..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/PDPContextState.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class PDPContextState -{ - public int cid; - public boolean active; - public String type; - public String apn; - public String address; - - public String toString() { - return "com.android.internal.telephony.gsm.PDPContextState: {" + - " cid: " + cid + - ", active: " + active + - ", type: " + type + - ", apn: " + apn + - ", address: " + address + - " }"; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java b/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java deleted file mode 100644 index 66f8b72..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/PdpConnection.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2006 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.os.*; -import android.database.Cursor; -import android.provider.Telephony; -import android.text.util.Regex; -import android.util.EventLog; -import android.util.Log; - -import java.util.ArrayList; -import com.android.internal.telephony.Phone; - -/** - * {@hide} - */ -public class PdpConnection extends Handler { - - private static final String LOG_TAG = "GSM"; - private static final boolean DBG = true; - private static final boolean FAKE_FAIL = false; - - public enum PdpState { - ACTIVE, /* has active pdp context */ - ACTIVATING, /* during connecting process */ - INACTIVE; /* has empty pdp context */ - - public String toString() { - switch (this) { - case ACTIVE: return "active"; - case ACTIVATING: return "setting up"; - default: return "inactive"; - } - } - - public boolean isActive() { - return this == ACTIVE; - } - - public boolean isInactive() { - return this == INACTIVE; - } - } - - public enum PdpFailCause { - NONE, - BAD_APN, - BAD_PAP_SECRET, - BARRED, - USER_AUTHENTICATION, - SERVICE_OPTION_NOT_SUPPORTED, - SERVICE_OPTION_NOT_SUBSCRIBED, - SIM_LOCKED, - RADIO_OFF, - NO_SIGNAL, - NO_DATA_PLAN, - RADIO_NOT_AVIALABLE, - SUSPENED_TEMPORARY, - RADIO_ERROR_RETRY, - UNKNOWN; - - public boolean isPermanentFail() { - return (this == RADIO_OFF); - } - - public String toString() { - switch (this) { - case NONE: return "no error"; - case BAD_APN: return "bad apn"; - case BAD_PAP_SECRET:return "bad pap secret"; - case BARRED: return "barred"; - case USER_AUTHENTICATION: return "error user autentication"; - case SERVICE_OPTION_NOT_SUPPORTED: return "data not supported"; - case SERVICE_OPTION_NOT_SUBSCRIBED: return "datt not subcribed"; - case SIM_LOCKED: return "sim locked"; - case RADIO_OFF: return "radio is off"; - case NO_SIGNAL: return "no signal"; - case NO_DATA_PLAN: return "no data plan"; - case RADIO_NOT_AVIALABLE: return "radio not available"; - case SUSPENED_TEMPORARY: return "suspend temporary"; - case RADIO_ERROR_RETRY: return "transient radio error"; - default: return "unknown data error"; - } - } - } - - /** Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause */ - private static final int PDP_FAIL_RIL_BARRED = 8; - private static final int PDP_FAIL_RIL_BAD_APN = 27; - private static final int PDP_FAIL_RIL_USER_AUTHENTICATION = 29; - private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED = 32; - private static final int PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED = 33; - private static final int PDP_FAIL_RIL_ERROR_UNSPECIFIED = 0xffff; - - //***** Event codes - private static final int EVENT_SETUP_PDP_DONE = 1; - private static final int EVENT_GET_LAST_FAIL_DONE = 2; - private static final int EVENT_LINK_STATE_CHANGED = 3; - private static final int EVENT_DEACTIVATE_DONE = 4; - private static final int EVENT_FORCE_RETRY = 5; - - //***** Instance Variables - private GSMPhone phone; - private String pdp_name; - private PdpState state; - private Message onConnectCompleted; - private Message onDisconnect; - private int cid; - private long createTime; - private long lastFailTime; - private PdpFailCause lastFailCause; - private ApnSetting apn; - private String interfaceName; - private String ipAddress; - private String gatewayAddress; - private String[] dnsServers; - - private static final String NULL_IP = "0.0.0.0"; - - // dataLink is only used to support pppd link - DataLink dataLink; - // receivedDisconnectReq is set when disconnect pdp link during activating - private boolean receivedDisconnectReq; - - //***** Constructor - PdpConnection(GSMPhone phone) - { - this.phone = phone; - this.state = PdpState.INACTIVE; - onConnectCompleted = null; - onDisconnect = null; - this.cid = -1; - this.createTime = -1; - this.lastFailTime = -1; - this.lastFailCause = PdpFailCause.NONE; - this.apn = null; - this.dataLink = null; - receivedDisconnectReq = false; - this.dnsServers = new String[2]; - - if (SystemProperties.get("ro.radio.use-ppp","no").equals("yes")) { - dataLink = new PppLink(phone.mDataConnection); - dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null); - } - } - - /** - * Setup PDP connection for provided apn - * @param apn for this connection - * @param onCompleted notify success or not after down - */ - void connect(ApnSetting apn, Message onCompleted) { - if (DBG) log("Connecting to carrier: '" + apn.carrier - + "' APN: '" + apn.apn - + "' proxy: '" + apn.proxy + "' port: '" + apn.port); - - setHttpProxy (apn.proxy, apn.port); - - state = PdpState.ACTIVATING; - this.apn = apn; - onConnectCompleted = onCompleted; - createTime = -1; - lastFailTime = -1; - lastFailCause = PdpFailCause.NONE; - receivedDisconnectReq = false; - - if (FAKE_FAIL) { - // for debug before baseband implement error in setup PDP - if (apn.apn.equalsIgnoreCase("badapn")){ - notifyFail(PdpFailCause.BAD_APN, onConnectCompleted); - return; - } - } - - phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password, - obtainMessage(EVENT_SETUP_PDP_DONE)); - } - - void disconnect(Message msg) { - onDisconnect = msg; - if (state == PdpState.ACTIVE) { - if (dataLink != null) { - dataLink.disconnect(); - } - - if (phone.mCM.getRadioState().isOn()) { - phone.mCM.deactivateDefaultPDP(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg)); - } - } else if (state == PdpState.ACTIVATING) { - receivedDisconnectReq = true; - } else { - // state == INACTIVE. Nothing to do, so notify immediately. - notifyDisconnect(msg); - } - } - - private void - setHttpProxy(String httpProxy, String httpPort) - { - if (httpProxy == null || httpProxy.length() == 0) { - phone.setSystemProperty("net.gprs.http-proxy", null); - return; - } - - if (httpPort == null || httpPort.length() == 0) { - httpPort = "8080"; // Default to port 8080 - } - - phone.setSystemProperty("net.gprs.http-proxy", - "http://" + httpProxy + ":" + httpPort + "/"); - } - - public String toString() { - return "State=" + state + " Apn=" + apn + - " create=" + createTime + " lastFail=" + lastFailTime + - " lastFailCause=" + lastFailCause; - } - - public long getConnectionTime() { - return createTime; - } - - public long getLastFailTime() { - return lastFailTime; - } - - public PdpFailCause getLastFailCause() { - return lastFailCause; - } - - public ApnSetting getApn() { - return apn; - } - - String getInterface() { - return interfaceName; - } - - String getIpAddress() { - return ipAddress; - } - - String getGatewayAddress() { - return gatewayAddress; - } - - String[] getDnsServers() { - return dnsServers; - } - - public PdpState getState() { - return state; - } - - private void notifyFail(PdpFailCause cause, Message onCompleted) { - if (onCompleted == null) return; - - state = PdpState.INACTIVE; - lastFailCause = cause; - lastFailTime = System.currentTimeMillis(); - onConnectCompleted = null; - - if (DBG) log("Notify PDP fail at " + lastFailTime - + " due to " + lastFailCause); - - AsyncResult.forMessage(onCompleted, cause, new Exception()); - onCompleted.sendToTarget(); - } - - private void notifySuccess(Message onCompleted) { - if (onCompleted == null) return; - - state = PdpState.ACTIVE; - createTime = System.currentTimeMillis(); - onConnectCompleted = null; - onCompleted.arg1 = cid; - - if (DBG) log("Notify PDP success at " + createTime); - - AsyncResult.forMessage(onCompleted); - onCompleted.sendToTarget(); - } - - private void notifyDisconnect(Message msg) { - if (DBG) log("Notify PDP disconnect"); - - if (msg != null) { - AsyncResult.forMessage(msg); - msg.sendToTarget(); - } - clearSettings(); - } - - void clearSettings() { - state = PdpState.INACTIVE; - receivedDisconnectReq = false; - createTime = -1; - lastFailTime = -1; - lastFailCause = PdpFailCause.NONE; - apn = null; - onConnectCompleted = null; - interfaceName = null; - ipAddress = null; - gatewayAddress = null; - dnsServers[0] = null; - dnsServers[1] = null; - } - - private void onLinkStateChanged(DataLink.LinkState linkState) { - switch (linkState) { - case LINK_UP: - notifySuccess(onConnectCompleted); - break; - - case LINK_DOWN: - case LINK_EXITED: - phone.mCM.getLastPdpFailCause( - obtainMessage (EVENT_GET_LAST_FAIL_DONE)); - break; - } - } - - private PdpFailCause getFailCauseFromRequest(int rilCause) { - PdpFailCause cause; - - switch (rilCause) { - case PDP_FAIL_RIL_BARRED: - cause = PdpFailCause.BARRED; - break; - case PDP_FAIL_RIL_BAD_APN: - cause = PdpFailCause.BAD_APN; - break; - case PDP_FAIL_RIL_USER_AUTHENTICATION: - cause = PdpFailCause.USER_AUTHENTICATION; - break; - case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED: - cause = PdpFailCause.SERVICE_OPTION_NOT_SUPPORTED; - break; - case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED: - cause = PdpFailCause.SERVICE_OPTION_NOT_SUBSCRIBED; - break; - default: - cause = PdpFailCause.UNKNOWN; - } - return cause; - } - - - private void log(String s) { - Log.d(LOG_TAG, "[PdpConnection] " + s); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - switch (msg.what) { - case EVENT_SETUP_PDP_DONE: - ar = (AsyncResult) msg.obj; - - if (ar.exception != null) { - Log.e(LOG_TAG, "PDP Context Init failed " + ar.exception); - - if (receivedDisconnectReq) { - // Don't bother reporting the error if there's already a - // pending disconnect request, since DataConnectionTracker - // has already updated its state. - notifyDisconnect(onDisconnect); - } else { - if ( ar.exception instanceof CommandException && - ((CommandException) (ar.exception)).getCommandError() - == CommandException.Error.RADIO_NOT_AVAILABLE) { - notifyFail(PdpFailCause.RADIO_NOT_AVIALABLE, - onConnectCompleted); - } else { - phone.mCM.getLastPdpFailCause( - obtainMessage(EVENT_GET_LAST_FAIL_DONE)); - } - } - } else { - if (receivedDisconnectReq) { - // Don't bother reporting success if there's already a - // pending disconnect request, since DataConnectionTracker - // has already updated its state. - // Set ACTIVE so that disconnect does the right thing. - state = PdpState.ACTIVE; - disconnect(onDisconnect); - } else { - String[] response = ((String[]) ar.result); - cid = Integer.parseInt(response[0]); - - if (response.length > 2) { - interfaceName = response[1]; - ipAddress = response[2]; - String prefix = "net." + interfaceName + "."; - gatewayAddress = SystemProperties.get(prefix + "gw"); - dnsServers[0] = SystemProperties.get(prefix + "dns1"); - dnsServers[1] = SystemProperties.get(prefix + "dns2"); - if (DBG) { - log("interface=" + interfaceName + " ipAddress=" + ipAddress - + " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0] - + " DNS2=" + dnsServers[1]); - } - - if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1]) - && !phone.isDnsCheckDisabled()) { - // Work around a race condition where QMI does not fill in DNS: - // Deactivate PDP and let DataConnectionTracker retry. - // Do not apply the race condition workaround for MMS APN - // if Proxy is an IP-address. - // Otherwise, the default APN will not be restored anymore. - if (!apn.types[0].equals(Phone.APN_TYPE_MMS) - || !isIpAddress(apn.mmsProxy)) { - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_BAD_DNS_ADDRESS, - dnsServers[0]); - phone.mCM.deactivateDefaultPDP(cid, - obtainMessage(EVENT_FORCE_RETRY)); - break; - } - } - } - - if (dataLink != null) { - dataLink.connect(); - } else { - onLinkStateChanged(DataLink.LinkState.LINK_UP); - } - - if (DBG) log("PDP setup on cid = " + cid); - } - } - break; - case EVENT_FORCE_RETRY: - if (receivedDisconnectReq) { - notifyDisconnect(onDisconnect); - } else { - ar = (AsyncResult) msg.obj; - notifyFail(PdpFailCause.RADIO_ERROR_RETRY, onConnectCompleted); - } - break; - case EVENT_GET_LAST_FAIL_DONE: - if (receivedDisconnectReq) { - // Don't bother reporting the error if there's already a - // pending disconnect request, since DataConnectionTracker - // has already updated its state. - notifyDisconnect(onDisconnect); - } else { - ar = (AsyncResult) msg.obj; - PdpFailCause cause = PdpFailCause.UNKNOWN; - - if (ar.exception == null) { - int rilFailCause = ((int[]) (ar.result))[0]; - cause = getFailCauseFromRequest(rilFailCause); - } - notifyFail(cause, onConnectCompleted); - } - - break; - case EVENT_LINK_STATE_CHANGED: - ar = (AsyncResult) msg.obj; - DataLink.LinkState ls = (DataLink.LinkState) ar.result; - onLinkStateChanged(ls); - break; - case EVENT_DEACTIVATE_DONE: - ar = (AsyncResult) msg.obj; - notifyDisconnect((Message) ar.userObj); - break; - } - } - - private boolean isIpAddress(String address) { - if (address == null) return false; - - return Regex.IP_ADDRESS_PATTERN.matcher(apn.mmsProxy).matches(); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/PppLink.java b/telephony/java/com/android/internal/telephony/gsm/PppLink.java deleted file mode 100644 index 43d4f1f..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/PppLink.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright (C) 2006 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 java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.RandomAccessFile; - -import android.database.Cursor; -import android.os.Message; -import android.os.SystemProperties; -import android.os.SystemService; -import com.android.internal.telephony.gsm.DataConnectionTracker.State; -import com.android.internal.util.ArrayUtils; -import android.util.Log; - -/** - * Represents a PPP link. - * - * Ideally this would be managed by the RIL implementation, but - * we currently have implementations where this is not the case. - * - * {@hide} - */ -final class PppLink extends DataLink implements DataLinkInterface { - private static final String LOG_TAG = "GSM"; - - static final String PATH_PPP_OPERSTATE = "/sys/class/net/ppp0/operstate"; - static final String SERVICE_PPPD_GPRS = "pppd_gprs"; - static final String PROPERTY_PPPD_EXIT_CODE = "net.gprs.ppp-exit"; - static final int POLL_SYSFS_MILLIS = 5 * 1000; - static final int EVENT_POLL_DATA_CONNECTION = 2; - static final int EVENT_PPP_OPERSTATE_CHANGED = 8; - static final int EVENT_PPP_PIDFILE_CHANGED = 9; - - static final byte[] UP_ASCII_STRING = new byte[] { - 'u' & 0xff, - 'p' & 0xff, - }; - static final byte[] DOWN_ASCII_STRING = new byte[] { - 'd' & 0xff, - 'o' & 0xff, - 'w' & 0xff, - 'n' & 0xff, - }; - static final byte[] UNKNOWN_ASCII_STRING = new byte[] { - 'u' & 0xff, - 'n' & 0xff, - 'k' & 0xff, - 'n' & 0xff, - 'o' & 0xff, - 'w' & 0xff, - 'n' & 0xff, - }; - private final byte[] mCheckPPPBuffer = new byte[32]; - - int lastPppdExitCode = EXIT_OK; - - - PppLink(DataConnectionTracker dc) { - super(dc); - } - - public void connect() { - // Clear any previous exit code - SystemProperties.set(PROPERTY_PPPD_EXIT_CODE, ""); - SystemService.start(SERVICE_PPPD_GPRS); - removeMessages(EVENT_POLL_DATA_CONNECTION); - Message poll = obtainMessage(); - poll.what = EVENT_POLL_DATA_CONNECTION; - sendMessageDelayed(poll, POLL_SYSFS_MILLIS); - } - - public void disconnect() { - SystemService.stop(SERVICE_PPPD_GPRS); - } - - public int getLastLinkExitCode() { - return lastPppdExitCode; - } - - public void setPasswordInfo(Cursor cursor) { - StringBuilder builder = new StringBuilder(); - FileOutputStream output = null; - - try { - output = new FileOutputStream("/etc/ppp/pap-secrets"); - if (cursor.moveToFirst()) { - do { - builder.append(cursor.getString(cursor.getColumnIndex("user"))); - builder.append(" "); - builder.append(cursor.getString(cursor.getColumnIndex("server"))); - builder.append(" "); - builder.append(cursor.getString(cursor.getColumnIndex("password"))); - builder.append("\n"); - } while (cursor.moveToNext()); - } - - output.write(builder.toString().getBytes()); - } catch (java.io.IOException e) { - Log.e(LOG_TAG, "Could not create '/etc/ppp/pap-secrets'", e); - } finally { - try { - if (output != null) output.close(); - } catch (java.io.IOException e) { - Log.e(LOG_TAG, "Error closing '/etc/ppp/pap-secrets'", e); - } - } - } - - public void handleMessage (Message msg) { - - switch (msg.what) { - - case EVENT_POLL_DATA_CONNECTION: - checkPPP(); - - // keep polling in case interface goes down - if (dataConnection.state != State.IDLE) { - Message poll = obtainMessage(); - poll.what = EVENT_POLL_DATA_CONNECTION; - sendMessageDelayed(poll, POLL_SYSFS_MILLIS); - } - break; - } - } - - private void checkPPP() { - boolean connecting = (dataConnection.state == State.CONNECTING); - - try { - RandomAccessFile file = new RandomAccessFile(PATH_PPP_OPERSTATE, "r"); - file.read(mCheckPPPBuffer); - file.close(); - - // Unfortunately, we're currently seeing operstate - // "unknown" where one might otherwise expect "up" - if (ArrayUtils.equals(mCheckPPPBuffer, UP_ASCII_STRING, UP_ASCII_STRING.length) - || ArrayUtils.equals(mCheckPPPBuffer, UNKNOWN_ASCII_STRING, - UNKNOWN_ASCII_STRING.length) - && dataConnection.state == State.CONNECTING) { - - Log.i(LOG_TAG, - "found ppp interface. Notifying GPRS connected"); - - if (mLinkChangeRegistrant != null) { - mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP); - } - - connecting = false; - } else if (dataConnection.state == State.CONNECTED - && ArrayUtils.equals(mCheckPPPBuffer, DOWN_ASCII_STRING, - DOWN_ASCII_STRING.length)) { - - Log.i(LOG_TAG, - "ppp interface went down. Reconnecting..."); - - if (mLinkChangeRegistrant != null) { - mLinkChangeRegistrant.notifyResult(LinkState.LINK_DOWN); - } - } - } catch (IOException ex) { - if (! (ex instanceof FileNotFoundException)) { - Log.i(LOG_TAG, "Poll ppp0 ex " + ex.toString()); - } - - if (dataConnection.state == State.CONNECTED && - mLinkChangeRegistrant != null) { - mLinkChangeRegistrant.notifyResult(LinkState.LINK_DOWN); - } - } - - // CONNECTING means pppd has started but negotiation is not complete - // If we're still CONNECTING here, check to see if pppd has - // already exited - if (connecting) { - String exitCode; - - exitCode = SystemProperties.get(PROPERTY_PPPD_EXIT_CODE, ""); - - if (!exitCode.equals("")) { - // pppd has exited. Let's figure out why - lastPppdExitCode = Integer.parseInt(exitCode); - - Log.d(LOG_TAG,"pppd exited with " + exitCode); - - if (mLinkChangeRegistrant != null) { - mLinkChangeRegistrant.notifyResult(LinkState.LINK_EXITED); - } - } - } - - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/RIL.java b/telephony/java/com/android/internal/telephony/gsm/RIL.java deleted file mode 100644 index 45000ba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/RIL.java +++ /dev/null @@ -1,2574 +0,0 @@ -/* - * Copyright (C) 2006 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 static com.android.internal.telephony.gsm.RILConstants.*; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.LocalSocket; -import android.net.LocalSocketAddress; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.os.Parcel; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.telephony.PhoneNumberUtils; -import android.telephony.gsm.SmsManager; -import android.telephony.gsm.SmsMessage; -import android.telephony.NeighboringCellInfo; -import android.util.Config; -import android.util.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; - -/** - * {@hide} - */ -class RILRequest -{ - static final String LOG_TAG = "RILJ"; - - //***** Class Variables - static int sNextSerial = 0; - static Object sSerialMonitor = new Object(); - private static Object sPoolSync = new Object(); - private static RILRequest sPool = null; - private static int sPoolSize = 0; - private static final int MAX_POOL_SIZE = 4; - - //***** Instance Variables - int mSerial; - int mRequest; - Message mResult; - Parcel mp; - RILRequest mNext; - - /** - * Retrieves a new RILRequest instance from the pool. - * - * @param request RIL_REQUEST_* - * @param result sent when operation completes - * @return a RILRequest instance from the pool. - */ - static RILRequest obtain(int request, Message result) { - RILRequest rr = null; - - synchronized(sPoolSync) { - if (sPool != null) { - rr = sPool; - sPool = rr.mNext; - rr.mNext = null; - sPoolSize--; - } - } - - if (rr == null) { - rr = new RILRequest(); - } - - synchronized(sSerialMonitor) { - rr.mSerial = sNextSerial++; - } - rr.mRequest = request; - rr.mResult = result; - rr.mp = Parcel.obtain(); - - if (result != null && result.getTarget() == null) { - throw new NullPointerException("Message target must not be null"); - } - - // first elements in any RIL Parcel - rr.mp.writeInt(request); - rr.mp.writeInt(rr.mSerial); - - return rr; - } - - /** - * Returns a RILRequest instance to the pool. - * - * Note: This should only be called once per use. - */ - void release() { - synchronized (sPoolSync) { - if (sPoolSize < MAX_POOL_SIZE) { - this.mNext = sPool; - sPool = this; - sPoolSize++; - } - } - } - - private RILRequest() - { - } - - static void - resetSerial() - { - synchronized(sSerialMonitor) { - sNextSerial = 0; - } - } - - String - serialString() - { - //Cheesy way to do %04d - StringBuilder sb = new StringBuilder(8); - String sn; - - sn = Integer.toString(mSerial); - - //sb.append("J["); - sb.append('['); - for (int i = 0, s = sn.length() ; i < 4 - s; i++) { - sb.append('0'); - } - - sb.append(sn); - sb.append(']'); - return sb.toString(); - } - - void - onError(int error) - { - CommandException ex; - - ex = CommandException.fromRilErrno(error); - - if (RIL.RILJ_LOGD) Log.d(LOG_TAG, serialString() + "< " - + RIL.requestToString(mRequest) - + " error: " + ex); - - if (mResult != null) { - AsyncResult.forMessage(mResult, null, ex); - mResult.sendToTarget(); - } - - if (mp != null) { - mp.recycle(); - mp = null; - } - } -} - - -/** - * RIL implementation of the CommandsInterface. - * FIXME public only for testing - * - * {@hide} - */ -public final class RIL extends BaseCommands implements CommandsInterface -{ - static final String LOG_TAG = "RILJ"; - private static final boolean DBG = false; - static final boolean RILJ_LOGD = Config.LOGD; - static final boolean RILJ_LOGV = DBG ? Config.LOGD : Config.LOGV; - static int WAKE_LOCK_TIMEOUT = 5000; - - //***** Instance Variables - - LocalSocket mSocket; - HandlerThread mSenderThread; - RILSender mSender; - Thread mReceiverThread; - RILReceiver mReceiver; - private Context mContext; - WakeLock mWakeLock; - int mRequestMessagesPending; - - // Is this the first radio state change? - private boolean mInitialRadioStateChange = true; - - //I'd rather this be LinkedList or something - ArrayList<RILRequest> mRequestsList = new ArrayList<RILRequest>(); - - Object mLastNITZTimeInfo; - - //***** Events - - static final int EVENT_SEND = 1; - static final int EVENT_WAKE_LOCK_TIMEOUT = 2; - - //***** Constants - - // match with constant in ril.cpp - static final int RIL_MAX_COMMAND_BYTES = (8 * 1024); - static final int RESPONSE_SOLICITED = 0; - static final int RESPONSE_UNSOLICITED = 1; - - static final String SOCKET_NAME_RIL = "rild"; - - static final int SOCKET_OPEN_RETRY_MILLIS = 4 * 1000; - - - BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { - sendScreenState(true); - } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { - sendScreenState(false); - } else { - Log.w(LOG_TAG, "RIL received unexpected Intent: " + intent.getAction()); - } - } - }; - - class RILSender extends Handler implements Runnable - { - public RILSender(Looper looper) { - super(looper); - } - - // Only allocated once - byte[] dataLength = new byte[4]; - - //***** Runnable implementation - public void - run() - { - //setup if needed - } - - - //***** Handler implemementation - - public void - handleMessage(Message msg) - { - RILRequest rr = (RILRequest)(msg.obj); - RILRequest req = null; - - switch (msg.what) { - case EVENT_SEND: - /** - * mRequestMessagePending++ already happened for every - * EVENT_SEND, thus we must make sure - * mRequestMessagePending-- happens once and only once - */ - boolean alreadySubtracted = false; - try { - LocalSocket s; - - s = mSocket; - - if (s == null) { - rr.onError(RADIO_NOT_AVAILABLE); - rr.release(); - mRequestMessagesPending--; - alreadySubtracted = true; - return; - } - - synchronized (mRequestsList) { - mRequestsList.add(rr); - } - - mRequestMessagesPending--; - alreadySubtracted = true; - - byte[] data; - - data = rr.mp.marshall(); - rr.mp.recycle(); - rr.mp = null; - - if (data.length > RIL_MAX_COMMAND_BYTES) { - throw new RuntimeException( - "Parcel larger than max bytes allowed! " - + data.length); - } - - // parcel length in big endian - dataLength[0] = dataLength[1] = 0; - dataLength[2] = (byte)((data.length >> 8) & 0xff); - dataLength[3] = (byte)((data.length) & 0xff); - - //Log.v(LOG_TAG, "writing packet: " + data.length + " bytes"); - - s.getOutputStream().write(dataLength); - s.getOutputStream().write(data); - } catch (IOException ex) { - Log.e(LOG_TAG, "IOException", ex); - req = findAndRemoveRequestFromList(rr.mSerial); - // make sure this request has not already been handled, - // eg, if RILReceiver cleared the list. - if (req != null || !alreadySubtracted) { - rr.onError(RADIO_NOT_AVAILABLE); - rr.release(); - } - } catch (RuntimeException exc) { - Log.e(LOG_TAG, "Uncaught exception ", exc); - req = findAndRemoveRequestFromList(rr.mSerial); - // make sure this request has not already been handled, - // eg, if RILReceiver cleared the list. - if (req != null || !alreadySubtracted) { - rr.onError(GENERIC_FAILURE); - rr.release(); - } - } - - if (!alreadySubtracted) { - mRequestMessagesPending--; - } - - break; - - case EVENT_WAKE_LOCK_TIMEOUT: - // Haven't heard back from the last request. Assume we're - // not getting a response and release the wake lock. - // TODO should we clean up mRequestList and mRequestPending - synchronized (mWakeLock) { - if (mWakeLock.isHeld()) { - if (RILJ_LOGD) { - synchronized (mRequestsList) { - int count = mRequestsList.size(); - Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " + - " mReqPending=" + mRequestMessagesPending + - " mRequestList=" + count); - - for (int i = 0; i < count; i++) { - rr = mRequestsList.get(i); - Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] " + - requestToString(rr.mRequest)); - - } - } - } - mWakeLock.release(); - } - } - - break; - } - } - } - - /** - * Reads in a single RIL message off the wire. A RIL message consists - * of a 4-byte little-endian length and a subsequent series of bytes. - * The final message (length header omitted) is read into - * <code>buffer</code> and the length of the final message (less header) - * is returned. A return value of -1 indicates end-of-stream. - * - * @param is non-null; Stream to read from - * @param buffer Buffer to fill in. Must be as large as maximum - * message size, or an ArrayOutOfBounds exception will be thrown. - * @return Length of message less header, or -1 on end of stream. - * @throws IOException - */ - private static int readRilMessage(InputStream is, byte[] buffer) - throws IOException - { - int countRead; - int offset; - int remaining; - int messageLength; - - // First, read in the length of the message - offset = 0; - remaining = 4; - do { - countRead = is.read(buffer, offset, remaining); - - if (countRead < 0 ) { - Log.e(LOG_TAG, "Hit EOS reading message length"); - return -1; - } - - offset += countRead; - remaining -= countRead; - } while (remaining > 0); - - messageLength = ((buffer[0] & 0xff) << 24) - | ((buffer[1] & 0xff) << 16) - | ((buffer[2] & 0xff) << 8) - | (buffer[3] & 0xff); - - // Then, re-use the buffer and read in the message itself - offset = 0; - remaining = messageLength; - do { - countRead = is.read(buffer, offset, remaining); - - if (countRead < 0 ) { - Log.e(LOG_TAG, "Hit EOS reading message. messageLength=" + messageLength - + " remaining=" + remaining); - return -1; - } - - offset += countRead; - remaining -= countRead; - } while (remaining > 0); - - return messageLength; - } - - class RILReceiver implements Runnable - { - byte[] buffer; - - RILReceiver() - { - buffer = new byte[RIL_MAX_COMMAND_BYTES]; - } - - public void - run() - { - int retryCount = 0; - - try {for (;;) { - LocalSocket s = null; - LocalSocketAddress l; - - try { - s = new LocalSocket(); - l = new LocalSocketAddress(SOCKET_NAME_RIL, - LocalSocketAddress.Namespace.RESERVED); - s.connect(l); - } catch (IOException ex){ - try { - if (s != null) { - s.close(); - } - } catch (IOException ex2) { - //ignore failure to close after failure to connect - } - - // don't print an error message after the the first time - // or after the 8th time - - if (retryCount == 8) { - Log.e (LOG_TAG, - "Couldn't find '" + SOCKET_NAME_RIL - + "' socket after " + retryCount - + " times, continuing to retry silently"); - } else if (retryCount > 0 && retryCount < 8) { - Log.i (LOG_TAG, - "Couldn't find '" + SOCKET_NAME_RIL - + "' socket; retrying after timeout"); - } - - try { - Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); - } catch (InterruptedException er) { - } - - retryCount++; - continue; - } - - retryCount = 0; - - mSocket = s; - Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket"); - - int length = 0; - try { - InputStream is = mSocket.getInputStream(); - - for (;;) { - Parcel p; - - length = readRilMessage(is, buffer); - - if (length < 0) { - // End-of-stream reached - break; - } - - p = Parcel.obtain(); - p.unmarshall(buffer, 0, length); - p.setDataPosition(0); - - //Log.v(LOG_TAG, "Read packet: " + length + " bytes"); - - processResponse(p); - p.recycle(); - } - } catch (java.io.IOException ex) { - Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed", - ex); - } catch (Throwable tr) { - Log.e(LOG_TAG, "Uncaught exception read length=" + length + - "Exception:" + tr.toString()); - } - - Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL - + "' socket"); - - setRadioState (RadioState.RADIO_UNAVAILABLE); - - try { - mSocket.close(); - } catch (IOException ex) { - } - - mSocket = null; - RILRequest.resetSerial(); - - // Clear request list on close - synchronized (mRequestsList) { - for (int i = 0, sz = mRequestsList.size() ; i < sz ; i++) { - RILRequest rr = mRequestsList.get(i); - rr.onError(RADIO_NOT_AVAILABLE); - rr.release(); - } - - mRequestsList.clear(); - } - }} catch (Throwable tr) { - Log.e(LOG_TAG,"Uncaught exception", tr); - } - } - } - - - - //***** Constructor - - public - RIL(Context context) - { - super(context); - - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); - mWakeLock.setReferenceCounted(false); - mRequestMessagesPending = 0; - - mContext = context; - - mSenderThread = new HandlerThread("RILSender"); - mSenderThread.start(); - - Looper looper = mSenderThread.getLooper(); - mSender = new RILSender(looper); - - mReceiver = new RILReceiver(); - mReceiverThread = new Thread(mReceiver, "RILReceiver"); - mReceiverThread.start(); - - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_SCREEN_ON); - filter.addAction(Intent.ACTION_SCREEN_OFF); - context.registerReceiver(mIntentReceiver, filter); - } - - //***** CommandsInterface implementation - - @Override public void - setOnNITZTime(Handler h, int what, Object obj) - { - super.setOnNITZTime(h, what, obj); - - // Send the last NITZ time if we have it - if (mLastNITZTimeInfo != null) { - mNITZTimeRegistrant - .notifyRegistrant( - new AsyncResult (null, mLastNITZTimeInfo, null)); - mLastNITZTimeInfo = null; - } - } - - public void - getSimStatus(Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_SIM_STATUS, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - supplySimPin(String pin, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(1); - rr.mp.writeString(pin); - - send(rr); - } - - public void - supplySimPuk(String puk, String newPin, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(2); - rr.mp.writeString(puk); - rr.mp.writeString(newPin); - - send(rr); - } - - public void - supplySimPin2(String pin, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PIN2, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(1); - rr.mp.writeString(pin); - - send(rr); - } - - public void - supplySimPuk2(String puk, String newPin2, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_SIM_PUK2, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(2); - rr.mp.writeString(puk); - rr.mp.writeString(newPin2); - - send(rr); - } - - public void - changeSimPin(String oldPin, String newPin, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(2); - rr.mp.writeString(oldPin); - rr.mp.writeString(newPin); - - send(rr); - } - - public void - changeSimPin2(String oldPin2, String newPin2, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_SIM_PIN2, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(2); - rr.mp.writeString(oldPin2); - rr.mp.writeString(newPin2); - - send(rr); - } - - public void - changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(3); - rr.mp.writeString(facility); - rr.mp.writeString(oldPwd); - rr.mp.writeString(newPwd); - - send(rr); - } - - public void - supplyNetworkDepersonalization(String netpin, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeInt(1); - rr.mp.writeString(netpin); - - send(rr); - } - - public void - getCurrentCalls (Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getPDPContextList(Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_PDP_CONTEXT_LIST, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - dial (String address, int clirMode, Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_DIAL, result); - - rr.mp.writeString(address); - rr.mp.writeInt(clirMode); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getIMSI(Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMSI, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> getIMSI:RIL_REQUEST_GET_IMSI " + RIL_REQUEST_GET_IMSI + " " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getIMEI(Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEI, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getIMEISV(Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_IMEISV, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void - hangupConnection (int gsmIndex, Message result) - { - if (RILJ_LOGD) riljLog("hangupConnection: gsmIndex=" + gsmIndex); - - RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + gsmIndex); - - rr.mp.writeInt(1); - rr.mp.writeInt(gsmIndex); - - send(rr); - } - - public void - hangupWaitingOrBackground (Message result) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, - result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - hangupForegroundResumeBackground (Message result) - { - RILRequest rr - = RILRequest.obtain( - RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, - result); - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - switchWaitingOrHoldingAndActive (Message result) - { - RILRequest rr - = RILRequest.obtain( - RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, - result); - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - conference (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_CONFERENCE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void - separateConnection (int gsmIndex, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SEPARATE_CONNECTION, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + gsmIndex); - - rr.mp.writeInt(1); - rr.mp.writeInt(gsmIndex); - - send(rr); - } - - public void - acceptCall (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_ANSWER, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - rejectCall (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_UDUB, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - explicitCallTransfer (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getLastCallFailCause (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getLastPdpFailCause (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_LAST_PDP_FAIL_CAUSE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setMute (boolean enableMute, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_MUTE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + enableMute); - - rr.mp.writeInt(1); - rr.mp.writeInt(enableMute ? 1 : 0); - - send(rr); - } - - public void - getMute (Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_GET_MUTE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getSignalStrength (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SIGNAL_STRENGTH, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getRegistrationState (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_REGISTRATION_STATE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getGPRSRegistrationState (Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_GPRS_REGISTRATION_STATE, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getOperator(Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_OPERATOR, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - sendDtmf(char c, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DTMF, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(Character.toString(c)); - - send(rr); - } - - public void - startDtmf(char c, Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DTMF_START, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(Character.toString(c)); - - send(rr); - } - - public void - stopDtmf(Message result) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DTMF_STOP, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void - sendSMS (String smscPDU, String pdu, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SEND_SMS, result); - - rr.mp.writeInt(2); - rr.mp.writeString(smscPDU); - rr.mp.writeString(pdu); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void deleteSmsOnSim(int index, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_DELETE_SMS_ON_SIM, - response); - - rr.mp.writeInt(1); - rr.mp.writeInt(index); - - if (RILJ_LOGD) { - riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) - + " " + index); - } - - send(rr); - } - - public void writeSmsToSim(int status, String smsc, String pdu, Message response) { - status = translateStatus(status); - - RILRequest rr = RILRequest.obtain(RIL_REQUEST_WRITE_SMS_TO_SIM, - response); - - rr.mp.writeInt(status); - rr.mp.writeString(pdu); - rr.mp.writeString(smsc); - - if (RILJ_LOGD) { - riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) - + " " + status); - } - - send(rr); - } - - /** - * Translates EF_SMS status bits to a status value compatible with - * SMS AT commands. See TS 27.005 3.1. - */ - private int translateStatus(int status) { - switch(status & 0x7) { - case SmsManager.STATUS_ON_SIM_READ: - return 1; - case SmsManager.STATUS_ON_SIM_UNREAD: - return 0; - case SmsManager.STATUS_ON_SIM_SENT: - return 3; - case SmsManager.STATUS_ON_SIM_UNSENT: - return 2; - } - - // Default to READ. - return 1; - } - - public void - setupDefaultPDP(String apn, String user, String password, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SETUP_DEFAULT_PDP, result); - - rr.mp.writeInt(3); - rr.mp.writeString(apn); - rr.mp.writeString(user); - rr.mp.writeString(password); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " - + apn); - - send(rr); - } - - public void - deactivateDefaultPDP(int cid, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_DEACTIVATE_DEFAULT_PDP, result); - - rr.mp.writeInt(1); - rr.mp.writeString(Integer.toString(cid)); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + cid); - - send(rr); - } - - public void - setRadioPower(boolean on, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_RADIO_POWER, result); - - rr.mp.writeInt(1); - rr.mp.writeInt(on ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setSuppServiceNotifications(boolean enable, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result); - - rr.mp.writeInt(1); - rr.mp.writeInt(enable ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest)); - - send(rr); - } - - public void - acknowledgeLastIncomingSMS(boolean success, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SMS_ACKNOWLEDGE, result); - - rr.mp.writeInt(1); - rr.mp.writeInt(success ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - simIO (int command, int fileid, String path, int p1, int p2, int p3, - String data, String pin2, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SIM_IO, result); - - rr.mp.writeInt(command); - rr.mp.writeInt(fileid); - rr.mp.writeString(path); - rr.mp.writeInt(p1); - rr.mp.writeInt(p2); - rr.mp.writeInt(p3); - rr.mp.writeString(data); - rr.mp.writeString(pin2); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> simIO: " + requestToString(rr.mRequest) - + " 0x" + Integer.toHexString(command) - + " 0x" + Integer.toHexString(fileid) + " " - + p1 + "," + p2 + "," + p3); - - send(rr); - } - - public void - getCLIR(Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_GET_CLIR, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setCLIR(int clirMode, Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_CLIR, result); - - // count ints - rr.mp.writeInt(1); - - rr.mp.writeInt(clirMode); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + clirMode); - - send(rr); - } - - public void - queryCallWaiting(int serviceClass, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_WAITING, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(serviceClass); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + serviceClass); - - send(rr); - } - - public void - setCallWaiting(boolean enable, int serviceClass, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_CALL_WAITING, response); - - rr.mp.writeInt(2); - rr.mp.writeInt(enable ? 1 : 0); - rr.mp.writeInt(serviceClass); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + enable + ", " + serviceClass); - - send(rr); - } - - public void - setNetworkSelectionModeAutomatic(Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setNetworkSelectionModeManual(String operatorNumeric, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + operatorNumeric); - - rr.mp.writeString(operatorNumeric); - - send(rr); - } - - public void - getNetworkSelectionMode(Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - getAvailableNetworks(Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - setCallForward(int action, int cfReason, int serviceClass, - String number, int timeSeconds, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_CALL_FORWARD, response); - - rr.mp.writeInt(action); - rr.mp.writeInt(cfReason); - rr.mp.writeInt(serviceClass); - rr.mp.writeInt(PhoneNumberUtils.toaFromString(number)); - rr.mp.writeString(number); - rr.mp.writeInt (timeSeconds); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + action + " " + cfReason + " " + serviceClass - + timeSeconds); - - send(rr); - } - - public void - queryCallForwardStatus(int cfReason, int serviceClass, - String number, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, response); - - rr.mp.writeInt(2); // 2 is for query action, not in used anyway - rr.mp.writeInt(cfReason); - rr.mp.writeInt(serviceClass); - rr.mp.writeInt(PhoneNumberUtils.toaFromString(number)); - rr.mp.writeString(number); - rr.mp.writeInt (0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + cfReason + " " + serviceClass); - - send(rr); - } - - public void - queryCLIP(Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_CLIP, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void - getBasebandVersion (Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_BASEBAND_VERSION, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void - queryFacilityLock (String facility, String password, int serviceClass, - Message response) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_QUERY_FACILITY_LOCK, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - // count strings - rr.mp.writeInt(3); - - rr.mp.writeString(facility); - rr.mp.writeString(password); - - rr.mp.writeString(Integer.toString(serviceClass)); - - send(rr); - } - - public void - setFacilityLock (String facility, boolean lockState, String password, - int serviceClass, Message response) - { - String lockString; - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_FACILITY_LOCK, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - // count strings - rr.mp.writeInt(4); - - rr.mp.writeString(facility); - lockString = (lockState)?"1":"0"; - rr.mp.writeString(lockString); - rr.mp.writeString(password); - rr.mp.writeString(Integer.toString(serviceClass)); - - send(rr); - - } - - public void - sendUSSD (String ussdString, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SEND_USSD, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + ussdString); - - rr.mp.writeString(ussdString); - - send(rr); - } - - // inherited javadoc suffices - public void cancelPendingUssd (Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_CANCEL_USSD, response); - - if (RILJ_LOGD) riljLog(rr.serialString() - + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - - public void resetRadio(Message result) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_RESET_RADIO, result); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - public void invokeOemRilRequestRaw(byte[] data, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_RAW, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + "[" + SimUtils.bytesToHexString(data) + "]"); - - rr.mp.writeByteArray(data); - - send(rr); - - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) - { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_OEM_HOOK_STRINGS, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeStringArray(strings); - - send(rr); - } - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param response is callback message - */ - public void setBandMode (int bandMode, Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_SET_BAND_MODE, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(bandMode); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " " + bandMode); - - send(rr); - } - - /** - * Query the list of band mode supported by RF. - * - * @param response is callback message - * ((AsyncResult)response.obj).result is an int[] with every - * element representing one avialable BM_*_BAND - */ - public void queryAvailableBandMode (Message response) { - RILRequest rr - = RILRequest.obtain(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void sendTerminalResponse(String contents, Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(contents); - send(rr); - } - - /** - * {@inheritDoc} - */ - public void sendEnvelope(String contents, Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - rr.mp.writeString(contents); - send(rr); - } - - /** - * {@inheritDoc} - */ - public void handleCallSetupRequestFromSim( - boolean accept, Message response) { - - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, - response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - int[] param = new int[1]; - param[0] = accept ? 1 : 0; - rr.mp.writeIntArray(param); - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setPreferredNetworkType(int networkType , Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response); - - rr.mp.writeInt(1); - rr.mp.writeInt(networkType); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) - + " : " + networkType); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void getPreferredNetworkType(Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void getNeighboringCids(Message response) { - RILRequest rr = RILRequest.obtain( - RILConstants.RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, response); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)); - - send(rr); - } - - /** - * {@inheritDoc} - */ - public void setLocationUpdates(boolean enable, Message response) { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_SET_LOCATION_UPDATES, response); - rr.mp.writeInt(1); - rr.mp.writeInt(enable ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " - + requestToString(rr.mRequest) + ": " + enable); - - send(rr); - } - - //***** Private Methods - - private void sendScreenState(boolean on) - { - RILRequest rr = RILRequest.obtain(RIL_REQUEST_SCREEN_STATE, null); - rr.mp.writeInt(1); - rr.mp.writeInt(on ? 1 : 0); - - if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + ": " + on); - - send(rr); - } - - protected void - onRadioAvailable() - { - // In case screen state was lost (due to process crash), - // this ensures that the RIL knows the correct screen state. - - // TODO: Should query Power Manager and send the actual - // screen state. Just send true for now. - sendScreenState(true); - } - - private void setRadioStateFromRILInt(int state) { - RadioState newState; - - /* RIL_RadioState ril.h */ - switch(state) { - case 0: newState = RadioState.RADIO_OFF; break; - case 1: newState = RadioState.RADIO_UNAVAILABLE; break; - case 2: newState = RadioState.SIM_NOT_READY; break; - case 3: newState = RadioState.SIM_LOCKED_OR_ABSENT; break; - case 4: newState = RadioState.SIM_READY; break; - default: - throw new RuntimeException( - "Unrecognized RIL_RadioState: " +state); - } - - if (mInitialRadioStateChange) { - mInitialRadioStateChange = false; - if (newState.isOn()) { - /* If this is our first notification, make sure the radio - * is powered off. This gets the radio into a known state, - * since it's possible for the phone proc to have restarted - * (eg, if it or the runtime crashed) without the RIL - * and/or radio knowing. - */ - if (RILJ_LOGD) Log.d(LOG_TAG, "Radio ON @ init; reset to OFF"); - setRadioPower(false, null); - return; - } - } - - setRadioState(newState); - } - - /** - * Holds a PARTIAL_WAKE_LOCK whenever - * a) There is outstanding RIL request sent to RIL deamon and no replied - * b) There is a request waiting to be sent out. - * - * There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't - * happen often. - */ - - private void - acquireWakeLock() - { - synchronized (mWakeLock) { - mWakeLock.acquire(); - mRequestMessagesPending++; - - mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); - Message msg = mSender.obtainMessage(EVENT_WAKE_LOCK_TIMEOUT); - mSender.sendMessageDelayed(msg, WAKE_LOCK_TIMEOUT); - } - } - - private void - releaseWakeLockIfDone() - { - synchronized (mWakeLock) { - if (mWakeLock.isHeld() && - (mRequestMessagesPending == 0) && - (mRequestsList.size() == 0)) { - mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT); - mWakeLock.release(); - } - } - } - - private void - send(RILRequest rr) - { - Message msg; - - msg = mSender.obtainMessage(EVENT_SEND, rr); - - acquireWakeLock(); - - msg.sendToTarget(); - } - - private void - processResponse (Parcel p) - { - int type; - - type = p.readInt(); - - if (type == RESPONSE_UNSOLICITED) { - processUnsolicited (p); - } else if (type == RESPONSE_SOLICITED) { - processSolicited (p); - } - - releaseWakeLockIfDone(); - } - - - - private RILRequest findAndRemoveRequestFromList(int serial) - { - synchronized (mRequestsList) { - for (int i = 0, s = mRequestsList.size() ; i < s ; i++) { - RILRequest rr = mRequestsList.get(i); - - if (rr.mSerial == serial) { - mRequestsList.remove(i); - return rr; - } - } - } - - return null; - } - - private void - processSolicited (Parcel p) - { - int serial, error; - boolean found = false; - - serial = p.readInt(); - error = p.readInt(); - - RILRequest rr; - - rr = findAndRemoveRequestFromList(serial); - - if (rr == null) { - Log.w(LOG_TAG, "Unexpected solicited response! sn: " - + serial + " error: " + error); - return; - } - - if (error != 0) { - rr.onError(error); - rr.release(); - return; - } - - Object ret; - - try {switch (rr.mRequest) { -/* - cat libs/telephony/ril_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: ret = \2(p); break;/' -*/ - case RIL_REQUEST_GET_SIM_STATUS: ret = responseSimStatus(p); break; - case RIL_REQUEST_ENTER_SIM_PIN: ret = responseVoid(p); break; - case RIL_REQUEST_ENTER_SIM_PUK: ret = responseVoid(p); break; - case RIL_REQUEST_ENTER_SIM_PIN2: ret = responseVoid(p); break; - case RIL_REQUEST_ENTER_SIM_PUK2: ret = responseVoid(p); break; - case RIL_REQUEST_CHANGE_SIM_PIN: ret = responseVoid(p); break; - case RIL_REQUEST_CHANGE_SIM_PIN2: ret = responseVoid(p); break; - case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: ret = responseVoid(p); break; - case RIL_REQUEST_GET_CURRENT_CALLS: ret = responseCallList(p); break; - case RIL_REQUEST_DIAL: ret = responseVoid(p); break; - case RIL_REQUEST_GET_IMSI: ret = responseString(p); break; - case RIL_REQUEST_HANGUP: ret = responseVoid(p); break; - case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break; - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: ret = responseVoid(p); break; - case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break; - case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break; - case RIL_REQUEST_UDUB: ret = responseVoid(p); break; - case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: ret = responseInts(p); break; - case RIL_REQUEST_SIGNAL_STRENGTH: ret = responseInts(p); break; - case RIL_REQUEST_REGISTRATION_STATE: ret = responseStrings(p); break; - case RIL_REQUEST_GPRS_REGISTRATION_STATE: ret = responseStrings(p); break; - case RIL_REQUEST_OPERATOR: ret = responseStrings(p); break; - case RIL_REQUEST_RADIO_POWER: ret = responseVoid(p); break; - case RIL_REQUEST_DTMF: ret = responseVoid(p); break; - case RIL_REQUEST_SEND_SMS: ret = responseSMS(p); break; - case RIL_REQUEST_SEND_SMS_EXPECT_MORE: ret = responseSMS(p); break; - case RIL_REQUEST_SETUP_DEFAULT_PDP: ret = responseStrings(p); break; - case RIL_REQUEST_SIM_IO: ret = responseSIM_IO(p); break; - case RIL_REQUEST_SEND_USSD: ret = responseVoid(p); break; - case RIL_REQUEST_CANCEL_USSD: ret = responseVoid(p); break; - case RIL_REQUEST_GET_CLIR: ret = responseInts(p); break; - case RIL_REQUEST_SET_CLIR: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: ret = responseCallForward(p); break; - case RIL_REQUEST_SET_CALL_FORWARD: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_CALL_WAITING: ret = responseInts(p); break; - case RIL_REQUEST_SET_CALL_WAITING: ret = responseVoid(p); break; - case RIL_REQUEST_SMS_ACKNOWLEDGE: ret = responseVoid(p); break; - case RIL_REQUEST_GET_IMEI: ret = responseString(p); break; - case RIL_REQUEST_GET_IMEISV: ret = responseString(p); break; - case RIL_REQUEST_ANSWER: ret = responseVoid(p); break; - case RIL_REQUEST_DEACTIVATE_DEFAULT_PDP: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_FACILITY_LOCK: ret = responseInts(p); break; - case RIL_REQUEST_SET_FACILITY_LOCK: ret = responseVoid(p); break; - case RIL_REQUEST_CHANGE_BARRING_PASSWORD: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: ret = responseInts(p); break; - case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: ret = responseVoid(p); break; - case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : ret = responseNetworkInfos(p); break; - case RIL_REQUEST_DTMF_START: ret = responseVoid(p); break; - case RIL_REQUEST_DTMF_STOP: ret = responseVoid(p); break; - case RIL_REQUEST_BASEBAND_VERSION: ret = responseString(p); break; - case RIL_REQUEST_SEPARATE_CONNECTION: ret = responseVoid(p); break; - case RIL_REQUEST_SET_MUTE: ret =responseVoid(p); break; - case RIL_REQUEST_GET_MUTE: ret = responseInts(p); break; - case RIL_REQUEST_QUERY_CLIP: ret = responseInts(p); break; - case RIL_REQUEST_LAST_PDP_FAIL_CAUSE: ret = responseInts(p); break; - case RIL_REQUEST_PDP_CONTEXT_LIST: ret = responseContextList(p); break; - case RIL_REQUEST_RESET_RADIO: ret = responseVoid(p); break; - case RIL_REQUEST_OEM_HOOK_RAW: ret = responseRaw(p); break; - case RIL_REQUEST_OEM_HOOK_STRINGS: ret = responseStrings(p); break; - case RIL_REQUEST_SCREEN_STATE: ret = responseVoid(p); break; - case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: ret = responseVoid(p); break; - case RIL_REQUEST_WRITE_SMS_TO_SIM: ret = responseInts(p); break; - case RIL_REQUEST_DELETE_SMS_ON_SIM: ret = responseVoid(p); break; - case RIL_REQUEST_SET_BAND_MODE: ret = responseVoid(p); break; - case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: ret = responseInts(p); break; - case RIL_REQUEST_STK_GET_PROFILE: ret = responseString(p); break; - case RIL_REQUEST_STK_SET_PROFILE: ret = responseVoid(p); break; - case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: ret = responseString(p); break; - case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: ret = responseVoid(p); break; - case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: ret = responseInts(p); break; - case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: ret = responseVoid(p); break; - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: ret = responseVoid(p); break; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: ret = responseInts(p); break; - case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: ret = responseCellList(p); break; - case RIL_REQUEST_SET_LOCATION_UPDATES: ret = responseVoid(p); break; - - default: - throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest); - //break; - }} catch (Throwable tr) { - // Exceptions here usually mean invalid RIL responses - - Log.w(LOG_TAG, rr.serialString() + "< " - + requestToString(rr.mRequest) + " exception, possible invalid RIL response", tr); - - if (rr.mResult != null) { - AsyncResult.forMessage(rr.mResult, null, tr); - rr.mResult.sendToTarget(); - } - rr.release(); - return; - } - - if (RILJ_LOGD) riljLog(rr.serialString() + "< " + requestToString(rr.mRequest) - + " " + retToString(rr.mRequest, ret)); - - if (rr.mResult != null) { - AsyncResult.forMessage(rr.mResult, ret, null); - rr.mResult.sendToTarget(); - } - - rr.release(); - } - - private String - retToString(int req, Object ret) - { - if (ret == null) return ""; - switch (req) { - // Don't log these return values, for privacy's sake. - case RIL_REQUEST_GET_IMSI: - case RIL_REQUEST_GET_IMEI: - case RIL_REQUEST_GET_IMEISV: - return ""; - } - - StringBuilder sb; - String s; - int length; - if (ret instanceof int[]){ - int[] intArray = (int[]) ret; - length = intArray.length; - sb = new StringBuilder("{"); - if (length > 0) { - int i = 0; - sb.append(intArray[i++]); - while ( i < length) { - sb.append(", ").append(intArray[i++]); - } - } - sb.append("}"); - s = sb.toString(); - } else if (ret instanceof String[]) { - String[] strings = (String[]) ret; - length = strings.length; - sb = new StringBuilder("{"); - if (length > 0) { - int i = 0; - sb.append(strings[i++]); - while ( i < length) { - sb.append(", ").append(strings[i++]); - } - } - sb.append("}"); - s = sb.toString(); - }else if (req == RIL_REQUEST_GET_CURRENT_CALLS) { - ArrayList<DriverCall> calls = (ArrayList<DriverCall>) ret; - sb = new StringBuilder(" "); - for (DriverCall dc : calls) { - sb.append("[").append(dc).append("] "); - } - s = sb.toString(); - } else if (req == RIL_REQUEST_GET_NEIGHBORING_CELL_IDS) { - ArrayList<NeighboringCellInfo> cells; - cells = (ArrayList<NeighboringCellInfo>) ret; - sb = new StringBuilder(" "); - for (NeighboringCellInfo cell : cells) { - sb.append(cell).append(" "); - } - s = sb.toString(); - } else { - s = ret.toString(); - } - return s; - } - - private void - processUnsolicited (Parcel p) - { - int response; - Object ret; - - response = p.readInt(); - - try {switch(response) { -/* - cat libs/telephony/ril_unsol_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{([^,]+),[^,]+,([^}]+).+/case \1: \2(rr, p); break;/' -*/ - - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: ret = responseVoid(p); break; - case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break; - case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: ret = responseVoid(p); break; - case RIL_UNSOL_RESPONSE_NEW_SMS: ret = responseString(p); break; - case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: ret = responseString(p); break; - case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: ret = responseInts(p); break; - case RIL_UNSOL_ON_USSD: ret = responseStrings(p); break; - case RIL_UNSOL_NITZ_TIME_RECEIVED: ret = responseString(p); break; - case RIL_UNSOL_SIGNAL_STRENGTH: ret = responseInts(p); break; - case RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED: ret = responseContextList(p);break; - case RIL_UNSOL_SUPP_SVC_NOTIFICATION: ret = responseSuppServiceNotification(p); break; - case RIL_UNSOL_STK_SESSION_END: ret = responseVoid(p); break; - case RIL_UNSOL_STK_PROACTIVE_COMMAND: ret = responseString(p); break; - case RIL_UNSOL_STK_EVENT_NOTIFY: ret = responseString(p); break; - case RIL_UNSOL_STK_CALL_SETUP: ret = responseInts(p); break; - case RIL_UNSOL_SIM_SMS_STORAGE_FULL: ret = responseVoid(p); break; - case RIL_UNSOL_SIM_REFRESH: ret = responseInts(p); break; - case RIL_UNSOL_CALL_RING: ret = responseVoid(p); break; - default: - throw new RuntimeException("Unrecognized unsol response: " + response); - //break; (implied) - }} catch (Throwable tr) { - Log.e(LOG_TAG, "Exception processing unsol response: " + response + - "Exception:" + tr.toString()); - return; - } - - switch(response) { - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: - /* has bonus radio state int */ - setRadioStateFromRILInt(p.readInt()); - - if (RILJ_LOGD) unsljLogMore(response, mState.toString()); - break; - case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: - if (RILJ_LOGD) unsljLog(response); - - mCallStateRegistrants - .notifyRegistrants(new AsyncResult(null, null, null)); - break; - case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: - if (RILJ_LOGD) unsljLog(response); - - mNetworkStateRegistrants - .notifyRegistrants(new AsyncResult(null, null, null)); - break; - case RIL_UNSOL_RESPONSE_NEW_SMS: { - if (RILJ_LOGD) unsljLog(response); - - // FIXME this should move up a layer - String a[] = new String[2]; - - a[1] = (String)ret; - - SmsMessage sms; - - sms = SmsMessage.newFromCMT(a); - if (mSMSRegistrant != null) { - mSMSRegistrant - .notifyRegistrant(new AsyncResult(null, sms, null)); - } - break; - } - case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mSmsStatusRegistrant != null) { - mSmsStatusRegistrant.notifyRegistrant( - new AsyncResult(null, ret, null)); - } - break; - case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: - if (RILJ_LOGD) unsljLogRet(response, ret); - - int[] smsIndex = (int[])ret; - - if(smsIndex.length == 1) { - if (mSmsOnSimRegistrant != null) { - mSmsOnSimRegistrant. - notifyRegistrant(new AsyncResult(null, smsIndex, null)); - } - } else { - if (RILJ_LOGD) riljLog(" NEW_SMS_ON_SIM ERROR with wrong length " - + smsIndex.length); - } - break; - case RIL_UNSOL_ON_USSD: - String[] resp = (String[])ret; - - if (resp.length < 2) { - resp = new String[2]; - resp[0] = ((String[])ret)[0]; - resp[1] = null; - } - if (RILJ_LOGD) unsljLogMore(response, resp[0]); - if (mUSSDRegistrant != null) { - mUSSDRegistrant.notifyRegistrant( - new AsyncResult (null, resp, null)); - } - break; - case RIL_UNSOL_NITZ_TIME_RECEIVED: - if (RILJ_LOGD) unsljLogRet(response, ret); - - // has bonus long containing milliseconds since boot that the NITZ - // time was received - long nitzReceiveTime = p.readLong(); - - Object[] result = new Object[2]; - - result[0] = ret; - result[1] = Long.valueOf(nitzReceiveTime); - - if (mNITZTimeRegistrant != null) { - - mNITZTimeRegistrant - .notifyRegistrant(new AsyncResult (null, result, null)); - } else { - // in case NITZ time registrant isnt registered yet - mLastNITZTimeInfo = result; - } - break; - - case RIL_UNSOL_SIGNAL_STRENGTH: - // Note this is set to "verbose" because it happens - // frequently - if (RILJ_LOGV) unsljLogvRet(response, ret); - - if (mSignalStrengthRegistrant != null) { - mSignalStrengthRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - case RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED: - if (RILJ_LOGD) unsljLogRet(response, ret); - - mPDPRegistrants - .notifyRegistrants(new AsyncResult(null, ret, null)); - break; - - case RIL_UNSOL_SUPP_SVC_NOTIFICATION: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mSsnRegistrant != null) { - mSsnRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_SESSION_END: - if (RILJ_LOGD) unsljLog(response); - - if (mStkSessionEndRegistrant != null) { - mStkSessionEndRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_PROACTIVE_COMMAND: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mStkProCmdRegistrant != null) { - mStkProCmdRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_EVENT_NOTIFY: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mStkEventRegistrant != null) { - mStkEventRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_STK_CALL_SETUP: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mStkCallSetUpRegistrant != null) { - mStkCallSetUpRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_SIM_SMS_STORAGE_FULL: - if (RILJ_LOGD) unsljLog(response); - - if (mSimSmsFullRegistrant != null) { - mSimSmsFullRegistrant.notifyRegistrant(); - } - break; - - case RIL_UNSOL_SIM_REFRESH: - if (RILJ_LOGD) unsljLogRet(response, ret); - - if (mSimRefreshRegistrant != null) { - mSimRefreshRegistrant.notifyRegistrant( - new AsyncResult (null, ret, null)); - } - break; - - case RIL_UNSOL_CALL_RING: - if (RILJ_LOGD) unsljLog(response); - - if (mRingRegistrant != null) { - mRingRegistrant.notifyRegistrant(); - } - break; - } - } - - private Object - responseInts(Parcel p) - { - int numInts; - int response[]; - - numInts = p.readInt(); - - response = new int[numInts]; - - for (int i = 0 ; i < numInts ; i++) { - response[i] = p.readInt(); - } - - return response; - } - - - private Object - responseVoid(Parcel p) - { - return null; - } - - private Object - responseCallForward(Parcel p) - { - int numInfos; - CallForwardInfo infos[]; - - numInfos = p.readInt(); - - infos = new CallForwardInfo[numInfos]; - - for (int i = 0 ; i < numInfos ; i++) { - infos[i] = new CallForwardInfo(); - - infos[i].status = p.readInt(); - infos[i].reason = p.readInt(); - infos[i].serviceClass = p.readInt(); - infos[i].toa = p.readInt(); - infos[i].number = p.readString(); - infos[i].timeSeconds = p.readInt(); - } - - return infos; - } - - private Object - responseSuppServiceNotification(Parcel p) - { - SuppServiceNotification notification = new SuppServiceNotification(); - - notification.notificationType = p.readInt(); - notification.code = p.readInt(); - notification.index = p.readInt(); - notification.type = p.readInt(); - notification.number = p.readString(); - - return notification; - } - - private Object - responseString(Parcel p) - { - String response; - - response = p.readString(); - - return response; - } - - private Object - responseStrings(Parcel p) - { - int num; - String response[]; - - response = p.readStringArray(); - - if (false) { - num = p.readInt(); - - response = new String[num]; - for (int i = 0; i < num; i++) { - response[i] = p.readString(); - } - } - - return response; - } - - private Object - responseRaw(Parcel p) - { - int num; - byte response[]; - - response = p.createByteArray(); - - return response; - } - - private Object - responseSMS(Parcel p) - { - int messageRef; - String ackPDU; - - messageRef = p.readInt(); - ackPDU = p.readString(); - - SmsResponse response = new SmsResponse(messageRef, ackPDU); - - return response; - } - - - private Object - responseSIM_IO(Parcel p) - { - int sw1, sw2; - byte data[] = null; - Message ret; - - sw1 = p.readInt(); - sw2 = p.readInt(); - - String s = p.readString(); - - return new SimIoResult(sw1, sw2, s); - } - - private Object - responseSimStatus(Parcel p) - { - int status; - - status = ((int[])responseInts(p))[0]; - switch (status){ - case RIL_SIM_ABSENT: return SimStatus.SIM_ABSENT; - case RIL_SIM_NOT_READY: return SimStatus.SIM_NOT_READY; - case RIL_SIM_READY: return SimStatus.SIM_READY; - case RIL_SIM_PIN: return SimStatus.SIM_PIN; - case RIL_SIM_PUK: return SimStatus.SIM_PUK; - case RIL_SIM_NETWORK_PERSONALIZATION: - return SimStatus.SIM_NETWORK_PERSONALIZATION; - default: - throw new RuntimeException ("Invalid RIL_REQUEST_GET_SIM_STATUS result: " + status); - } - } - - - private Object - responseCallList(Parcel p) - { - int num; - ArrayList<DriverCall> response; - DriverCall dc; - - num = p.readInt(); - response = new ArrayList<DriverCall>(num); - - for (int i = 0 ; i < num ; i++) { - dc = new DriverCall(); - - dc.state = DriverCall.stateFromCLCC(p.readInt()); - dc.index = p.readInt(); - dc.TOA = p.readInt(); - dc.isMpty = (0 != p.readInt()); - dc.isMT = (0 != p.readInt()); - dc.als = p.readInt(); - dc.isVoice = (0 == p.readInt()) ? false : true; - dc.number = p.readString(); - - // Make sure there's a leading + on addresses with a TOA - // of 145 - - dc.number = PhoneNumberUtils.stringFromStringAndTOA( - dc.number, dc.TOA); - - response.add(dc); - } - - Collections.sort(response); - - return response; - } - - private Object - responseContextList(Parcel p) - { - int num; - ArrayList<PDPContextState> response; - - num = p.readInt(); - response = new ArrayList<PDPContextState>(num); - - for (int i = 0; i < num; i++) { - PDPContextState pdp = new PDPContextState(); - - pdp.cid = p.readInt(); - pdp.active = p.readInt() == 0 ? false : true; - pdp.type = p.readString(); - pdp.apn = p.readString(); - pdp.address = p.readString(); - - response.add(pdp); - } - - return response; - } - - private Object - responseNetworkInfos(Parcel p) - { - String strings[] = (String [])responseStrings(p); - ArrayList<NetworkInfo> ret; - - if (strings.length % 4 != 0) { - throw new RuntimeException( - "RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: invalid response. Got " - + strings.length + " strings, expected multible of 4"); - } - - ret = new ArrayList<NetworkInfo>(strings.length / 4); - - for (int i = 0 ; i < strings.length ; i += 4) { - ret.add ( - new NetworkInfo( - strings[i+0], - strings[i+1], - strings[i+2], - strings[i+3])); - } - - return ret; - } - - private Object - responseCellList(Parcel p) - { - int num; - ArrayList<NeighboringCellInfo> response; - NeighboringCellInfo cell; - - num = p.readInt(); - response = new ArrayList<NeighboringCellInfo>(num); - - for (int i = 0 ; i < num ; i++) { - try { - int rssi = p.readInt(); - int cid = Integer.valueOf(p.readString(), 16); - cell = new NeighboringCellInfo(rssi, cid); - response.add(cell); - } catch ( Exception e) { - } - } - - return response; - } - - - static String - requestToString(int request) - { -/* - cat libs/telephony/ril_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' -*/ - switch(request) { - case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS"; - case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN"; - case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK"; - case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2"; - case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2"; - case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN"; - case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2"; - case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION"; - case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS"; - case RIL_REQUEST_DIAL: return "DIAL"; - case RIL_REQUEST_GET_IMSI: return "GET_IMSI"; - case RIL_REQUEST_HANGUP: return "HANGUP"; - case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND"; - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND"; - case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE"; - case RIL_REQUEST_CONFERENCE: return "CONFERENCE"; - case RIL_REQUEST_UDUB: return "UDUB"; - case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE"; - case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH"; - case RIL_REQUEST_REGISTRATION_STATE: return "REGISTRATION_STATE"; - case RIL_REQUEST_GPRS_REGISTRATION_STATE: return "GPRS_REGISTRATION_STATE"; - case RIL_REQUEST_OPERATOR: return "OPERATOR"; - case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER"; - case RIL_REQUEST_DTMF: return "DTMF"; - case RIL_REQUEST_SEND_SMS: return "SEND_SMS"; - case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE"; - case RIL_REQUEST_SETUP_DEFAULT_PDP: return "SETUP_DEFAULT_PDP"; - case RIL_REQUEST_SIM_IO: return "SIM_IO"; - case RIL_REQUEST_SEND_USSD: return "SEND_USSD"; - case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD"; - case RIL_REQUEST_GET_CLIR: return "GET_CLIR"; - case RIL_REQUEST_SET_CLIR: return "SET_CLIR"; - case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS"; - case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD"; - case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING"; - case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING"; - case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE"; - case RIL_REQUEST_GET_IMEI: return "GET_IMEI"; - case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV"; - case RIL_REQUEST_ANSWER: return "ANSWER"; - case RIL_REQUEST_DEACTIVATE_DEFAULT_PDP: return "DEACTIVATE_DEFAULT_PDP"; - case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK"; - case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK"; - case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD"; - case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE"; - case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC"; - case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL"; - case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS : return "QUERY_AVAILABLE_NETWORKS "; - case RIL_REQUEST_DTMF_START: return "DTMF_START"; - case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP"; - case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION"; - case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION"; - case RIL_REQUEST_SET_MUTE: return "SET_MUTE"; - case RIL_REQUEST_GET_MUTE: return "GET_MUTE"; - case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP"; - case RIL_REQUEST_LAST_PDP_FAIL_CAUSE: return "LAST_PDP_FAIL_CAUSE"; - case RIL_REQUEST_PDP_CONTEXT_LIST: return "PDP_CONTEXT_LIST"; - case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO"; - case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW"; - case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS"; - case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE"; - case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION"; - case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM"; - case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM"; - case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE"; - case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE"; - case RIL_REQUEST_STK_GET_PROFILE: return "REQUEST_STK_GET_PROFILE"; - case RIL_REQUEST_STK_SET_PROFILE: return "REQUEST_STK_SET_PROFILE"; - case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "REQUEST_STK_SEND_ENVELOPE_COMMAND"; - case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "REQUEST_STK_SEND_TERMINAL_RESPONSE"; - case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM"; - case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "REQUEST_EXPLICIT_CALL_TRANSFER"; - case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "REQUEST_SET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "REQUEST_GET_PREFERRED_NETWORK_TYPE"; - case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "REQUEST_GET_NEIGHBORING_CELL_IDS"; - case RIL_REQUEST_SET_LOCATION_UPDATES: return "REQUEST_SET_LOCATION_UPDATES"; - default: return "<unknown request>"; - } - } - - static String - responseToString(int request) - { -/* - cat libs/telephony/ril_unsol_commands.h \ - | egrep "^ *{RIL_" \ - | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/' -*/ - switch(request) { - case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED"; - case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS"; - case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT"; - case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM"; - case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD"; - case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST"; - case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED"; - case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH"; - case RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED: return "UNSOL_PDP_CONTEXT_LIST_CHANGED"; - case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION"; - case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END"; - case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND"; - case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY"; - case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP"; - case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL"; - case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH"; - case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING"; - default: return "<unknown reponse>"; - } - } - - private void riljLog(String msg) { - Log.d(LOG_TAG, msg); - } - - private void riljLogv(String msg) { - Log.v(LOG_TAG, msg); - } - - private void unsljLog(int response) { - riljLog("[UNSL]< " + responseToString(response)); - } - - private void unsljLogMore(int response, String more) { - riljLog("[UNSL]< " + responseToString(response) + " " + more); - } - - private void unsljLogRet(int response, Object ret) { - riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret)); - } - - private void unsljLogvRet(int response, Object ret) { - riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret)); - } - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/RILConstants.java b/telephony/java/com/android/internal/telephony/gsm/RILConstants.java deleted file mode 100644 index 0a8e192..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/RILConstants.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2006 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; - - -/** - * {@hide} - */ -interface RILConstants -{ - // From the top of ril.cpp - int RIL_ERRNO_INVALID_RESPONSE = -1; - - // from RIL_Errno - int SUCCESS = 0; - int RADIO_NOT_AVAILABLE = 1; /* If radio did not start or is resetting */ - int GENERIC_FAILURE = 2; - int PASSWORD_INCORRECT = 3; /* for PIN/PIN2 methods only! */ - int SIM_PIN2 = 4; /* Operation requires SIM PIN2 to be entered */ - int SIM_PUK2 = 5; /* Operation requires SIM PIN2 to be entered */ - int REQUEST_NOT_SUPPORTED = 6; - int REQUEST_CANCELLED = 7; - int OP_NOT_ALLOWED_DURING_VOICE_CALL = 8; /* data operation is not allowed during voice call in class C */ - int OP_NOT_ALLOWED_BEFORE_REG_NW = 9; /* request is not allowed before device registers to network */ - int SMS_SEND_FAIL_RETRY = 10; /* send sms fail and need retry */ -/* -cat include/telephony/ril.h | \ - egrep '^#define' | \ - sed -re 's/^#define +([^ ]+)* +([^ ]+)/ int \1 = \2;/' \ - >>java/android/com.android.internal.telephony/gsm/RILConstants.java -*/ - - - int RIL_SIM_ABSENT = 0; - int RIL_SIM_NOT_READY = 1; - int RIL_SIM_READY = 2; - int RIL_SIM_PIN = 3; - int RIL_SIM_PUK = 4; - int RIL_SIM_NETWORK_PERSONALIZATION = 5; - int RIL_REQUEST_GET_SIM_STATUS = 1; - int RIL_REQUEST_ENTER_SIM_PIN = 2; - int RIL_REQUEST_ENTER_SIM_PUK = 3; - int RIL_REQUEST_ENTER_SIM_PIN2 = 4; - int RIL_REQUEST_ENTER_SIM_PUK2 = 5; - int RIL_REQUEST_CHANGE_SIM_PIN = 6; - int RIL_REQUEST_CHANGE_SIM_PIN2 = 7; - int RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION = 8; - int RIL_REQUEST_GET_CURRENT_CALLS = 9; - int RIL_REQUEST_DIAL = 10; - int RIL_REQUEST_GET_IMSI = 11; - int RIL_REQUEST_HANGUP = 12; - int RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND = 13; - int RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND = 14; - int RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE = 15; - int RIL_REQUEST_CONFERENCE = 16; - int RIL_REQUEST_UDUB = 17; - int RIL_REQUEST_LAST_CALL_FAIL_CAUSE = 18; - int RIL_REQUEST_SIGNAL_STRENGTH = 19; - int RIL_REQUEST_REGISTRATION_STATE = 20; - int RIL_REQUEST_GPRS_REGISTRATION_STATE = 21; - int RIL_REQUEST_OPERATOR = 22; - int RIL_REQUEST_RADIO_POWER = 23; - int RIL_REQUEST_DTMF = 24; - int RIL_REQUEST_SEND_SMS = 25; - int RIL_REQUEST_SEND_SMS_EXPECT_MORE = 26; - int RIL_REQUEST_SETUP_DEFAULT_PDP = 27; - int RIL_REQUEST_SIM_IO = 28; - int RIL_REQUEST_SEND_USSD = 29; - int RIL_REQUEST_CANCEL_USSD = 30; - int RIL_REQUEST_GET_CLIR = 31; - int RIL_REQUEST_SET_CLIR = 32; - int RIL_REQUEST_QUERY_CALL_FORWARD_STATUS = 33; - int RIL_REQUEST_SET_CALL_FORWARD = 34; - int RIL_REQUEST_QUERY_CALL_WAITING = 35; - int RIL_REQUEST_SET_CALL_WAITING = 36; - int RIL_REQUEST_SMS_ACKNOWLEDGE = 37; - int RIL_REQUEST_GET_IMEI = 38; - int RIL_REQUEST_GET_IMEISV = 39; - int RIL_REQUEST_ANSWER = 40; - int RIL_REQUEST_DEACTIVATE_DEFAULT_PDP = 41; - int RIL_REQUEST_QUERY_FACILITY_LOCK = 42; - int RIL_REQUEST_SET_FACILITY_LOCK = 43; - int RIL_REQUEST_CHANGE_BARRING_PASSWORD = 44; - int RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE = 45; - int RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC = 46; - int RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL = 47; - int RIL_REQUEST_QUERY_AVAILABLE_NETWORKS = 48; - int RIL_REQUEST_DTMF_START = 49; - int RIL_REQUEST_DTMF_STOP = 50; - int RIL_REQUEST_BASEBAND_VERSION = 51; - int RIL_REQUEST_SEPARATE_CONNECTION = 52; - int RIL_REQUEST_SET_MUTE = 53; - int RIL_REQUEST_GET_MUTE = 54; - int RIL_REQUEST_QUERY_CLIP = 55; - int RIL_REQUEST_LAST_PDP_FAIL_CAUSE = 56; - int RIL_REQUEST_PDP_CONTEXT_LIST = 57; - int RIL_REQUEST_RESET_RADIO = 58; - int RIL_REQUEST_OEM_HOOK_RAW = 59; - int RIL_REQUEST_OEM_HOOK_STRINGS = 60; - int RIL_REQUEST_SCREEN_STATE = 61; - int RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION = 62; - int RIL_REQUEST_WRITE_SMS_TO_SIM = 63; - int RIL_REQUEST_DELETE_SMS_ON_SIM = 64; - int RIL_REQUEST_SET_BAND_MODE = 65; - int RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE = 66; - int RIL_REQUEST_STK_GET_PROFILE = 67; - int RIL_REQUEST_STK_SET_PROFILE = 68; - int RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND = 69; - int RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE = 70; - int RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM = 71; - int RIL_REQUEST_EXPLICIT_CALL_TRANSFER = 72; - int RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE = 73; - int RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE = 74; - int RIL_REQUEST_GET_NEIGHBORING_CELL_IDS = 75; - int RIL_REQUEST_SET_LOCATION_UPDATES = 76; - int RIL_UNSOL_RESPONSE_BASE = 1000; - int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000; - int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001; - int RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED = 1002; - int RIL_UNSOL_RESPONSE_NEW_SMS = 1003; - int RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004; - int RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005; - int RIL_UNSOL_ON_USSD = 1006; - int RIL_UNSOL_ON_USSD_REQUEST = 1007; - int RIL_UNSOL_NITZ_TIME_RECEIVED = 1008; - int RIL_UNSOL_SIGNAL_STRENGTH = 1009; - int RIL_UNSOL_PDP_CONTEXT_LIST_CHANGED = 1010; - int RIL_UNSOL_SUPP_SVC_NOTIFICATION = 1011; - int RIL_UNSOL_STK_SESSION_END = 1012; - int RIL_UNSOL_STK_PROACTIVE_COMMAND = 1013; - int RIL_UNSOL_STK_EVENT_NOTIFY = 1014; - int RIL_UNSOL_STK_CALL_SETUP = 1015; - int RIL_UNSOL_SIM_SMS_STORAGE_FULL = 1016; - int RIL_UNSOL_SIM_REFRESH = 1017; - int RIL_UNSOL_CALL_RING = 1018; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java b/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java deleted file mode 100644 index 81fc657..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SIMFileHandler.java +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.telephony.*; -import com.android.internal.telephony.gsm.stk.ImageDescriptor; -import android.os.*; -import android.os.AsyncResult; -import android.os.RegistrantList; -import android.os.Registrant; -import android.util.Log; -import java.util.ArrayList; - -/** - * {@hide} - */ -public final class SIMFileHandler extends Handler -{ - static final String LOG_TAG = "GSM"; - - //from TS 11.11 9.1 or elsewhere - static private final int COMMAND_READ_BINARY = 0xb0; - static private final int COMMAND_UPDATE_BINARY = 0xd6; - static private final int COMMAND_READ_RECORD = 0xb2; - static private final int COMMAND_UPDATE_RECORD = 0xdc; - static private final int COMMAND_SEEK = 0xa2; - static private final int COMMAND_GET_RESPONSE = 0xc0; - - // from TS 11.11 9.2.5 - static private final int READ_RECORD_MODE_ABSOLUTE = 4; - - //***** types of files TS 11.11 9.3 - static private final int EF_TYPE_TRANSPARENT = 0; - static private final int EF_TYPE_LINEAR_FIXED = 1; - static private final int EF_TYPE_CYCLIC = 3; - - //***** types of files TS 11.11 9.3 - static private final int TYPE_RFU = 0; - static private final int TYPE_MF = 1; - static private final int TYPE_DF = 2; - static private final int TYPE_EF = 4; - - // size of GET_RESPONSE for EF - static private final int GET_RESPONSE_EF_SIZE_BYTES = 15; - - // Byte order received in response to COMMAND_GET_RESPONSE - // Refer TS 51.011 Section 9.2.1 - static private final int RESPONSE_DATA_RFU_1 = 0; - static private final int RESPONSE_DATA_RFU_2 = 1; - - static private final int RESPONSE_DATA_FILE_SIZE_1 = 2; - static private final int RESPONSE_DATA_FILE_SIZE_2 = 3; - - static private final int RESPONSE_DATA_FILE_ID_1 = 4; - static private final int RESPONSE_DATA_FILE_ID_2 = 5; - static private final int RESPONSE_DATA_FILE_TYPE = 6; - static private final int RESPONSE_DATA_RFU_3 = 7; - static private final int RESPONSE_DATA_ACCESS_CONDITION_1 = 8; - static private final int RESPONSE_DATA_ACCESS_CONDITION_2 = 9; - static private final int RESPONSE_DATA_ACCESS_CONDITION_3 = 10; - static private final int RESPONSE_DATA_FILE_STATUS = 11; - static private final int RESPONSE_DATA_LENGTH = 12; - static private final int RESPONSE_DATA_STRUCTURE = 13; - static private final int RESPONSE_DATA_RECORD_LENGTH = 14; - - - //***** Instance Variables - GSMPhone phone; - - //***** Events - - /** Finished retrieving size of transparent EF; start loading. */ - static private final int EVENT_GET_BINARY_SIZE_DONE = 4; - /** Finished loading contents of transparent EF; post result. */ - static private final int EVENT_READ_BINARY_DONE = 5; - /** Finished retrieving size of records for linear-fixed EF; now load. */ - static private final int EVENT_GET_RECORD_SIZE_DONE = 6; - /** Finished loading single record from a linear-fixed EF; post result. */ - static private final int EVENT_READ_RECORD_DONE = 7; - /** Finished retrieving record size; post result. */ - static private final int EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE = 8; - /** Finished retrieving image instance record; post result. */ - static private final int EVENT_READ_IMG_DONE = 9; - /** Finished retrieving icon data; post result. */ - static private final int EVENT_READ_ICON_DONE = 10; - - //***** Inner Classes - - static class LoadLinearFixedContext - { - - int efid; - int recordNum, recordSize, countRecords; - boolean loadAll; - - Message onLoaded; - - ArrayList<byte[]> results; - - LoadLinearFixedContext(int efid, int recordNum, Message onLoaded) - { - this.efid = efid; - this.recordNum = recordNum; - this.onLoaded = onLoaded; - this.loadAll = false; - } - - LoadLinearFixedContext(int efid, Message onLoaded) - { - this.efid = efid; - this.recordNum = 1; - this.loadAll = true; - this.onLoaded = onLoaded; - } - - } - - - //***** Constructor - - SIMFileHandler(GSMPhone phone) - { - this.phone = phone; - } - - //***** Public Methods - - /** - * Load a record from a SIM Linear Fixed EF - * - * @param fileid EF id - * @param recordNum 1-based (not 0-based) record number - * @param onLoaded - * - * ((AsyncResult)(onLoaded.obj)).result is the byte[] - * - */ - void loadEFLinearFixed(int fileid, int recordNum, Message onLoaded) - { - Message response - = obtainMessage(EVENT_GET_RECORD_SIZE_DONE, - new LoadLinearFixedContext(fileid, recordNum, onLoaded)); - - phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null, - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response); - } - - /** - * Load a image instance record from a SIM Linear Fixed EF-IMG - * - * @param recordNum 1-based (not 0-based) record number - * @param onLoaded - * - * ((AsyncResult)(onLoaded.obj)).result is the byte[] - * - */ - public void loadEFImgLinearFixed(int recordNum, Message onLoaded) { - Message response = obtainMessage(EVENT_READ_IMG_DONE, - new LoadLinearFixedContext(SimConstants.EF_IMG, recordNum, - onLoaded)); - - phone.mCM.simIO(COMMAND_GET_RESPONSE, SimConstants.EF_IMG, "img", - recordNum, READ_RECORD_MODE_ABSOLUTE, - ImageDescriptor.ID_LENGTH, null, null, response); - } - - /** - * get record size for a linear fixed EF - * - * @param fileid EF id - * @param onLoaded ((AsnyncResult)(onLoaded.obj)).result is the recordSize[] - * int[0] is the record length int[1] is the total length of the EF - * file int[3] is the number of records in the EF file So int[0] * - * int[3] = int[1] - */ - void getEFLinearRecordSize(int fileid, Message onLoaded) - { - Message response - = obtainMessage(EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE, - new LoadLinearFixedContext(fileid, onLoaded)); - phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null, - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response); - } - - /** - * Load all records from a SIM Linear Fixed EF - * - * @param fileid EF id - * @param onLoaded - * - * ((AsyncResult)(onLoaded.obj)).result is an ArrayList<byte[]> - * - */ - void loadEFLinearFixedAll(int fileid, Message onLoaded) - { - Message response = obtainMessage(EVENT_GET_RECORD_SIZE_DONE, - new LoadLinearFixedContext(fileid,onLoaded)); - - phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null, - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response); - } - - /** - * Load a SIM Transparent EF - * - * @param fileid EF id - * @param onLoaded - * - * ((AsyncResult)(onLoaded.obj)).result is the byte[] - * - */ - - void loadEFTransparent(int fileid, Message onLoaded) - { - Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE, - fileid, 0, onLoaded); - - phone.mCM.simIO(COMMAND_GET_RESPONSE, fileid, null, - 0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, response); - } - - /** - * Load a SIM Transparent EF-IMG. Used right after loadEFImgLinearFixed to - * retrive STK's icon data. - * - * @param fileid EF id - * @param onLoaded - * - * ((AsyncResult)(onLoaded.obj)).result is the byte[] - * - */ - public void loadEFImgTransparent(int fileid, int highOffset, int lowOffset, - int length, Message onLoaded) { - Message response = obtainMessage(EVENT_READ_ICON_DONE, fileid, 0, - onLoaded); - - phone.mCM.simIO(COMMAND_READ_BINARY, fileid, "img", highOffset, lowOffset, - length, null, null, response); - } - - /** - * Update a record in a linear fixed EF - * @param fileid EF id - * @param recordNum 1-based (not 0-based) record number - * @param data must be exactly as long as the record in the EF - * @param pin2 for CHV2 operations, otherwist must be null - * @param onComplete onComplete.obj will be an AsyncResult - * onComplete.obj.userObj will be a SimIoResult on success - */ - void updateEFLinearFixed(int fileid, int recordNum, byte[] data, - String pin2, Message onComplete) - { - phone.mCM.simIO(COMMAND_UPDATE_RECORD, fileid, null, - recordNum, READ_RECORD_MODE_ABSOLUTE, data.length, - SimUtils.bytesToHexString(data), pin2, onComplete); - } - - /** - * Update a transparent EF - * @param fileid EF id - * @param data must be exactly as long as the EF - */ - void updateEFTransparent(int fileid, byte[] data, Message onComplete) - { - phone.mCM.simIO(COMMAND_UPDATE_BINARY, fileid, null, - 0, 0, data.length, - SimUtils.bytesToHexString(data), null, onComplete); - } - - //***** Overridden from Handler - - public void handleMessage(Message msg) - { - AsyncResult ar; - SimIoResult result; - Message response = null; - String str; - LoadLinearFixedContext lc; - - SimException simException; - byte data[]; - int size; - int fileid; - int recordNum; - int recordSize[]; - - try { - switch (msg.what) { - case EVENT_READ_IMG_DONE: - ar = (AsyncResult) msg.obj; - lc = (LoadLinearFixedContext) ar.userObj; - result = (SimIoResult) ar.result; - response = lc.onLoaded; - - simException = result.getException(); - if (simException != null) { - sendResult(response, result.payload, ar.exception); - } - break; - case EVENT_READ_ICON_DONE: - ar = (AsyncResult) msg.obj; - response = (Message) ar.userObj; - result = (SimIoResult) ar.result; - - simException = result.getException(); - if (simException != null) { - sendResult(response, result.payload, ar.exception); - } - break; - case EVENT_GET_EF_LINEAR_RECORD_SIZE_DONE: - ar = (AsyncResult)msg.obj; - lc = (LoadLinearFixedContext) ar.userObj; - result = (SimIoResult) ar.result; - response = lc.onLoaded; - - if (ar.exception != null) { - sendResult(response, null, ar.exception); - break; - } - - simException = result.getException(); - if (simException != null) { - sendResult(response, null, simException); - break; - } - - data = result.payload; - - if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE] || - EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) { - throw new SimFileTypeMismatch(); - } - - recordSize = new int[3]; - recordSize[0] = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; - recordSize[1] = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) - + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); - recordSize[2] = recordSize[1] / recordSize[0]; - - sendResult(response, recordSize, null); - break; - case EVENT_GET_RECORD_SIZE_DONE: - ar = (AsyncResult)msg.obj; - lc = (LoadLinearFixedContext) ar.userObj; - result = (SimIoResult) ar.result; - response = lc.onLoaded; - - if (ar.exception != null) { - sendResult(response, null, ar.exception); - break; - } - - simException = result.getException(); - - if (simException != null) { - sendResult(response, null, simException); - break; - } - - data = result.payload; - fileid = lc.efid; - recordNum = lc.recordNum; - - if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) { - throw new SimFileTypeMismatch(); - } - - if (EF_TYPE_LINEAR_FIXED != data[RESPONSE_DATA_STRUCTURE]) { - throw new SimFileTypeMismatch(); - } - - lc.recordSize = data[RESPONSE_DATA_RECORD_LENGTH] & 0xFF; - - size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) - + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); - - lc.countRecords = size / lc.recordSize; - - if (lc.loadAll) { - lc.results = new ArrayList<byte[]>(lc.countRecords); - } - - phone.mCM.simIO(COMMAND_READ_RECORD, lc.efid, null, - lc.recordNum, - READ_RECORD_MODE_ABSOLUTE, - lc.recordSize, null, null, - obtainMessage(EVENT_READ_RECORD_DONE, lc)); - break; - case EVENT_GET_BINARY_SIZE_DONE: - ar = (AsyncResult)msg.obj; - response = (Message) ar.userObj; - result = (SimIoResult) ar.result; - - if (ar.exception != null) { - sendResult(response, null, ar.exception); - break; - } - - simException = result.getException(); - - if (simException != null) { - sendResult(response, null, simException); - break; - } - - data = result.payload; - - fileid = msg.arg1; - - if (TYPE_EF != data[RESPONSE_DATA_FILE_TYPE]) { - throw new SimFileTypeMismatch(); - } - - if (EF_TYPE_TRANSPARENT != data[RESPONSE_DATA_STRUCTURE]) { - throw new SimFileTypeMismatch(); - } - - size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8) - + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff); - - phone.mCM.simIO(COMMAND_READ_BINARY, fileid, null, - 0, 0, size, null, null, - obtainMessage(EVENT_READ_BINARY_DONE, - fileid, 0, response)); - break; - - case EVENT_READ_RECORD_DONE: - - ar = (AsyncResult)msg.obj; - lc = (LoadLinearFixedContext) ar.userObj; - result = (SimIoResult) ar.result; - response = lc.onLoaded; - - if (ar.exception != null) { - sendResult(response, null, ar.exception); - break; - } - - simException = result.getException(); - - if (simException != null) { - sendResult(response, null, simException); - break; - } - - if (!lc.loadAll) { - sendResult(response, result.payload, null); - } else { - lc.results.add(result.payload); - - lc.recordNum++; - - if (lc.recordNum > lc.countRecords) { - sendResult(response, lc.results, null); - } else { - phone.mCM.simIO(COMMAND_READ_RECORD, lc.efid, null, - lc.recordNum, - READ_RECORD_MODE_ABSOLUTE, - lc.recordSize, null, null, - obtainMessage(EVENT_READ_RECORD_DONE, lc)); - } - } - - break; - - case EVENT_READ_BINARY_DONE: - ar = (AsyncResult)msg.obj; - response = (Message) ar.userObj; - result = (SimIoResult) ar.result; - - if (ar.exception != null) { - sendResult(response, null, ar.exception); - break; - } - - simException = result.getException(); - - if (simException != null) { - sendResult(response, null, simException); - break; - } - - sendResult(response, result.payload, null); - break; - - }} catch (Exception exc) { - if (response != null) { - sendResult(response, null, exc); - } else { - Log.e(LOG_TAG, "uncaught exception", exc); - } - } - } - - //***** Private Methods - - private void sendResult(Message response, Object result, Throwable ex) - { - if (response == null) { - return; - } - - AsyncResult.forMessage(response, result, ex); - - response.sendToTarget(); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java deleted file mode 100644 index 22bd6e2..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java +++ /dev/null @@ -1,1582 +0,0 @@ -/* - * Copyright (C) 2006 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.app.AlarmManager; -import android.content.Context; -import android.os.AsyncResult; -import android.os.RegistrantList; -import android.os.Registrant; -import android.os.Handler; -import android.os.Message; -import android.os.SystemProperties; -import android.telephony.gsm.SmsMessage; -import android.util.Log; -import java.util.ArrayList; -import android.app.ActivityManagerNative; -import android.app.IActivityManager; -import java.util.Locale; -import android.content.res.Configuration; - -import static com.android.internal.telephony.TelephonyProperties.*; -import com.android.internal.telephony.SimCard; - -/** - * {@hide} - */ -public final class SIMRecords extends Handler implements SimConstants -{ - static final String LOG_TAG = "GSM"; - - private static final boolean CRASH_RIL = false; - - private static final boolean DBG = true; - - //***** Instance Variables - - GSMPhone phone; - RegistrantList recordsLoadedRegistrants = new RegistrantList(); - - int recordsToLoad; // number of pending load requests - - AdnRecordCache adnCache; - - VoiceMailConstants mVmConfig; - - //***** Cached SIM State; cleared on channel close - - boolean recordsRequested = false; // true if we've made requests for the sim records - - String imsi; - String iccid; - String msisdn = null; // My mobile number - String msisdnTag = null; - String voiceMailNum = null; - String voiceMailTag = null; - String newVoiceMailNum = null; - String newVoiceMailTag = null; - boolean isVoiceMailFixed = false; - int countVoiceMessages = 0; - boolean callForwardingEnabled; - int mncLength = 0; // 0 is used to indicate that the value - // is not initialized - int mailboxIndex = 0; // 0 is no mailbox dailing number associated - - /** - * Sates only used by getSpnFsm FSM - */ - private Get_Spn_Fsm_State spnState; - - /** CPHS service information (See CPHS 4.2 B.3.1.1) - * It will be set in onSimReady if reading GET_CPHS_INFO successfully - * mCphsInfo[0] is CPHS Phase - * mCphsInfo[1] and mCphsInfo[2] is CPHS Service Table - */ - private byte[] mCphsInfo = null; - - byte[] efMWIS = null; - byte[] efCPHS_MWI =null; - byte[] mEfCff = null; - byte[] mEfCfis = null; - - - String spn; - int spnDisplayCondition; - // Numeric network codes listed in TS 51.011 EF[SPDI] - ArrayList<String> spdiNetworks = null; - - String pnnHomeName = null; - - //***** Constants - - // Bitmasks for SPN display rules. - static final int SPN_RULE_SHOW_SPN = 0x01; - static final int SPN_RULE_SHOW_PLMN = 0x02; - - // From TS 51.011 EF[SPDI] section - static final int TAG_SPDI_PLMN_LIST = 0x80; - - // Full Name IEI from TS 24.008 - static final int TAG_FULL_NETWORK_NAME = 0x43; - - // Short Name IEI from TS 24.008 - static final int TAG_SHORT_NETWORK_NAME = 0x45; - - // active CFF from CPHS 4.2 B.4.5 - static final int CFF_UNCONDITIONAL_ACTIVE = 0x0a; - static final int CFF_UNCONDITIONAL_DEACTIVE = 0x05; - static final int CFF_LINE1_MASK = 0x0f; - static final int CFF_LINE1_RESET = 0xf0; - - // CPHS Service Table (See CPHS 4.2 B.3.1) - private static final int CPHS_SST_MBN_MASK = 0x30; - private static final int CPHS_SST_MBN_ENABLED = 0x30; - - //***** Event Constants - - private static final int EVENT_SIM_READY = 1; - private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2; - private static final int EVENT_GET_IMSI_DONE = 3; - private static final int EVENT_GET_ICCID_DONE = 4; - private static final int EVENT_GET_MBI_DONE = 5; - private static final int EVENT_GET_MBDN_DONE = 6; - private static final int EVENT_GET_MWIS_DONE = 7; - private static final int EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE = 8; - private static final int EVENT_GET_AD_DONE = 9; // Admin data on SIM - private static final int EVENT_GET_MSISDN_DONE = 10; - private static final int EVENT_GET_CPHS_MAILBOX_DONE = 11; - private static final int EVENT_GET_SPN_DONE = 12; - private static final int EVENT_GET_SPDI_DONE = 13; - private static final int EVENT_UPDATE_DONE = 14; - private static final int EVENT_GET_PNN_DONE = 15; - private static final int EVENT_GET_SST_DONE = 17; - private static final int EVENT_GET_ALL_SMS_DONE = 18; - private static final int EVENT_MARK_SMS_READ_DONE = 19; - private static final int EVENT_SET_MBDN_DONE = 20; - private static final int EVENT_SMS_ON_SIM = 21; - private static final int EVENT_GET_SMS_DONE = 22; - private static final int EVENT_GET_CFF_DONE = 24; - private static final int EVENT_SET_CPHS_MAILBOX_DONE = 25; - private static final int EVENT_GET_INFO_CPHS_DONE = 26; - private static final int EVENT_SET_MSISDN_DONE = 30; - private static final int EVENT_SIM_REFRESH = 31; - private static final int EVENT_GET_CFIS_DONE = 32; - - private static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; - - //***** Constructor - - SIMRecords(GSMPhone phone) - { - this.phone = phone; - - adnCache = new AdnRecordCache(phone); - - mVmConfig = new VoiceMailConstants(); - - recordsRequested = false; // No load request is made till SIM ready - - // recordsToLoad is set to 0 because no requests are made yet - recordsToLoad = 0; - - - phone.mCM.registerForSIMReady(this, EVENT_SIM_READY, null); - phone.mCM.registerForOffOrNotAvailable( - this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); - phone.mCM.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null); - phone.mCM.setOnSimRefresh(this, EVENT_SIM_REFRESH, null); - - // Start off by setting empty state - onRadioOffOrNotAvailable(); - - } - - AdnRecordCache getAdnCache() { - return adnCache; - } - - private void onRadioOffOrNotAvailable() - { - imsi = null; - msisdn = null; - voiceMailNum = null; - countVoiceMessages = 0; - mncLength = 0; - iccid = null; - spn = null; - // -1 means no EF_SPN found; treat accordingly. - spnDisplayCondition = -1; - efMWIS = null; - efCPHS_MWI = null; - spn = null; - spdiNetworks = null; - pnnHomeName = null; - - adnCache.reset(); - - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_NUMERIC, null); - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, null); - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ISO_COUNTRY, null); - - // recordsRequested is set to false indicating that the SIM - // read requests made so far are not valid. This is set to - // true only when fresh set of read requests are made. - recordsRequested = false; - } - - - //***** Public Methods - public void registerForRecordsLoaded(Handler h, int what, Object obj) - { - Registrant r = new Registrant(h, what, obj); - recordsLoadedRegistrants.add(r); - - if (recordsToLoad == 0 && recordsRequested == true) { - r.notifyRegistrant(new AsyncResult(null, null, null)); - } - } - - /** Returns null if SIM is not yet ready */ - public String getIMSI() - { - return imsi; - } - - public String getMsisdnNumber() - { - return msisdn; - } - - /** - * Set subscriber number to SIM record - * - * The subscriber number is stored in EF_MSISDN (TS 51.011) - * - * When the operation is complete, onComplete will be sent to its handler - * - * @param alphaTag alpha-tagging of the dailing nubmer (up to 10 characters) - * @param number dailing nubmer (up to 20 digits) - * if the number starts with '+', then set to international TOA - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void setMsisdnNumber(String alphaTag, String number, - Message onComplete) { - - msisdn = number; - msisdnTag = alphaTag; - - if(DBG) log("Set MSISDN: " + msisdnTag +" " + msisdn); - - - AdnRecord adn = new AdnRecord(msisdnTag, msisdn); - - new AdnRecordLoader(phone).updateEF(adn, EF_MSISDN, EF_EXT1, 1, null, - obtainMessage(EVENT_SET_MSISDN_DONE, onComplete)); - } - - public String getMsisdnAlphaTag() { - return msisdnTag; - } - - public String getVoiceMailNumber() - { - return voiceMailNum; - } - - /** - * Return Service Provider Name stored in SIM - * @return null if SIM is not yet ready - */ - public String getServiceProvideName() - { - return spn; - } - - /** - * Set voice mail number to SIM record - * - * The voice mail number can be stored either in EF_MBDN (TS 51.011) or - * EF_MAILBOX_CPHS (CPHS 4.2) - * - * If EF_MBDN is available, store the voice mail number to EF_MBDN - * - * If EF_MAILBOX_CPHS is enabled, store the voice mail number to EF_CHPS - * - * So the voice mail number will be stored in both EFs if both are available - * - * Return error only if both EF_MBDN and EF_MAILBOX_CPHS fail. - * - * When the operation is complete, onComplete will be sent to its handler - * - * @param alphaTag alpha-tagging of the dailing nubmer (upto 10 characters) - * @param voiceNumber dailing nubmer (upto 20 digits) - * if the number is start with '+', then set to international TOA - * @param onComplete - * onComplete.obj will be an AsyncResult - * ((AsyncResult)onComplete.obj).exception == null on success - * ((AsyncResult)onComplete.obj).exception != null on fail - */ - public void setVoiceMailNumber(String alphaTag, String voiceNumber, - Message onComplete) { - if (isVoiceMailFixed) { - AsyncResult.forMessage((onComplete)).exception = - new SimVmFixedException("Voicemail number is fixed by operator"); - onComplete.sendToTarget(); - return; - } - - newVoiceMailNum = voiceNumber; - newVoiceMailTag = alphaTag; - - AdnRecord adn = new AdnRecord(newVoiceMailTag, newVoiceMailNum); - - if (mailboxIndex != 0 && mailboxIndex != 0xff) { - - new AdnRecordLoader(phone).updateEF(adn, EF_MBDN, EF_EXT6, - mailboxIndex, null, - obtainMessage(EVENT_SET_MBDN_DONE, onComplete)); - - } else if (isCphsMailboxEnabled()) { - - new AdnRecordLoader(phone).updateEF(adn, EF_MAILBOX_CPHS, - EF_EXT1, 1, null, - obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, onComplete)); - - }else { - AsyncResult.forMessage((onComplete)).exception = - new SimVmNotSupportedException("Update SIM voice mailbox error"); - onComplete.sendToTarget(); - } - } - - public String getVoiceMailAlphaTag() - { - return voiceMailTag; - } - - /** - * Sets the SIM voice message waiting indicator records - * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported - * @param countWaiting The number of messages waiting, if known. Use - * -1 to indicate that an unknown number of - * messages are waiting - */ - public void - setVoiceMessageWaiting(int line, int countWaiting) - { - if (line != 1) { - // only profile 1 is supported - return; - } - - // range check - if (countWaiting < 0) { - countWaiting = -1; - } else if (countWaiting > 0xff) { - // TS 23.040 9.2.3.24.2 - // "The value 255 shall be taken to mean 255 or greater" - countWaiting = 0xff; - } - - countVoiceMessages = countWaiting; - - phone.notifyMessageWaitingIndicator(); - - try { - if (efMWIS != null) { - // TS 51.011 10.3.45 - - // lsb of byte 0 is 'voicemail' status - efMWIS[0] = (byte)((efMWIS[0] & 0xfe) - | (countVoiceMessages == 0 ? 0 : 1)); - - // byte 1 is the number of voice messages waiting - if (countWaiting < 0) { - // The spec does not define what this should be - // if we don't know the count - efMWIS[1] = 0; - } else { - efMWIS[1] = (byte) countWaiting; - } - - phone.mSIMFileHandler.updateEFLinearFixed( - EF_MWIS, 1, efMWIS, null, - obtainMessage (EVENT_UPDATE_DONE, EF_MWIS)); - } - - if (efCPHS_MWI != null) { - // Refer CPHS4_2.WW6 B4.2.3 - efCPHS_MWI[0] = (byte)((efCPHS_MWI[0] & 0xf0) - | (countVoiceMessages == 0 ? 0x5 : 0xa)); - - phone.mSIMFileHandler.updateEFTransparent( - EF_VOICE_MAIL_INDICATOR_CPHS, efCPHS_MWI, - obtainMessage (EVENT_UPDATE_DONE, EF_VOICE_MAIL_INDICATOR_CPHS)); - } - } catch (ArrayIndexOutOfBoundsException ex) { - Log.w(LOG_TAG, - "Error saving voice mail state to SIM. Probably malformed SIM record", ex); - } - } - - /** @return true if there are messages waiting, false otherwise. */ - public boolean getVoiceMessageWaiting() - { - return countVoiceMessages != 0; - } - - /** - * Returns number of voice messages waiting, if available - * If not available (eg, on an older CPHS SIM) -1 is returned if - * getVoiceMessageWaiting() is true - */ - public int getCountVoiceMessages() - { - return countVoiceMessages; - } - - public boolean getVoiceCallForwardingFlag() { - return callForwardingEnabled; - } - - public void setVoiceCallForwardingFlag(int line, boolean enable) { - - if (line != 1) return; // only line 1 is supported - - callForwardingEnabled = enable; - - phone.notifyCallForwardingIndicator(); - - try { - if (mEfCfis != null) { - // lsb is of byte 1 is voice status - if (enable) { - mEfCfis[1] |= 1; - } else { - mEfCfis[1] &= 0xfe; - } - - // TODO: Should really update other fields in EF_CFIS, eg, - // dialing number. We don't read or use it right now. - - phone.mSIMFileHandler.updateEFLinearFixed( - EF_CFIS, 1, mEfCfis, null, - obtainMessage (EVENT_UPDATE_DONE, EF_CFIS)); - } - - if (mEfCff != null) { - if (enable) { - mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET) - | CFF_UNCONDITIONAL_ACTIVE); - } else { - mEfCff[0] = (byte) ((mEfCff[0] & CFF_LINE1_RESET) - | CFF_UNCONDITIONAL_DEACTIVE); - } - - phone.mSIMFileHandler.updateEFTransparent( - EF_CFF_CPHS, mEfCff, - obtainMessage (EVENT_UPDATE_DONE, EF_CFF_CPHS)); - } - } catch (ArrayIndexOutOfBoundsException ex) { - Log.w(LOG_TAG, - "Error saving call fowarding flag to SIM. " - + "Probably malformed SIM record", ex); - - } - } - - /** - * Called by STK Service when REFRESH is received. - * @param fileChanged indicates whether any files changed - * @param fileList if non-null, a list of EF files that changed - */ - public void onRefresh(boolean fileChanged, int[] fileList) { - if (fileChanged) { - // A future optimization would be to inspect fileList and - // only reload those files that we care about. For now, - // just re-fetch all SIM records that we cache. - fetchSimRecords(); - } - } - - /** Returns the 5 or 6 digit MCC/MNC of the operator that - * provided the SIM card. Returns null of SIM is not yet ready - */ - String getSIMOperatorNumeric() - { - if (imsi == null) { - return null; - } - - if (mncLength != 0) { - // Length = length of MCC + length of MNC - // length of mcc = 3 (TS 23.003 Section 2.2) - return imsi.substring(0, 3 + mncLength); - } - - // Guess the MNC length based on the MCC if we don't - // have a valid value in ef[ad] - - int mcc; - - mcc = Integer.parseInt(imsi.substring(0,3)); - - return imsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc)); - } - - boolean getRecordsLoaded() - { - if (recordsToLoad == 0 && recordsRequested == true) { - return true; - } else { - return false; - } - } - - /** - * If the timezone is not already set, set it based on the MCC of the SIM. - * @param mcc Mobile Country Code of the SIM - */ - private void setTimezoneFromMccIfNeeded(int mcc) { - String timezone = SystemProperties.get(TIMEZONE_PROPERTY); - if (timezone == null || timezone.length() == 0) { - String zoneId = MccTable.defaultTimeZoneForMcc(mcc); - - if (zoneId != null && zoneId.length() > 0) { - // Set time zone based on MCC - AlarmManager alarm = - (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); - alarm.setTimeZone(zoneId); - } - } - } - - /** - * If the locale is not already set, set it based on the MCC of the SIM. - * @param mcc Mobile Country Code of the SIM - */ - private void setLocaleFromMccIfNeeded(int mcc) { - String language = SystemProperties.get("persist.sys.language"); - String country = SystemProperties.get("persist.sys.country"); - Log.d(LOG_TAG,"setLocaleFromMcc"); - if((language == null || language.length() == 0) && (country == null || country.length() == 0)) { - try { - language = MccTable.defaultLanguageForMcc(mcc); - country = MccTable.countryCodeForMcc(mcc).toUpperCase(); - // try to find a good match - String[] locales = phone.getContext().getAssets().getLocales(); - final int N = locales.length; - String bestMatch = null; - for(int i = 0; i < N; i++) { - Log.d(LOG_TAG," trying "+locales[i]); - if(locales[i]!=null && locales[i].length() >= 2 && - locales[i].substring(0,2).equals(language)) { - if(locales[i].length() >= 5 && - locales[i].substring(3,5).equals(country)) { - bestMatch = locales[i]; - break; - } else if(bestMatch == null) { - bestMatch = locales[i]; - } - } - } - Log.d(LOG_TAG," got bestmatch = "+bestMatch); - if(bestMatch != null) { - IActivityManager am = ActivityManagerNative.getDefault(); - Configuration config = am.getConfiguration(); - - if(bestMatch.length() >= 5) { - config.locale = new Locale(bestMatch.substring(0,2), - bestMatch.substring(3,5)); - } else { - config.locale = new Locale(bestMatch.substring(0,2)); - } - config.userSetLocale = true; - am.updateConfiguration(config); - } - } catch (Exception e) { - // Intentionally left blank - } - } - } - - //***** Overridden from Handler - public void handleMessage(Message msg) - { - AsyncResult ar; - AdnRecord adn; - - byte data[]; - - boolean isRecordLoadResponse = false; - - try { switch (msg.what) { - case EVENT_SIM_READY: - onSimReady(); - break; - - case EVENT_RADIO_OFF_OR_NOT_AVAILABLE: - onRadioOffOrNotAvailable(); - break; - - /* IO events */ - case EVENT_GET_IMSI_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - Log.e(LOG_TAG, "Exception querying IMSI, Exception:" + ar.exception); - break; - } - - imsi = (String) ar.result; - - // IMSI (MCC+MNC+MSIN) is at least 6 digits, but not more - // than 15 (and usually 15). - if (imsi != null && (imsi.length() < 6 || imsi.length() > 15)) { - Log.e(LOG_TAG, "invalid IMSI " + imsi); - imsi = null; - } - - Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxxxx"); - phone.mSimCard.updateImsiConfiguration(imsi); - phone.mSimCard.broadcastSimStateChangedIntent( - SimCard.INTENT_VALUE_SIM_IMSI, null); - - int mcc = Integer.parseInt(imsi.substring(0, 3)); - setTimezoneFromMccIfNeeded(mcc); - setLocaleFromMccIfNeeded(mcc); - break; - - case EVENT_GET_MBI_DONE: - boolean isValidMbdn; - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[]) ar.result; - - isValidMbdn = false; - if (ar.exception == null) { - // Refer TS 51.011 Section 10.3.44 for content details - Log.d(LOG_TAG, "EF_MBI: " + - SimUtils.bytesToHexString(data)); - - // Voice mail record number stored first - mailboxIndex = (int)data[0] & 0xff; - - // check if dailing numbe id valid - if (mailboxIndex != 0 && mailboxIndex != 0xff) { - Log.d(LOG_TAG, "Got valid mailbox number for MBDN"); - isValidMbdn = true; - } - } - - // one more record to load - recordsToLoad += 1; - - if (isValidMbdn) { - // Note: MBDN was not included in NUM_OF_SIM_RECORDS_LOADED - new AdnRecordLoader(phone).loadFromEF(EF_MBDN, EF_EXT6, - mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE)); - } else { - // If this EF not present, try mailbox as in CPHS standard - // CPHS (CPHS4_2.WW6) is a european standard. - new AdnRecordLoader(phone).loadFromEF(EF_MAILBOX_CPHS, - EF_EXT1, 1, - obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - } - - break; - case EVENT_GET_CPHS_MAILBOX_DONE: - case EVENT_GET_MBDN_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - - Log.d(LOG_TAG, "Invalid or missing EF" - + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? "[MAILBOX]" : "[MBDN]")); - - // Bug #645770 fall back to CPHS - // FIXME should use SST to decide - - if (msg.what == EVENT_GET_MBDN_DONE) { - //load CPHS on fail... - // FIXME right now, only load line1's CPHS voice mail entry - - recordsToLoad += 1; - new AdnRecordLoader(phone).loadFromEF( - EF_MAILBOX_CPHS, EF_EXT1, 1, - obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - } - break; - } - - adn = (AdnRecord)ar.result; - - Log.d(LOG_TAG, "VM: " + adn + ((msg.what == EVENT_GET_CPHS_MAILBOX_DONE) ? " EF[MAILBOX]" : " EF[MBDN]")); - - if (adn.isEmpty() && msg.what == EVENT_GET_MBDN_DONE) { - // Bug #645770 fall back to CPHS - // FIXME should use SST to decide - // FIXME right now, only load line1's CPHS voice mail entry - recordsToLoad += 1; - new AdnRecordLoader(phone).loadFromEF( - EF_MAILBOX_CPHS, EF_EXT1, 1, - obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - - break; - } - - voiceMailNum = adn.getNumber(); - voiceMailTag = adn.getAlphaTag(); - break; - - case EVENT_GET_MSISDN_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - Log.d(LOG_TAG, "Invalid or missing EF[MSISDN]"); - break; - } - - adn = (AdnRecord)ar.result; - - msisdn = adn.getNumber(); - msisdnTag = adn.getAlphaTag(); - - Log.d(LOG_TAG, "MSISDN: " + msisdn); - break; - - case EVENT_SET_MSISDN_DONE: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - - if (ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - break; - - case EVENT_GET_MWIS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - Log.d(LOG_TAG, "EF_MWIS: " + - SimUtils.bytesToHexString(data)); - - efMWIS = data; - - if ((data[0] & 0xff) == 0xff) { - Log.d(LOG_TAG, "SIMRecords: Uninitialized record MWIS"); - break; - } - - // Refer TS 51.011 Section 10.3.45 for the content description - boolean voiceMailWaiting = ((data[0] & 0x01) != 0); - countVoiceMessages = data[1] & 0xff; - - if (voiceMailWaiting && countVoiceMessages == 0) { - // Unknown count = -1 - countVoiceMessages = -1; - } - - phone.notifyMessageWaitingIndicator(); - break; - - case EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - efCPHS_MWI = data; - - // Use this data if the EF[MWIS] exists and - // has been loaded - - if (efMWIS == null) { - int indicator = (int)(data[0] & 0xf); - - // Refer CPHS4_2.WW6 B4.2.3 - if (indicator == 0xA) { - // Unknown count = -1 - countVoiceMessages = -1; - } else if (indicator == 0x5) { - countVoiceMessages = 0; - } - - phone.notifyMessageWaitingIndicator(); - } - break; - - case EVENT_GET_ICCID_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - iccid = SimUtils.bcdToString(data, 0, data.length); - - Log.d(LOG_TAG, "iccid: " + iccid); - - break; - - - case EVENT_GET_AD_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - Log.d(LOG_TAG, "EF_AD: " + - SimUtils.bytesToHexString(data)); - - if (data.length < 3) { - Log.d(LOG_TAG, "SIMRecords: Corrupt AD data on SIM"); - break; - } - - if (data.length == 3) { - Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD"); - break; - } - - mncLength = (int)data[3] & 0xf; - - if (mncLength == 0xf) { - // Resetting mncLength to 0 to indicate that it is not - // initialised - mncLength = 0; - - Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD"); - break; - } - - break; - - case EVENT_GET_SPN_DONE: - isRecordLoadResponse = true; - ar = (AsyncResult) msg.obj; - getSpnFsm(false, ar); - break; - - case EVENT_GET_CFF_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult) msg.obj; - data = (byte[]) ar.result; - - if (ar.exception != null) { - break; - } - - Log.d(LOG_TAG, "EF_CFF_CPHS: " + - SimUtils.bytesToHexString(data)); - mEfCff = data; - - if (mEfCfis == null) { - callForwardingEnabled = - ((data[0] & CFF_LINE1_MASK) == CFF_UNCONDITIONAL_ACTIVE); - - phone.notifyCallForwardingIndicator(); - } - break; - - case EVENT_GET_SPDI_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - parseEfSpdi(data); - break; - - case EVENT_UPDATE_DONE: - ar = (AsyncResult)msg.obj; - if (ar.exception != null) { - Log.i(LOG_TAG, "SIMRecords update failed", ar.exception); - } - break; - - case EVENT_GET_PNN_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - SimTlv tlv = new SimTlv(data, 0, data.length); - - for ( ; tlv.isValidObject() ; tlv.nextObject()) { - if (tlv.getTag() == TAG_FULL_NETWORK_NAME) { - pnnHomeName - = SimUtils.networkNameToString( - tlv.getData(), 0, tlv.getData().length); - break; - } - } - break; - - case EVENT_GET_ALL_SMS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - if (ar.exception != null) - break; - - handleSmses((ArrayList) ar.result); - break; - - case EVENT_MARK_SMS_READ_DONE: - Log.i("ENF", "marked read: sms " + msg.arg1); - break; - - - case EVENT_SMS_ON_SIM: - isRecordLoadResponse = false; - - ar = (AsyncResult)msg.obj; - - int[] index = (int[])ar.result; - - if (ar.exception != null || index.length != 1) { - Log.e(LOG_TAG, "[SIMRecords] Error on SMS_ON_SIM with exp " - + ar.exception + " length " + index.length); - } else { - Log.d(LOG_TAG, "READ EF_SMS RECORD index=" + index[0]); - phone.mSIMFileHandler.loadEFLinearFixed(EF_SMS,index[0],obtainMessage(EVENT_GET_SMS_DONE)); - } - break; - - case EVENT_GET_SMS_DONE: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - if (ar.exception == null) { - handleSms((byte[])ar.result); - } else { - Log.e(LOG_TAG, "[SIMRecords] Error on GET_SMS with exp " - + ar.exception); - } - break; - case EVENT_GET_SST_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - //Log.d(LOG_TAG, "SST: " + SimUtils.bytesToHexString(data)); - break; - - case EVENT_GET_INFO_CPHS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - - if (ar.exception != null) { - break; - } - - mCphsInfo = (byte[])ar.result; - - if (DBG) log("iCPHS: " + SimUtils.bytesToHexString(mCphsInfo)); - break; - - case EVENT_SET_MBDN_DONE: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - - if (ar.exception == null) { - voiceMailNum = newVoiceMailNum; - voiceMailTag = newVoiceMailTag; - } - - if (isCphsMailboxEnabled()) { - adn = new AdnRecord(voiceMailTag, voiceMailNum); - Message onCphsCompleted = (Message) ar.userObj; - - /* write to cphs mailbox whenever it is available but - * we only need notify caller once if both updating are - * successful. - * - * so if set_mbdn successful, notify caller here and set - * onCphsCompleted to null - */ - if (ar.exception == null && ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = null; - ((Message) ar.userObj).sendToTarget(); - - if (DBG) log("Callback with MBDN successful."); - - onCphsCompleted = null; - } - - new AdnRecordLoader(phone). - updateEF(adn, EF_MAILBOX_CPHS, EF_EXT1, 1, null, - obtainMessage(EVENT_SET_CPHS_MAILBOX_DONE, - onCphsCompleted)); - } else { - if (ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - } - break; - case EVENT_SET_CPHS_MAILBOX_DONE: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - if(ar.exception == null) { - voiceMailNum = newVoiceMailNum; - voiceMailTag = newVoiceMailTag; - } else { - if (DBG) log("Set CPHS MailBox with exception: " - + ar.exception); - } - if (ar.userObj != null) { - if (DBG) log("Callback with CPHS MB successful."); - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - break; - case EVENT_SIM_REFRESH: - isRecordLoadResponse = false; - ar = (AsyncResult)msg.obj; - if (DBG) log("Sim REFRESH with exception: " + ar.exception); - if (ar.exception == null) { - handleSimRefresh((int[])(ar.result)); - } - break; - case EVENT_GET_CFIS_DONE: - isRecordLoadResponse = true; - - ar = (AsyncResult)msg.obj; - data = (byte[])ar.result; - - if (ar.exception != null) { - break; - } - - Log.d(LOG_TAG, "EF_CFIS: " + - SimUtils.bytesToHexString(data)); - - mEfCfis = data; - - // Refer TS 51.011 Section 10.3.46 for the content description - callForwardingEnabled = ((data[1] & 0x01) != 0); - - phone.notifyCallForwardingIndicator(); - break; - - }}catch (RuntimeException exc) { - // I don't want these exceptions to be fatal - Log.w(LOG_TAG, "Exception parsing SIM record", exc); - } finally { - // Count up record load responses even if they are fails - if (isRecordLoadResponse) { - onRecordLoaded(); - } - } - } - - private void handleFileUpdate(int efid) { - switch(efid) { - case EF_MBDN: - recordsToLoad++; - new AdnRecordLoader(phone).loadFromEF(EF_MBDN, EF_EXT6, - mailboxIndex, obtainMessage(EVENT_GET_MBDN_DONE)); - break; - case EF_MAILBOX_CPHS: - recordsToLoad++; - new AdnRecordLoader(phone).loadFromEF(EF_MAILBOX_CPHS, EF_EXT1, - 1, obtainMessage(EVENT_GET_CPHS_MAILBOX_DONE)); - break; - default: - // For now, fetch all records if this is not a - // voicemail number. - // TODO: Handle other cases, instead of fetching all. - adnCache.reset(); - fetchSimRecords(); - break; - } - } - - private void handleSimRefresh(int[] result) { - if (result == null || result.length == 0) { - if (DBG) log("handleSimRefresh without input"); - return; - } - - switch ((result[0])) { - case CommandsInterface.SIM_REFRESH_FILE_UPDATED: - if (DBG) log("handleSimRefresh with SIM_REFRESH_FILE_UPDATED"); - // result[1] contains the EFID of the updated file. - int efid = result[1]; - handleFileUpdate(efid); - break; - case CommandsInterface.SIM_REFRESH_INIT: - if (DBG) log("handleSimRefresh with SIM_REFRESH_INIT"); - // need to reload all files (that we care about) - adnCache.reset(); - fetchSimRecords(); - break; - case CommandsInterface.SIM_REFRESH_RESET: - if (DBG) log("handleSimRefresh with SIM_REFRESH_RESET"); - phone.mCM.setRadioPower(false, null); - /* Note: no need to call setRadioPower(true). Assuming the desired - * radio power state is still ON (as tracked by ServiceStateTracker), - * ServiceStateTracker will call setRadioPower when it receives the - * RADIO_STATE_CHANGED notification for the power off. And if the - * desired power state has changed in the interim, we don't want to - * override it with an unconditional power on. - */ - break; - default: - // unknown refresh operation - if (DBG) log("handleSimRefresh with unknown operation"); - break; - } - } - - private void handleSms(byte[] ba) - { - if (ba[0] != 0) - Log.d("ENF", "status : " + ba[0]); - - // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3 - // 3 == "received by MS from network; message to be read" - if (ba[0] == 3) { - int n = ba.length; - - // Note: Data may include trailing FF's. That's OK; message - // should still parse correctly. - byte[] nba = new byte[n - 1]; - System.arraycopy(ba, 1, nba, 0, n - 1); - - String pdu = SimUtils.bytesToHexString(nba); - // XXX first line is bogus - SmsMessage message = SmsMessage.newFromCMT( - new String[] { "", pdu }); - - phone.mSMS.dispatchMessage(message); - } - } - - - private void handleSmses(ArrayList messages) { - int count = messages.size(); - - for (int i = 0; i < count; i++) { - byte[] ba = (byte[]) messages.get(i); - - if (ba[0] != 0) - Log.i("ENF", "status " + i + ": " + ba[0]); - - // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3 - // 3 == "received by MS from network; message to be read" - - if (ba[0] == 3) { - int n = ba.length; - - // Note: Data may include trailing FF's. That's OK; message - // should still parse correctly. - byte[] nba = new byte[n - 1]; - System.arraycopy(ba, 1, nba, 0, n - 1); - - String pdu = SimUtils.bytesToHexString(nba); - // XXX first line is bogus - SmsMessage message = SmsMessage.newFromCMT( - new String[] { "", pdu }); - - phone.mSMS.dispatchMessage(message); - - // 3GPP TS 51.011 v5.0.0 (20011-12) 10.5.3 - // 1 == "received by MS from network; message read" - - ba[0] = 1; - - if (false) { // XXX writing seems to crash RdoServD - phone.mSIMFileHandler.updateEFLinearFixed(EF_SMS, i, ba, null, - obtainMessage(EVENT_MARK_SMS_READ_DONE, i)); - } - } - } - } - - - //***** Private Methods - - private void onRecordLoaded() - { - // One record loaded successfully or failed, In either case - // we need to update the recordsToLoad count - recordsToLoad -= 1; - - if (recordsToLoad == 0 && recordsRequested == true) { - onAllRecordsLoaded(); - } else if (recordsToLoad < 0) { - Log.e(LOG_TAG, "SIMRecords: recordsToLoad <0, programmer error suspected"); - recordsToLoad = 0; - } - } - - private void onAllRecordsLoaded() - { - Log.d(LOG_TAG, "SIMRecords: record load complete"); - - // Some fields require more than one SIM record to set - - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_NUMERIC, - getSIMOperatorNumeric()); - - if (imsi != null) { - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ISO_COUNTRY, - MccTable.countryCodeForMcc( - Integer.parseInt(imsi.substring(0,3)))); - } - else { - Log.e("SIM", "[SIMRecords] onAllRecordsLoaded: imsi is NULL!"); - } - - setVoiceMailByCountry(getSIMOperatorNumeric()); - - recordsLoadedRegistrants.notifyRegistrants( - new AsyncResult(null, null, null)); - phone.mSimCard.broadcastSimStateChangedIntent( - SimCard.INTENT_VALUE_SIM_LOADED, null); - } - - private void setVoiceMailByCountry (String spn) { - if (mVmConfig.containsCarrier(spn)) { - isVoiceMailFixed = true; - voiceMailNum = mVmConfig.getVoiceMailNumber(spn); - voiceMailTag = mVmConfig.getVoiceMailTag(spn); - } - } - - private void onSimReady() { - /* broadcast intent SIM_READY here so that we can make sure - READY is sent before IMSI ready - */ - phone.mSimCard.broadcastSimStateChangedIntent( - SimCard.INTENT_VALUE_SIM_READY, null); - - fetchSimRecords(); - } - - private void fetchSimRecords() { - recordsRequested = true; - - Log.v(LOG_TAG, "SIMRecords:fetchSimRecords " + recordsToLoad); - - phone.mCM.getIMSI(obtainMessage(EVENT_GET_IMSI_DONE)); - recordsToLoad++; - - phone.mSIMFileHandler.loadEFTransparent(EF_ICCID, - obtainMessage(EVENT_GET_ICCID_DONE)); - recordsToLoad++; - - // FIXME should examine EF[MSISDN]'s capability configuration - // to determine which is the voice/data/fax line - new AdnRecordLoader(phone).loadFromEF(EF_MSISDN, EF_EXT1, 1, - obtainMessage(EVENT_GET_MSISDN_DONE)); - recordsToLoad++; - - // Record number is subscriber profile - phone.mSIMFileHandler.loadEFLinearFixed(EF_MBI, 1, - obtainMessage(EVENT_GET_MBI_DONE)); - recordsToLoad++; - - phone.mSIMFileHandler.loadEFTransparent(EF_AD, - obtainMessage(EVENT_GET_AD_DONE)); - recordsToLoad++; - - // Record number is subscriber profile - phone.mSIMFileHandler.loadEFLinearFixed(EF_MWIS, 1, - obtainMessage(EVENT_GET_MWIS_DONE)); - recordsToLoad++; - - - // Also load CPHS-style voice mail indicator, which stores - // the same info as EF[MWIS]. If both exist, both are updated - // but the EF[MWIS] data is preferred - // Please note this must be loaded after EF[MWIS] - phone.mSIMFileHandler.loadEFTransparent( - EF_VOICE_MAIL_INDICATOR_CPHS, - obtainMessage(EVENT_GET_VOICE_MAIL_INDICATOR_CPHS_DONE)); - recordsToLoad++; - - // Same goes for Call Forward Status indicator: fetch both - // EF[CFIS] and CPHS-EF, with EF[CFIS] preferred. - phone.mSIMFileHandler.loadEFLinearFixed(EF_CFIS, 1, obtainMessage(EVENT_GET_CFIS_DONE)); - recordsToLoad++; - phone.mSIMFileHandler.loadEFTransparent(EF_CFF_CPHS, - obtainMessage(EVENT_GET_CFF_DONE)); - recordsToLoad++; - - - getSpnFsm(true, null); - - phone.mSIMFileHandler.loadEFTransparent(EF_SPDI, - obtainMessage(EVENT_GET_SPDI_DONE)); - recordsToLoad++; - - phone.mSIMFileHandler.loadEFLinearFixed(EF_PNN, 1, - obtainMessage(EVENT_GET_PNN_DONE)); - recordsToLoad++; - - phone.mSIMFileHandler.loadEFTransparent(EF_SST, - obtainMessage(EVENT_GET_SST_DONE)); - recordsToLoad++; - - phone.mSIMFileHandler.loadEFTransparent(EF_INFO_CPHS, - obtainMessage(EVENT_GET_INFO_CPHS_DONE)); - recordsToLoad++; - - // XXX should seek instead of examining them all - if (false) { // XXX - phone.mSIMFileHandler.loadEFLinearFixedAll(EF_SMS, - obtainMessage(EVENT_GET_ALL_SMS_DONE)); - recordsToLoad++; - } - - if (CRASH_RIL) { - String sms = "0107912160130310f20404d0110041007030208054832b0120ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - byte[] ba = SimUtils.hexStringToBytes(sms); - - phone.mSIMFileHandler.updateEFLinearFixed(EF_SMS, 1, ba, null, - obtainMessage(EVENT_MARK_SMS_READ_DONE, 1)); - } - } - - /** - * Returns the SpnDisplayRule based on settings on the SIM and the - * specified plmn (currently-registered PLMN). See TS 22.101 Annex A - * and TS 51.011 10.3.11 for details. - * - * If the SPN is not found on the SIM, the rule is always PLMN_ONLY. - */ - int getDisplayRule(String plmn) { - int rule; - if (spn == null || spnDisplayCondition == -1) { - // EF_SPN was not found on the SIM, or not yet loaded. Just show ONS. - rule = SPN_RULE_SHOW_PLMN; - } else if (isOnMatchingPlmn(plmn)) { - rule = SPN_RULE_SHOW_SPN; - if ((spnDisplayCondition & 0x01) == 0x01) { - // ONS required when registered to HPLMN or PLMN in EF_SPDI - rule |= SPN_RULE_SHOW_PLMN; - } - } else { - rule = SPN_RULE_SHOW_PLMN; - if ((spnDisplayCondition & 0x02) == 0x00) { - // SPN required if not registered to HPLMN or PLMN in EF_SPDI - rule |= SPN_RULE_SHOW_SPN; - } - } - return rule; - } - - /** - * Checks if plmn is HPLMN or on the spdiNetworks list. - */ - private boolean isOnMatchingPlmn(String plmn) { - if (plmn == null) return false; - - if (plmn.equals(getSIMOperatorNumeric())) { - return true; - } - - if (spdiNetworks != null) { - for (String spdiNet : spdiNetworks) { - if (plmn.equals(spdiNet)) { - return true; - } - } - } - return false; - } - - /** - * States of Get SPN Finite State Machine which only used by getSpnFsm() - */ - private enum Get_Spn_Fsm_State { - IDLE, // No initialized - INIT, // Start FSM - READ_SPN_3GPP, // Load EF_SPN firstly - READ_SPN_CPHS, // Load EF_SPN_CPHS secondly - READ_SPN_SHORT_CPHS // Load EF_SPN_SHORT_CPHS last - } - - /** - * Finite State Machine to load Service Provider Name , which can be stored - * in either EF_SPN (3GPP), EF_SPN_CPHS, or EF_SPN_SHORT_CPHS (CPHS4.2) - * - * After starting, FSM will search SPN EFs in order and stop after finding - * the first valid SPN - * - * @param start set true only for initialize loading - * @param ar the AsyncResult from loadEFTransparent - * ar.exception holds exception in error - * ar.result is byte[] for data in success - */ - private void getSpnFsm(boolean start, AsyncResult ar) { - byte[] data; - - if (start) { - spnState = Get_Spn_Fsm_State.INIT; - } - - switch(spnState){ - case INIT: - spn = null; - - phone.mSIMFileHandler.loadEFTransparent( EF_SPN, - obtainMessage(EVENT_GET_SPN_DONE)); - recordsToLoad++; - - spnState = Get_Spn_Fsm_State.READ_SPN_3GPP; - break; - case READ_SPN_3GPP: - if (ar != null && ar.exception == null) { - data = (byte[]) ar.result; - spnDisplayCondition = 0xff & data[0]; - spn = SimUtils.adnStringFieldToString(data, 1, data.length - 1); - - if (DBG) log("Load EF_SPN: " + spn - + " spnDisplayCondition: " + spnDisplayCondition); - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, spn); - - spnState = Get_Spn_Fsm_State.IDLE; - } else { - phone.mSIMFileHandler.loadEFTransparent( EF_SPN_CPHS, - obtainMessage(EVENT_GET_SPN_DONE)); - recordsToLoad++; - - spnState = Get_Spn_Fsm_State.READ_SPN_CPHS; - - // See TS 51.011 10.3.11. Basically, default to - // show PLMN always, and SPN also if roaming. - spnDisplayCondition = -1; - } - break; - case READ_SPN_CPHS: - if (ar != null && ar.exception == null) { - data = (byte[]) ar.result; - spn = SimUtils.adnStringFieldToString( - data, 0, data.length - 1 ); - - if (DBG) log("Load EF_SPN_CPHS: " + spn); - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, spn); - - spnState = Get_Spn_Fsm_State.IDLE; - } else { - phone.mSIMFileHandler.loadEFTransparent( EF_SPN_SHORT_CPHS, - obtainMessage(EVENT_GET_SPN_DONE)); - recordsToLoad++; - - spnState = Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS; - } - break; - case READ_SPN_SHORT_CPHS: - if (ar != null && ar.exception == null) { - data = (byte[]) ar.result; - spn = SimUtils.adnStringFieldToString( - data, 0, data.length - 1); - - if (DBG) log("Load EF_SPN_SHORT_CPHS: " + spn); - phone.setSystemProperty(PROPERTY_SIM_OPERATOR_ALPHA, spn); - }else { - if (DBG) log("No SPN loaded in either CHPS or 3GPP"); - } - - spnState = Get_Spn_Fsm_State.IDLE; - break; - default: - spnState = Get_Spn_Fsm_State.IDLE; - } - } - - /** - * Parse TS 51.011 EF[SPDI] record - * This record contains the list of numeric network IDs that - * are treated specially when determining SPN display - */ - private void - parseEfSpdi(byte[] data) - { - SimTlv tlv = new SimTlv(data, 0, data.length); - - byte[] plmnEntries = null; - - // There should only be one TAG_SPDI_PLMN_LIST - for ( ; tlv.isValidObject() ; tlv.nextObject()) { - if (tlv.getTag() == TAG_SPDI_PLMN_LIST) { - plmnEntries = tlv.getData(); - break; - } - } - - if (plmnEntries == null) { - return; - } - - spdiNetworks = new ArrayList<String>(plmnEntries.length / 3); - - for (int i = 0 ; i + 2 < plmnEntries.length ; i += 3) { - String plmnCode; - plmnCode = SimUtils.bcdToString(plmnEntries, i, 3); - - // Valid operator codes are 5 or 6 digits - if (plmnCode.length() >= 5) { - log("EF_SPDI network: " + plmnCode); - spdiNetworks.add(plmnCode); - } - } - } - - /** - * check to see if Mailbox Number is allocated and activated in CPHS SST - */ - private boolean isCphsMailboxEnabled() { - if (mCphsInfo == null) return false; - return ((mCphsInfo[1] & CPHS_SST_MBN_MASK) == CPHS_SST_MBN_ENABLED ); - } - - private void log(String s) { - Log.d(LOG_TAG, "[SIMRecords] " + s); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java deleted file mode 100644 index 6eea1d4..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java +++ /dev/null @@ -1,941 +0,0 @@ -/* - * Copyright (C) 2006 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.app.Activity; -import android.app.PendingIntent; -import android.app.AlertDialog; -import android.app.PendingIntent.CanceledException; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.content.Intent; -import android.content.DialogInterface; -import android.content.res.Resources; -import android.database.Cursor; -import android.database.SQLException; -import android.net.Uri; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.provider.Telephony; -import android.provider.Settings; -import android.provider.Telephony.Sms.Intents; -import android.telephony.gsm.SmsMessage; -import android.telephony.gsm.SmsManager; -import com.android.internal.telephony.WapPushOverSms; -import android.telephony.ServiceState; -import android.util.Config; -import com.android.internal.util.HexDump; -import android.util.Log; -import android.view.WindowManager; - -import java.io.ByteArrayOutputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; - -import com.android.internal.R; - -final class SMSDispatcher extends Handler { - private static final String TAG = "GSM"; - - /** Default checking period for SMS sent without uesr permit */ - private static final int DEFAULT_SMS_CHECK_PERIOD = 3600000; - - /** Default number of SMS sent in checking period without uesr permit */ - private static final int DEFAULT_SMS_MAX_COUNT = 100; - - /** Default timeout for SMS sent query */ - private static final int DEFAULT_SMS_TIMOUEOUT = 6000; - - private static final String[] RAW_PROJECTION = new String[] { - "pdu", - "sequence", - }; - - static final int MAIL_SEND_SMS = 1; - - static final int EVENT_NEW_SMS = 1; - - static final int EVENT_SEND_SMS_COMPLETE = 2; - - /** Retry sending a previously failed SMS message */ - static final int EVENT_SEND_RETRY = 3; - - /** Status report received */ - static final int EVENT_NEW_SMS_STATUS_REPORT = 5; - - /** SIM storage is full */ - static final int EVENT_SIM_FULL = 6; - - /** SMS confirm required */ - static final int EVENT_POST_ALERT = 7; - - /** Send the user confirmed SMS */ - static final int EVENT_SEND_CONFIRMED_SMS = 8; - - /** Alert is timeout */ - static final int EVENT_ALERT_TIMEOUT = 9; - - private final GSMPhone mPhone; - - private final WapPushOverSms mWapPush; - - private final Context mContext; - - private final ContentResolver mResolver; - - private final CommandsInterface mCm; - - private final Uri mRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw"); - - /** Maximum number of times to retry sending a failed SMS. */ - private static final int MAX_SEND_RETRIES = 3; - /** Delay before next send attempt on a failed SMS, in milliseconds. */ - private static final int SEND_RETRY_DELAY = 2000; - /** single part SMS */ - private static final int SINGLE_PART_SMS = 1; - - /** - * Message reference for a CONCATENATED_8_BIT_REFERENCE or - * CONCATENATED_16_BIT_REFERENCE message set. Should be - * incremented for each set of concatenated messages. - */ - private static int sConcatenatedRef; - - private SmsCounter mCounter; - - private SmsTracker mSTracker; - - /** - * Implement the per-application based SMS control, which only allows - * a limit on the number of SMS/MMS messages an app can send in checking - * period. - */ - private class SmsCounter { - private int mCheckPeriod; - private int mMaxAllowed; - private HashMap<String, ArrayList<Long>> mSmsStamp; - - /** - * Create SmsCounter - * @param mMax is the number of SMS allowed without user permit - * @param mPeriod is the checking period - */ - SmsCounter(int mMax, int mPeriod) { - mMaxAllowed = mMax; - mCheckPeriod = mPeriod; - mSmsStamp = new HashMap<String, ArrayList<Long>> (); - } - - /** - * Check to see if an application allow to send new SMS messages - * - * @param appName is the application sending sms - * @param smsWaiting is the number of new sms wants to be sent - * @return true if application is allowed to send the requested number - * of new sms messages - */ - boolean check(String appName, int smsWaiting) { - if (!mSmsStamp.containsKey(appName)) { - mSmsStamp.put(appName, new ArrayList<Long>()); - } - - return isUnderLimit(mSmsStamp.get(appName), smsWaiting); - } - - private boolean isUnderLimit(ArrayList<Long> sent, int smsWaiting) { - Long ct = System.currentTimeMillis(); - - Log.d(TAG, "SMS send size=" + sent.size() + "time=" + ct); - - while (sent.size() > 0 && (ct - sent.get(0)) > mCheckPeriod ) { - sent.remove(0); - } - - if ( (sent.size() + smsWaiting) <= mMaxAllowed) { - for (int i = 0; i < smsWaiting; i++ ) { - sent.add(ct); - } - return true; - } - return false; - } - } - - SMSDispatcher(GSMPhone phone) { - mPhone = phone; - mWapPush = new WapPushOverSms(phone); - mContext = phone.getContext(); - mResolver = mContext.getContentResolver(); - mCm = phone.mCM; - mSTracker = null; - - int check_period = Settings.Gservices.getInt(mResolver, - Settings.Gservices.SMS_OUTGOING_CEHCK_INTERVAL_MS, - DEFAULT_SMS_CHECK_PERIOD); - int max_count = Settings.Gservices.getInt(mResolver, - Settings.Gservices.SMS_OUTGOING_CEHCK_MAX_COUNT, - DEFAULT_SMS_MAX_COUNT); - mCounter = new SmsCounter(max_count, check_period); - - mCm.setOnNewSMS(this, EVENT_NEW_SMS, null); - mCm.setOnSmsStatus(this, EVENT_NEW_SMS_STATUS_REPORT, null); - mCm.setOnSimSmsFull(this, EVENT_SIM_FULL, null); - - // Don't always start message ref at 0. - sConcatenatedRef = new Random().nextInt(256); - } - - /* TODO: Need to figure out how to keep track of status report routing in a - * persistent manner. If the phone process restarts (reboot or crash), - * we will lose this list and any status reports that come in after - * will be dropped. - */ - /** Sent messages awaiting a delivery status report. */ - private final ArrayList<SmsTracker> deliveryPendingList = new ArrayList<SmsTracker>(); - - /** - * Handles events coming from the phone stack. Overridden from handler. - * - * @param msg the message to handle - */ - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - switch (msg.what) { - case EVENT_NEW_SMS: - // A new SMS has been received by the device - if (Config.LOGD) { - Log.d(TAG, "New SMS Message Received"); - } - - SmsMessage sms; - - ar = (AsyncResult) msg.obj; - - // FIXME unit test leaves cm == null. this should change - if (mCm != null) { - // FIXME only acknowledge on store - mCm.acknowledgeLastIncomingSMS(true, null); - } - - if (ar.exception != null) { - Log.e(TAG, "Exception processing incoming SMS. Exception:" + ar.exception); - return; - } - - sms = (SmsMessage) ar.result; - dispatchMessage(sms); - - break; - - case EVENT_SEND_SMS_COMPLETE: - // An outbound SMS has been sucessfully transferred, or failed. - handleSendComplete((AsyncResult) msg.obj); - break; - - case EVENT_SEND_RETRY: - sendSms((SmsTracker) msg.obj); - break; - - case EVENT_NEW_SMS_STATUS_REPORT: - handleStatusReport((AsyncResult)msg.obj); - break; - - case EVENT_SIM_FULL: - handleSimFull(); - break; - - case EVENT_POST_ALERT: - handleReachSentLimit((SmsTracker)(msg.obj)); - break; - - case EVENT_ALERT_TIMEOUT: - ((AlertDialog)(msg.obj)).dismiss(); - msg.obj = null; - mSTracker = null; - break; - - case EVENT_SEND_CONFIRMED_SMS: - if (mSTracker!=null) { - if (isMultipartTracker(mSTracker)) { - sendMultipartSms(mSTracker); - } else { - sendSms(mSTracker); - } - mSTracker = null; - } - break; - } - } - - /** - * Called when SIM_FULL message is received from the RIL. Notifies interested - * parties that SIM storage for SMS messages is full. - */ - private void handleSimFull() { - // broadcast SIM_FULL intent - Intent intent = new Intent(Intents.SIM_FULL_ACTION); - mPhone.getContext().sendBroadcast(intent, "android.permission.RECEIVE_SMS"); - } - - /** - * Called when a status report is received. This should correspond to - * a previously successful SEND. - * - * @param ar AsyncResult passed into the message handler. ar.result should - * be a String representing the status report PDU, as ASCII hex. - */ - private void handleStatusReport(AsyncResult ar) { - String pduString = (String) ar.result; - SmsMessage sms = SmsMessage.newFromCDS(pduString); - - if (sms != null) { - int messageRef = sms.messageRef; - for (int i = 0, count = deliveryPendingList.size(); i < count; i++) { - SmsTracker tracker = deliveryPendingList.get(i); - if (tracker.mMessageRef == messageRef) { - // Found it. Remove from list and broadcast. - deliveryPendingList.remove(i); - PendingIntent intent = tracker.mDeliveryIntent; - Intent fillIn = new Intent(); - fillIn.putExtra("pdu", SimUtils.hexStringToBytes(pduString)); - try { - intent.send(mContext, Activity.RESULT_OK, fillIn); - } catch (CanceledException ex) {} - - // Only expect to see one tracker matching this messageref - break; - } - } - } - - if (mCm != null) { - mCm.acknowledgeLastIncomingSMS(true, null); - } - } - - /** - * Called when SMS send completes. Broadcasts a sentIntent on success. - * On failure, either sets up retries or broadcasts a sentIntent with - * the failure in the result code. - * - * @param ar AsyncResult passed into the message handler. ar.result should - * an SmsResponse instance if send was successful. ar.userObj - * should be an SmsTracker instance. - */ - private void handleSendComplete(AsyncResult ar) { - SmsTracker tracker = (SmsTracker) ar.userObj; - PendingIntent sentIntent = tracker.mSentIntent; - - if (ar.exception == null) { - if (Config.LOGD) { - Log.d(TAG, "SMS send complete. Broadcasting " - + "intent: " + sentIntent); - } - - if (tracker.mDeliveryIntent != null) { - // Expecting a status report. Add it to the list. - int messageRef = ((SmsResponse)ar.result).messageRef; - tracker.mMessageRef = messageRef; - deliveryPendingList.add(tracker); - } - - if (sentIntent != null) { - try { - sentIntent.send(Activity.RESULT_OK); - } catch (CanceledException ex) {} - } - } else { - if (Config.LOGD) { - Log.d(TAG, "SMS send failed"); - } - - int ss = mPhone.getServiceState().getState(); - - if (ss != ServiceState.STATE_IN_SERVICE) { - handleNotInService(ss, tracker); - } else if ((((CommandException)(ar.exception)).getCommandError() - == CommandException.Error.SMS_FAIL_RETRY) && - tracker.mRetryCount < MAX_SEND_RETRIES) { - // Retry after a delay if needed. - // TODO: According to TS 23.040, 9.2.3.6, we should resend - // with the same TP-MR as the failed message, and - // TP-RD set to 1. However, we don't have a means of - // knowing the MR for the failed message (EF_SMSstatus - // may or may not have the MR corresponding to this - // message, depending on the failure). Also, in some - // implementations this retry is handled by the baseband. - tracker.mRetryCount++; - Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker); - sendMessageDelayed(retryMsg, SEND_RETRY_DELAY); - } else if (tracker.mSentIntent != null) { - // Done retrying; return an error to the app. - try { - tracker.mSentIntent.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE); - } catch (CanceledException ex) {} - } - } - } - - /** - * Handles outbound message when the phone is not in service. - * - * @param ss Current service state. Valid values are: - * OUT_OF_SERVICE - * EMERGENCY_ONLY - * POWER_OFF - * @param tracker An SmsTracker for the current message. - */ - private void handleNotInService(int ss, SmsTracker tracker) { - if (tracker.mSentIntent != null) { - try { - if (ss == ServiceState.STATE_POWER_OFF) { - tracker.mSentIntent.send(SmsManager.RESULT_ERROR_RADIO_OFF); - } else { - tracker.mSentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE); - } - } catch (CanceledException ex) {} - } - } - - /** - * Dispatches an incoming SMS messages. - * - * @param sms the incoming message from the phone - */ - /* package */ void dispatchMessage(SmsMessage sms) { - - // If sms is null, means there was a parsing error. - // TODO: Should NAK this. - if (sms == null) { - return; - } - - boolean handled = false; - - // Special case the message waiting indicator messages - if (sms.isMWISetMessage()) { - mPhone.updateMessageWaitingIndicator(true); - - if (sms.isMwiDontStore()) { - handled = true; - } - - if (Config.LOGD) { - Log.d(TAG, - "Received voice mail indicator set SMS shouldStore=" - + !handled); - } - } else if (sms.isMWIClearMessage()) { - mPhone.updateMessageWaitingIndicator(false); - - if (sms.isMwiDontStore()) { - handled = true; - } - - if (Config.LOGD) { - Log.d(TAG, - "Received voice mail indicator clear SMS shouldStore=" - + !handled); - } - } - - if (handled) { - return; - } - - // Parse the headers to see if this is partial, or port addressed - int referenceNumber = -1; - int count = 0; - int sequence = 0; - int destPort = -1; - - SmsHeader header = sms.getUserDataHeader(); - if (header != null) { - for (SmsHeader.Element element : header.getElements()) { - switch (element.getID()) { - case SmsHeader.CONCATENATED_8_BIT_REFERENCE: { - byte[] data = element.getData(); - - referenceNumber = data[0] & 0xff; - count = data[1] & 0xff; - sequence = data[2] & 0xff; - - break; - } - - case SmsHeader.CONCATENATED_16_BIT_REFERENCE: { - byte[] data = element.getData(); - - referenceNumber = (data[0] & 0xff) * 256 + (data[1] & 0xff); - count = data[2] & 0xff; - sequence = data[3] & 0xff; - - break; - } - - case SmsHeader.APPLICATION_PORT_ADDRESSING_16_BIT: { - byte[] data = element.getData(); - - destPort = (data[0] & 0xff) << 8; - destPort |= (data[1] & 0xff); - - break; - } - } - } - } - - if (referenceNumber == -1) { - // notify everyone of the message if it isn't partial - byte[][] pdus = new byte[1][]; - pdus[0] = sms.getPdu(); - - if (destPort != -1) { - if (destPort == SmsHeader.PORT_WAP_PUSH) { - mWapPush.dispatchWapPdu(sms.getUserData()); - } - // The message was sent to a port, so concoct a URI for it - dispatchPortAddressedPdus(pdus, destPort); - } else { - // It's a normal message, dispatch it - dispatchPdus(pdus); - } - } else { - // Process the message part - processMessagePart(sms, referenceNumber, sequence, count, destPort); - } - } - - /** - * If this is the last part send the parts out to the application, otherwise - * the part is stored for later processing. - */ - private void processMessagePart(SmsMessage sms, int referenceNumber, - int sequence, int count, int destinationPort) { - // Lookup all other related parts - StringBuilder where = new StringBuilder("reference_number ="); - where.append(referenceNumber); - where.append(" AND address = ?"); - String[] whereArgs = new String[] {sms.getOriginatingAddress()}; - - byte[][] pdus = null; - Cursor cursor = null; - try { - cursor = mResolver.query(mRawUri, RAW_PROJECTION, where.toString(), whereArgs, null); - int cursorCount = cursor.getCount(); - if (cursorCount != count - 1) { - // We don't have all the parts yet, store this one away - ContentValues values = new ContentValues(); - values.put("date", new Long(sms.getTimestampMillis())); - values.put("pdu", HexDump.toHexString(sms.getPdu())); - values.put("address", sms.getOriginatingAddress()); - values.put("reference_number", referenceNumber); - values.put("count", count); - values.put("sequence", sequence); - if (destinationPort != -1) { - values.put("destination_port", destinationPort); - } - mResolver.insert(mRawUri, values); - - return; - } - - // All the parts are in place, deal with them - int pduColumn = cursor.getColumnIndex("pdu"); - int sequenceColumn = cursor.getColumnIndex("sequence"); - - pdus = new byte[count][]; - for (int i = 0; i < cursorCount; i++) { - cursor.moveToNext(); - int cursorSequence = (int)cursor.getLong(sequenceColumn); - pdus[cursorSequence - 1] = HexDump.hexStringToByteArray( - cursor.getString(pduColumn)); - } - // This one isn't in the DB, so add it - pdus[sequence - 1] = sms.getPdu(); - - // Remove the parts from the database - mResolver.delete(mRawUri, where.toString(), whereArgs); - } catch (SQLException e) { - Log.e(TAG, "Can't access multipart SMS database", e); - return; // TODO: NACK the message or something, don't just discard. - } finally { - if (cursor != null) cursor.close(); - } - - // Dispatch the PDUs to applications - switch (destinationPort) { - case SmsHeader.PORT_WAP_PUSH: { - // Build up the data stream - ByteArrayOutputStream output = new ByteArrayOutputStream(); - for (int i = 0; i < count; i++) { - SmsMessage msg = SmsMessage.createFromPdu(pdus[i]); - byte[] data = msg.getUserData(); - output.write(data, 0, data.length); - } - - // Handle the PUSH - mWapPush.dispatchWapPdu(output.toByteArray()); - break; - } - - case -1: - // The messages were not sent to a port - dispatchPdus(pdus); - break; - - default: - // The messages were sent to a port, so concoct a URI for it - dispatchPortAddressedPdus(pdus, destinationPort); - break; - } - } - - /** - * Dispatches standard PDUs to interested applications - * - * @param pdus The raw PDUs making up the message - */ - private void dispatchPdus(byte[][] pdus) { - Intent intent = new Intent(Intents.SMS_RECEIVED_ACTION); - intent.putExtra("pdus", pdus); - mPhone.getContext().sendBroadcast( - intent, "android.permission.RECEIVE_SMS"); - } - - /** - * Dispatches port addressed PDUs to interested applications - * - * @param pdus The raw PDUs making up the message - * @param port The destination port of the messages - */ - private void dispatchPortAddressedPdus(byte[][] pdus, int port) { - Uri uri = Uri.parse("sms://localhost:" + port); - Intent intent = new Intent(Intents.DATA_SMS_RECEIVED_ACTION, uri); - intent.putExtra("pdus", pdus); - mPhone.getContext().sendBroadcast( - intent, "android.permission.RECEIVE_SMS"); - } - - - /** - * Send a multi-part text based SMS. - * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param parts an <code>ArrayList</code> of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been delivered - * to the recipient. The raw pdu of the status report is in the - * extended data ("pdu"). - */ - void sendMultipartText(String destinationAddress, String scAddress, ArrayList<String> parts, - ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { - - PendingIntent sentIntent = null; - - - int ss = mPhone.getServiceState().getState(); - - if (ss == ServiceState.STATE_IN_SERVICE) { - // Only check SMS sending limit while in service - if (sentIntents != null && sentIntents.size() > 0) { - sentIntent = sentIntents.get(0); - } - String appName = getAppNameByIntent(sentIntent); - if ( !mCounter.check(appName, parts.size())) { - HashMap<String, Object> map = new HashMap<String, Object>(); - map.put("destination", destinationAddress); - map.put("scaddress", scAddress); - map.put("parts", parts); - map.put("sentIntents", sentIntents); - map.put("deliveryIntents", deliveryIntents); - - SmsTracker multipartParameter = new SmsTracker(map, null, null); - - sendMessage(obtainMessage(EVENT_POST_ALERT, multipartParameter)); - return; - } - } - - sendMultipartTextWithPermit(destinationAddress, - scAddress, parts, sentIntents, deliveryIntents); - } - - /** - * Send a multi-part text based SMS which already passed SMS control check. - * - * It is the working function for sendMultipartText(). - * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param parts an <code>ArrayList</code> of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * @param deliveryIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been delivered - * to the recipient. The raw pdu of the status report is in the - * extended data ("pdu"). - */ - private void sendMultipartTextWithPermit(String destinationAddress, - String scAddress, ArrayList<String> parts, - ArrayList<PendingIntent> sentIntents, - ArrayList<PendingIntent> deliveryIntents) { - - PendingIntent sentIntent = null; - PendingIntent deliveryIntent = null; - - // check if in service - int ss = mPhone.getServiceState().getState(); - if (ss != ServiceState.STATE_IN_SERVICE) { - for (int i = 0, count = parts.size(); i < count; i++) { - if (sentIntents != null && sentIntents.size() > i) { - sentIntent = sentIntents.get(i); - } - SmsTracker tracker = new SmsTracker(null, sentIntent, null); - handleNotInService(ss, tracker); - } - return; - } - - int ref = ++sConcatenatedRef & 0xff; - - for (int i = 0, count = parts.size(); i < count; i++) { - // build SmsHeader - byte[] data = new byte[3]; - data[0] = (byte) ref; // reference #, unique per message - data[1] = (byte) count; // total part count - data[2] = (byte) (i + 1); // 1-based sequence - SmsHeader header = new SmsHeader(); - header.add(new SmsHeader.Element(SmsHeader.CONCATENATED_8_BIT_REFERENCE, data)); - - if (sentIntents != null && sentIntents.size() > i) { - sentIntent = sentIntents.get(i); - } - if (deliveryIntents != null && deliveryIntents.size() > i) { - deliveryIntent = deliveryIntents.get(i); - } - - SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(scAddress, destinationAddress, - parts.get(i), deliveryIntent != null, header.toByteArray()); - - HashMap<String, Object> map = new HashMap<String, Object>(); - map.put("smsc", pdus.encodedScAddress); - map.put("pdu", pdus.encodedMessage); - - SmsTracker tracker = new SmsTracker(map, sentIntent, - deliveryIntent); - sendSms(tracker); - } - } - - /** - * Send a SMS - * - * @param smsc the SMSC to send the message through, or NULL for the - * defatult SMSC - * @param pdu the raw PDU to send - * @param sentIntent if not NULL this <code>Intent</code> is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, - * which cause smaller number of SMS to be sent in checking period. - * @param deliveryIntent if not NULL this <code>Intent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - if (pdu == null) { - if (sentIntent != null) { - try { - sentIntent.send(SmsManager.RESULT_ERROR_NULL_PDU); - } catch (CanceledException ex) {} - } - return; - } - - HashMap<String, Object> map = new HashMap<String, Object>(); - map.put("smsc", smsc); - map.put("pdu", pdu); - - SmsTracker tracker = new SmsTracker(map, sentIntent, - deliveryIntent); - int ss = mPhone.getServiceState().getState(); - - if (ss != ServiceState.STATE_IN_SERVICE) { - handleNotInService(ss, tracker); - } else { - String appName = getAppNameByIntent(sentIntent); - if (mCounter.check(appName, SINGLE_PART_SMS)) { - sendSms(tracker); - } else { - sendMessage(obtainMessage(EVENT_POST_ALERT, tracker)); - } - } - } - - /** - * Post an alert while SMS needs user confirm. - * - * An SmsTracker for the current message. - */ - private void handleReachSentLimit(SmsTracker tracker) { - - Resources r = Resources.getSystem(); - - String appName = getAppNameByIntent(tracker.mSentIntent); - - AlertDialog d = new AlertDialog.Builder(mContext) - .setTitle(r.getString(R.string.sms_control_title)) - .setMessage(appName + " " + r.getString(R.string.sms_control_message)) - .setPositiveButton(r.getString(R.string.sms_control_yes), mListener) - .setNegativeButton(r.getString(R.string.sms_control_no), null) - .create(); - - d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - d.show(); - - mSTracker = tracker; - sendMessageDelayed ( obtainMessage(EVENT_ALERT_TIMEOUT, d), - DEFAULT_SMS_TIMOUEOUT); - } - - private String getAppNameByIntent(PendingIntent intent) { - Resources r = Resources.getSystem(); - return (intent != null) ? intent.getTargetPackage() - : r.getString(R.string.sms_control_default_app_name); - } - - /** - * Send the message along to the radio. - * - * @param tracker holds the SMS message to send - */ - private void sendSms(SmsTracker tracker) { - HashMap map = tracker.mData; - - byte smsc[] = (byte[]) map.get("smsc"); - byte pdu[] = (byte[]) map.get("pdu"); - - Message reply = obtainMessage(EVENT_SEND_SMS_COMPLETE, tracker); - mCm.sendSMS(SimUtils.bytesToHexString(smsc), - SimUtils.bytesToHexString(pdu), reply); - } - - /** - * Send the multi-part SMS based on multipart Sms tracker - * - * @param tracker holds the multipart Sms tracker ready to be sent - */ - private void sendMultipartSms (SmsTracker tracker) { - ArrayList<String> parts; - ArrayList<PendingIntent> sentIntents; - ArrayList<PendingIntent> deliveryIntents; - - HashMap map = tracker.mData; - - String destinationAddress = (String) map.get("destination"); - String scAddress = (String) map.get("scaddress"); - - parts = (ArrayList<String>) map.get("parts"); - sentIntents = (ArrayList<PendingIntent>) map.get("sentIntents"); - deliveryIntents = (ArrayList<PendingIntent>) map.get("deliveryIntents"); - - sendMultipartTextWithPermit(destinationAddress, - scAddress, parts, sentIntents, deliveryIntents); - - } - - /** - * Check if a SmsTracker holds multi-part Sms - * - * @param tracker a SmsTracker could hold a multi-part Sms - * @return true for tracker holds Multi-parts Sms - */ - private boolean isMultipartTracker (SmsTracker tracker) { - HashMap map = tracker.mData; - return ( map.get("parts") != null); - } - - /** - * Keeps track of an SMS that has been sent to the RIL, until it it has - * successfully been sent, or we're done trying. - * - */ - static class SmsTracker { - HashMap mData; - int mRetryCount; - int mMessageRef; - - PendingIntent mSentIntent; - PendingIntent mDeliveryIntent; - - SmsTracker(HashMap data, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - mData = data; - mSentIntent = sentIntent; - mDeliveryIntent = deliveryIntent; - mRetryCount = 0; - } - - } - - private DialogInterface.OnClickListener mListener = - new DialogInterface.OnClickListener() { - - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - Log.d(TAG, "click YES to send out sms"); - sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS)); - } - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java deleted file mode 100644 index 995173b..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/ServiceStateTracker.java +++ /dev/null @@ -1,1468 +0,0 @@ -/* - * Copyright (C) 2006 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 static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ALPHA; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_ALPHA; -import static com.android.internal.telephony.TelephonyProperties.PROPERTY_SIM_OPERATOR_NUMERIC; -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.gsm.DataConnectionTracker.State; - -import android.app.AlarmManager; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.database.ContentObserver; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.PowerManager; -import android.os.Registrant; -import android.os.RegistrantList; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.provider.Checkin; -import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; -import android.provider.Telephony.Intents; -import android.telephony.gsm.GsmCellLocation; -import android.telephony.ServiceState; -import android.text.TextUtils; -import android.util.Config; -import android.util.Log; -import android.util.TimeUtils; -import android.util.EventLog; - -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -/** - * {@hide} - */ -final class ServiceStateTracker extends Handler -{ - /** - * The access technology currently in use: - * 0 = unknown - * 1 = GPRS only - * 2 = EDGE - * 3 = UMTS - */ - static final int DATA_ACCESS_UNKNOWN = 0; - static final int DATA_ACCESS_GPRS = 1; - static final int DATA_ACCESS_EDGE = 2; - static final int DATA_ACCESS_UMTS = 3; - - static final int MAX_NUM_DATA_STATE_READS = 15; - static final int DATA_STATE_POLL_SLEEP_MS = 100; - - //***** Instance Variables - - GSMPhone phone; - CommandsInterface cm; - - ServiceState ss; - ServiceState newSS; - GsmCellLocation cellLoc; - GsmCellLocation newCellLoc; - int mPreferredNetworkType; - - int rssi = 99; // signal strength 0-31, 99=unknown - // That's "received signal strength indication" fyi - - int[] pollingContext; // Used as a unique identifier to - // track requests associated with a poll - // and ignore stale responses. - // The value is a count-down of expected responses - // in this pollingContext - - boolean mDesiredPowerState; - - boolean dontPollSignalStrength = false; // Default is to poll strength - // If we're getting unsolicited signal strength updates from the radio, - // set value to true and don't bother polling any more - - private int gprsState = ServiceState.STATE_OUT_OF_SERVICE; - private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE; - - /** - * The access technology currently in use: DATA_ACCESS_ - */ - private int networkType = 0; - private int newNetworkType = 0; - /* gsm roaming status solely based on TS 27.007 7.2 CREG */ - private boolean mGsmRoaming = false; - - private RegistrantList networkAttachedRegistrants = new RegistrantList(); - private RegistrantList gprsAttachedRegistrants = new RegistrantList(); - private RegistrantList gprsDetachedRegistrants = new RegistrantList(); - private RegistrantList roamingOnRegistrants = new RegistrantList(); - private RegistrantList roamingOffRegistrants = new RegistrantList(); - - // Sometimes we get the NITZ time before we know what country we are in. - // Keep the time zone information from the NITZ string so we can fix - // the time zone once know the country. - private boolean mNeedFixZone = false; - private int mZoneOffset; - private boolean mZoneDst; - private long mZoneTime; - private boolean mGotCountryCode = false; - - String mSavedTimeZone; - long mSavedTime; - long mSavedAtTime; - - // We can't register for SIM_RECORDS_LOADED immediately because the - // SIMRecords object may not be instantiated yet. - private boolean mNeedToRegForSimLoaded; - - // Started the recheck process after finding gprs should registerd but not - private boolean mStartedGprsRegCheck = false; - // Already sent the event-log for no gprs register - private boolean mReportedGprsNoReg = false; - - // Wake lock used while setting time of day. - private PowerManager.WakeLock mWakeLock; - private static final String WAKELOCK_TAG = "ServiceStateTracker"; - - // Keep track of SPN display rules, so we only broadcast intent if something changes. - private String curSpn = null; - private String curPlmn = null; - private int curSpnRule = 0; - - //***** Constants - - static final boolean DBG = true; - static final String LOG_TAG = "GSM"; - - // signal strength poll rate - static final int POLL_PERIOD_MILLIS = 20 * 1000; - - // waiting period before recheck gprs and voice registration - static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000; - - //***** Events - static final int EVENT_RADIO_STATE_CHANGED = 1; - static final int EVENT_NETWORK_STATE_CHANGED = 2; - static final int EVENT_GET_SIGNAL_STRENGTH = 3; - static final int EVENT_POLL_STATE_REGISTRATION = 4; - static final int EVENT_POLL_STATE_GPRS = 5; - static final int EVENT_POLL_STATE_OPERATOR = 6; - static final int EVENT_POLL_SIGNAL_STRENGTH = 10; - static final int EVENT_NITZ_TIME = 11; - static final int EVENT_SIGNAL_STRENGTH_UPDATE = 12; - static final int EVENT_RADIO_AVAILABLE = 13; - static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE = 14; - static final int EVENT_GET_LOC_DONE = 15; - static final int EVENT_SIM_RECORDS_LOADED = 16; - static final int EVENT_SIM_READY = 17; - static final int EVENT_LOCATION_UPDATES_ENABLED = 18; - static final int EVENT_GET_PREFERRED_NETWORK_TYPE = 19; - static final int EVENT_SET_PREFERRED_NETWORK_TYPE = 20; - static final int EVENT_RESET_PREFERRED_NETWORK_TYPE = 21; - static final int EVENT_CHECK_REPORT_GPRS = 22; - - //***** Time Zones - - private static final String TIMEZONE_PROPERTY = "persist.sys.timezone"; - - // List of ISO codes for countries that can have an offset of GMT+0 - // when not in daylight savings time. This ignores some small places - // such as the Canary Islands (Spain) and Danmarkshavn (Denmark). - // The list must be sorted by code. - private static final String[] GMT_COUNTRY_CODES = { - "bf", // Burkina Faso - "ci", // Cote d'Ivoire - "eh", // Western Sahara - "fo", // Faroe Islands, Denmark - "gh", // Ghana - "gm", // Gambia - "gn", // Guinea - "gw", // Guinea Bissau - "ie", // Ireland - "lr", // Liberia - "is", // Iceland - "ma", // Morocco - "ml", // Mali - "mr", // Mauritania - "pt", // Portugal - "sl", // Sierra Leone - "sn", // Senegal - "st", // Sao Tome and Principe - "tg", // Togo - "uk", // U.K - }; - - private ContentObserver mAutoTimeObserver = new ContentObserver(new Handler()) { - @Override - public void onChange(boolean selfChange) { - Log.i("ServiceStateTracker", "Auto time state changed"); - revertToNitz(); - } - }; - - - //***** Constructors - - ServiceStateTracker(GSMPhone phone) - { - this.phone = phone; - cm = phone.mCM; - ss = new ServiceState(); - newSS = new ServiceState(); - cellLoc = new GsmCellLocation(); - newCellLoc = new GsmCellLocation(); - - PowerManager powerManager = - (PowerManager)phone.getContext().getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); - - cm.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); - cm.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); - - cm.registerForNetworkStateChanged(this, EVENT_NETWORK_STATE_CHANGED, null); - cm.setOnNITZTime(this, EVENT_NITZ_TIME, null); - cm.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null); - - cm.registerForSIMReady(this, EVENT_SIM_READY, null); - - // system setting property AIRPLANE_MODE_ON is set in Settings. - int airplaneMode = Settings.System.getInt( - phone.getContext().getContentResolver(), - Settings.System.AIRPLANE_MODE_ON, 0); - mDesiredPowerState = ! (airplaneMode > 0); - - ContentResolver cr = phone.getContext().getContentResolver(); - cr.registerContentObserver( - Settings.System.getUriFor(Settings.System.AUTO_TIME), true, - mAutoTimeObserver); - setRssiDefaultValues(); - mNeedToRegForSimLoaded = true; - } - - /** - * Registration point for transition into GPRS attached. - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - /*protected*/ void - registerForGprsAttached(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - gprsAttachedRegistrants.add(r); - - if (gprsState == ServiceState.STATE_IN_SERVICE) { - r.notifyRegistrant(); - } - } - - void registerForNetworkAttach(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - networkAttachedRegistrants.add(r); - - if (ss.getState() == ServiceState.STATE_IN_SERVICE) { - r.notifyRegistrant(); - } - } - /** - * Registration point for transition into GPRS detached. - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - /*protected*/ void - registerForGprsDetached(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - gprsDetachedRegistrants.add(r); - - if (gprsState == ServiceState.STATE_OUT_OF_SERVICE) { - r.notifyRegistrant(); - } - } - - /** - * Registration point for combined roaming on - * combined roaming is true when roaming is true and ONS differs SPN - * - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - void registerForRoamingOn(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - roamingOnRegistrants.add(r); - - if (ss.getRoaming()) { - r.notifyRegistrant(); - } - } - - /** - * Registration point for combined roaming off - * combined roaming is true when roaming is true and ONS differs SPN - * - * @param h handler to notify - * @param what what code of message when delivered - * @param obj placed in Message.obj - */ - void registerForRoamingOff(Handler h, int what, Object obj) { - Registrant r = new Registrant(h, what, obj); - roamingOffRegistrants.add(r); - - if (!ss.getRoaming()) { - r.notifyRegistrant(); - } - } - - /** - * Reregister network through toggle perferred network type - * This is a work aorund to deregister and register network since there is - * no ril api to set COPS=2 (deregister) only. - * - * @param onComplete is dispatched when this is complete. it will be - * an AsyncResult, and onComplete.obj.exception will be non-null - * on failure. - */ - void reRegisterNetwork(Message onComplete) { - cm.getPreferredNetworkType( - obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete)); - } - - //***** Called from GSMPhone - - public void - setRadioPower(boolean power) - { - mDesiredPowerState = power; - - setPowerStateToDesired(); - } - - public void - getLacAndCid(Message onComplete) { - cm.getRegistrationState(obtainMessage( - EVENT_GET_LOC_DONE, onComplete)); - } - - /*package*/ void enableLocationUpdates() { - cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED)); - } - - /*package*/ void disableLocationUpdates() { - cm.setLocationUpdates(false, null); - } - //***** Overridden from Handler - - public void - handleMessage (Message msg) - { - AsyncResult ar; - int[] ints; - String[] strings; - Message message; - - switch (msg.what) { - case EVENT_RADIO_AVAILABLE: - //this is unnecessary - //setPowerStateToDesired(); - break; - - case EVENT_SIM_READY: - // The SIM is now ready i.e if it was locked - // it has been unlocked. At this stage, the radio is already - // powered on. - if (mNeedToRegForSimLoaded) { - phone.mSIMRecords.registerForRecordsLoaded(this, - EVENT_SIM_RECORDS_LOADED, null); - mNeedToRegForSimLoaded = false; - } - // restore the previous network selection. - phone.restoreSavedNetworkSelection(null); - pollState(); - // Signal strength polling stops when radio is off - queueNextSignalStrengthPoll(); - break; - - case EVENT_RADIO_STATE_CHANGED: - // This will do nothing in the radio not - // available case - setPowerStateToDesired(); - pollState(); - break; - - case EVENT_NETWORK_STATE_CHANGED: - pollState(); - break; - - case EVENT_GET_SIGNAL_STRENGTH: - // This callback is called when signal strength is polled - // all by itself - - if (!(cm.getRadioState().isOn())) { - // Polling will continue when radio turns back on - return; - } - ar = (AsyncResult) msg.obj; - onSignalStrengthResult(ar); - queueNextSignalStrengthPoll(); - - break; - - case EVENT_GET_LOC_DONE: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - String states[] = (String[])ar.result; - int lac = -1; - int cid = -1; - if (states.length == 3) { - try { - if (states[1] != null && states[1].length() > 0) { - lac = Integer.parseInt(states[1], 16); - } - if (states[2] != null && states[2].length() > 0) { - cid = Integer.parseInt(states[2], 16); - } - } catch (NumberFormatException ex) { - Log.w(LOG_TAG, "error parsing location: " + ex); - } - } - - // only update if lac or cid changed - if (cellLoc.getCid() != cid || cellLoc.getLac() != lac) { - cellLoc.setLacAndCid(lac, cid); - phone.notifyLocationChanged(); - } - } - - if (ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - break; - - case EVENT_POLL_STATE_REGISTRATION: - case EVENT_POLL_STATE_GPRS: - case EVENT_POLL_STATE_OPERATOR: - case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: - ar = (AsyncResult) msg.obj; - - handlePollStateResult(msg.what, ar); - break; - - case EVENT_POLL_SIGNAL_STRENGTH: - // Just poll signal strength...not part of pollState() - - cm.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH)); - break; - - case EVENT_NITZ_TIME: - ar = (AsyncResult) msg.obj; - - String nitzString = (String)((Object[])ar.result)[0]; - long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue(); - - setTimeFromNITZString(nitzString, nitzReceiveTime); - break; - - case EVENT_SIGNAL_STRENGTH_UPDATE: - // This is a notification from - // CommandsInterface.setOnSignalStrengthUpdate - - ar = (AsyncResult) msg.obj; - - // The radio is telling us about signal strength changes - // we don't have to ask it - dontPollSignalStrength = true; - - onSignalStrengthResult(ar); - break; - - case EVENT_SIM_RECORDS_LOADED: - updateSpnDisplay(); - break; - - case EVENT_LOCATION_UPDATES_ENABLED: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - getLacAndCid(null); - } - break; - - case EVENT_SET_PREFERRED_NETWORK_TYPE: - ar = (AsyncResult) msg.obj; - // Don't care the result, only use for dereg network (COPS=2) - message = obtainMessage(EVENT_RESET_PREFERRED_NETWORK_TYPE, ar.userObj); - cm.setPreferredNetworkType(mPreferredNetworkType, message); - break; - - case EVENT_RESET_PREFERRED_NETWORK_TYPE: - ar = (AsyncResult) msg.obj; - if (ar.userObj != null) { - AsyncResult.forMessage(((Message) ar.userObj)).exception - = ar.exception; - ((Message) ar.userObj).sendToTarget(); - } - break; - - case EVENT_GET_PREFERRED_NETWORK_TYPE: - ar = (AsyncResult) msg.obj; - - if (ar.exception == null) { - mPreferredNetworkType = ((int[])ar.result)[0]; - } else { - mPreferredNetworkType = Phone.NT_AUTO_TYPE; - } - - message = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE, ar.userObj); - int toggledNetworkType = - (mPreferredNetworkType == Phone.NT_AUTO_TYPE) ? - Phone.NT_GSM_TYPE : Phone.NT_AUTO_TYPE; - - cm.setPreferredNetworkType(toggledNetworkType, message); - break; - - case EVENT_CHECK_REPORT_GPRS: - if (ss != null && !isGprsConsistant(gprsState, ss.getState())) { - - // Can't register data sevice while voice service is ok - // i.e. CREG is ok while CGREG is not - // possible a network or baseband side error - int cid = -1; - GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation()); - if (loc != null) cid = loc.getCid(); - - EventLog.List val = new EventLog.List(ss.getOperatorNumeric(), cid); - EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_CGREG_FAIL, val); - mReportedGprsNoReg = true; - } - mStartedGprsRegCheck = false; - break; - - } - } - - //***** Private Instance Methods - - private void updateSpnDisplay() { - int rule = phone.mSIMRecords.getDisplayRule(ss.getOperatorNumeric()); - String spn = phone.mSIMRecords.getServiceProvideName(); - String plmn = ss.getOperatorAlphaLong(); - - if (rule != curSpnRule - || !TextUtils.equals(spn, curSpn) - || !TextUtils.equals(plmn, curPlmn)) { - boolean showSpn = - (rule & SIMRecords.SPN_RULE_SHOW_SPN) == SIMRecords.SPN_RULE_SHOW_SPN; - boolean showPlmn = - (rule & SIMRecords.SPN_RULE_SHOW_PLMN) == SIMRecords.SPN_RULE_SHOW_PLMN; - Intent intent = new Intent(Intents.SPN_STRINGS_UPDATED_ACTION); - intent.putExtra(Intents.EXTRA_SHOW_SPN, showSpn); - intent.putExtra(Intents.EXTRA_SPN, spn); - intent.putExtra(Intents.EXTRA_SHOW_PLMN, showPlmn); - intent.putExtra(Intents.EXTRA_PLMN, plmn); - phone.getContext().sendStickyBroadcast(intent); - } - curSpnRule = rule; - curSpn = spn; - curPlmn = plmn; - } - - private void - setPowerStateToDesired() - { - // If we want it on and it's off, turn it on - if (mDesiredPowerState - && cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF - ) { - cm.setRadioPower(true, null); - } else if (!mDesiredPowerState && cm.getRadioState().isOn()) { - DataConnectionTracker dcTracker = phone.mDataConnection; - if (! dcTracker.isDataConnectionAsDesired()) { - - EventLog.List val = new EventLog.List( - dcTracker.getStateInString(), - (dcTracker.getAnyDataEnabled() ? 1 : 0) ); - EventLog.writeEvent(TelephonyEventLog.EVENT_DATA_STATE_RADIO_OFF, val); - } - dcTracker.cleanConnectionBeforeRadioOff(); - - // poll data state up to 15 times, with a 100ms delay - // totaling 1.5 sec. Normal data disable action will finish in 100ms. - for (int i = 0; i < MAX_NUM_DATA_STATE_READS; i++) { - if (dcTracker.state != State.CONNECTED - && dcTracker.state != State.DISCONNECTING) { - Log.d(LOG_TAG, "Data shutdown complete."); - break; - } - SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS); - } - // If it's on and available and we want it off.. - cm.setRadioPower(false, null); - } // Otherwise, we're in the desired state - } - - /** Cancel a pending (if any) pollState() operation */ - private void - cancelPollState() - { - // This will effectively cancel the rest of the poll requests - pollingContext = new int[1]; - } - - /** - * Handle the result of one of the pollState()-related requests - */ - - private void - handlePollStateResult (int what, AsyncResult ar) - { - int ints[]; - String states[]; - - // Ignore stale requests from last poll - if (ar.userObj != pollingContext) return; - - if (ar.exception != null) { - CommandException.Error err=null; - - if (ar.exception instanceof CommandException) { - err = ((CommandException)(ar.exception)).getCommandError(); - } - - if (err == CommandException.Error.RADIO_NOT_AVAILABLE) { - // Radio has crashed or turned off - cancelPollState(); - return; - } - - if (!cm.getRadioState().isOn()) { - // Radio has crashed or turned off - cancelPollState(); - return; - } - - if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW && - err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) { - Log.e(LOG_TAG, - "RIL implementation has returned an error where it must succeed" + - ar.exception); - } - } else try { - switch (what) { - case EVENT_POLL_STATE_REGISTRATION: - states = (String[])ar.result; - int lac = -1; - int cid = -1; - int regState = -1; - if (states.length > 0) { - try { - regState = Integer.parseInt(states[0]); - if (states.length == 3) { - if (states[1] != null && states[1].length() > 0) { - lac = Integer.parseInt(states[1], 16); - } - if (states[2] != null && states[2].length() > 0) { - cid = Integer.parseInt(states[2], 16); - } - } - } catch (NumberFormatException ex) { - Log.w(LOG_TAG, "error parsing RegistrationState: " + ex); - } - } - - mGsmRoaming = regCodeIsRoaming(regState); - newSS.setState (regCodeToServiceState(regState)); - - // LAC and CID are -1 if not avail - newCellLoc.setLacAndCid(lac, cid); - break; - - case EVENT_POLL_STATE_GPRS: - states = (String[])ar.result; - - int type = 0; - regState = -1; - if (states.length > 0) { - try { - regState = Integer.parseInt(states[0]); - - // states[3] (if present) is the current radio technology - if (states.length >= 4 && states[3] != null) { - type = Integer.parseInt(states[3]); - } - } catch (NumberFormatException ex) { - Log.w(LOG_TAG, "error parsing GprsRegistrationState: " + ex); - } - } - newGPRSState = regCodeToServiceState(regState); - newNetworkType = type; - break; - - case EVENT_POLL_STATE_OPERATOR: - String opNames[] = (String[])ar.result; - - if (opNames != null && opNames.length >= 3) { - newSS.setOperatorName ( - opNames[0], opNames[1], opNames[2]); - } - break; - - case EVENT_POLL_STATE_NETWORK_SELECTION_MODE: - ints = (int[])ar.result; - newSS.setIsManualSelection(ints[0] == 1); - break; - } - - } catch (RuntimeException ex) { - Log.e(LOG_TAG, "Exception while polling service state. " - + "Probably malformed RIL response.", ex); - } - - pollingContext[0]--; - - if (pollingContext[0] == 0) { - newSS.setRoaming(isRoamingBetweenOperators(mGsmRoaming, newSS)); - pollStateDone(); - } - - } - - private void - setRssiDefaultValues() - { - rssi = 99; - } - - /** - * A complete "service state" from our perspective is - * composed of a handful of separate requests to the radio. - * - * We make all of these requests at once, but then abandon them - * and start over again if the radio notifies us that some - * event has changed - */ - - private void - pollState() - { - pollingContext = new int[1]; - pollingContext[0] = 0; - - switch (cm.getRadioState()) { - case RADIO_UNAVAILABLE: - newSS.setStateOutOfService(); - newCellLoc.setStateInvalid(); - setRssiDefaultValues(); - mGotCountryCode = false; - - pollStateDone(); - break; - - - case RADIO_OFF: - newSS.setStateOff(); - newCellLoc.setStateInvalid(); - setRssiDefaultValues(); - mGotCountryCode = false; - - pollStateDone(); - break; - - default: - // Issue all poll-related commands at once - // then count down the responses, which - // are allowed to arrive out-of-order - - pollingContext[0]++; - cm.getOperator( - obtainMessage( - EVENT_POLL_STATE_OPERATOR, pollingContext)); - - pollingContext[0]++; - cm.getGPRSRegistrationState( - obtainMessage( - EVENT_POLL_STATE_GPRS, pollingContext)); - - pollingContext[0]++; - cm.getRegistrationState( - obtainMessage( - EVENT_POLL_STATE_REGISTRATION, pollingContext)); - - pollingContext[0]++; - cm.getNetworkSelectionMode( - obtainMessage( - EVENT_POLL_STATE_NETWORK_SELECTION_MODE, pollingContext)); - break; - } - } - - private static String networkTypeToString(int type) { - String ret = "unknown"; - - switch (type) { - case DATA_ACCESS_GPRS: - ret = "GPRS"; - break; - case DATA_ACCESS_EDGE: - ret = "EDGE"; - break; - case DATA_ACCESS_UMTS: - ret = "UMTS"; - break; - } - - return ret; - } - - private void - pollStateDone() - { - if (DBG) { - Log.d(LOG_TAG, "Poll ServiceState done: " + - " oldSS=[" + ss + "] newSS=[" + newSS + - "] oldGprs=" + gprsState + " newGprs=" + newGPRSState + - " oldType=" + networkTypeToString(networkType) + - " newType=" + networkTypeToString(newNetworkType)); - } - - boolean hasRegistered = - ss.getState() != ServiceState.STATE_IN_SERVICE - && newSS.getState() == ServiceState.STATE_IN_SERVICE; - - boolean hasDeregistered = - ss.getState() == ServiceState.STATE_IN_SERVICE - && newSS.getState() != ServiceState.STATE_IN_SERVICE; - - boolean hasGprsAttached = - gprsState != ServiceState.STATE_IN_SERVICE - && newGPRSState == ServiceState.STATE_IN_SERVICE; - - boolean hasGprsDetached = - gprsState == ServiceState.STATE_IN_SERVICE - && newGPRSState != ServiceState.STATE_IN_SERVICE; - - boolean hasNetworkTypeChanged = networkType != newNetworkType; - - boolean hasChanged = !newSS.equals(ss); - - boolean hasRoamingOn = !ss.getRoaming() && newSS.getRoaming(); - - boolean hasRoamingOff = ss.getRoaming() && !newSS.getRoaming(); - - boolean hasLocationChanged = !newCellLoc.equals(cellLoc); - - ServiceState tss; - tss = ss; - ss = newSS; - newSS = tss; - // clean slate for next time - newSS.setStateOutOfService(); - - GsmCellLocation tcl = cellLoc; - cellLoc = newCellLoc; - newCellLoc = tcl; - - gprsState = newGPRSState; - networkType = newNetworkType; - - newSS.setStateOutOfService(); // clean slate for next time - - if (hasNetworkTypeChanged) { - phone.setSystemProperty(PROPERTY_DATA_NETWORK_TYPE, - networkTypeToString(networkType)); - } - - if (hasRegistered) { - Checkin.updateStats(phone.getContext().getContentResolver(), - Checkin.Stats.Tag.PHONE_GSM_REGISTERED, 1, 0.0); - networkAttachedRegistrants.notifyRegistrants(); - } - - if (hasChanged) { - String operatorNumeric; - - phone.setSystemProperty(PROPERTY_OPERATOR_ALPHA, - ss.getOperatorAlphaLong()); - - operatorNumeric = ss.getOperatorNumeric(); - phone.setSystemProperty(PROPERTY_OPERATOR_NUMERIC, operatorNumeric); - - if (operatorNumeric == null) { - phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, ""); - } else { - String iso = ""; - try{ - iso = MccTable.countryCodeForMcc(Integer.parseInt( - operatorNumeric.substring(0,3))); - } catch ( NumberFormatException ex){ - Log.w(LOG_TAG, "countryCodeForMcc error" + ex); - } catch ( StringIndexOutOfBoundsException ex) { - Log.w(LOG_TAG, "countryCodeForMcc error" + ex); - } - - phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, iso); - mGotCountryCode = true; - - if (mNeedFixZone) { - TimeZone zone = null; - // If the offset is (0, false) and the timezone property - // is set, use the timezone property rather than - // GMT. - String zoneName = SystemProperties.get(TIMEZONE_PROPERTY); - if ((mZoneOffset == 0) && (mZoneDst == false) && - (zoneName != null) && (zoneName.length() > 0) && - (Arrays.binarySearch(GMT_COUNTRY_CODES, iso) < 0)) { - zone = TimeZone.getDefault(); - // For NITZ string without timezone, - // need adjust time to reflect default timezone setting - long tzOffset; - tzOffset = zone.getOffset(System.currentTimeMillis()); - if (getAutoTime()) { - setAndBroadcastNetworkSetTime(System.currentTimeMillis() - tzOffset); - } else { - // Adjust the saved NITZ time to account for tzOffset. - mSavedTime = mSavedTime - tzOffset; - } - } else if (iso.equals("")){ - // Country code not found. This is likely a test network. - // Get a TimeZone based only on the NITZ parameters (best guess). - zone = getNitzTimeZone(mZoneOffset, mZoneDst, mZoneTime); - } else { - zone = TimeUtils.getTimeZone(mZoneOffset, - mZoneDst, mZoneTime, iso); - } - - mNeedFixZone = false; - - if (zone != null) { - if (getAutoTime()) { - setAndBroadcastNetworkSetTimeZone(zone.getID()); - } - saveNitzTimeZone(zone.getID()); - } - } - } - - phone.setSystemProperty(PROPERTY_OPERATOR_ISROAMING, - ss.getRoaming() ? "true" : "false"); - - updateSpnDisplay(); - phone.notifyServiceStateChanged(ss); - } - - if (hasGprsAttached) { - gprsAttachedRegistrants.notifyRegistrants(); - } - - if (hasGprsDetached) { - gprsDetachedRegistrants.notifyRegistrants(); - } - - if (hasNetworkTypeChanged) { - phone.notifyDataConnection(null); - } - - if (hasRoamingOn) { - roamingOnRegistrants.notifyRegistrants(); - } - - if (hasRoamingOff) { - roamingOffRegistrants.notifyRegistrants(); - } - - if (hasLocationChanged) { - phone.notifyLocationChanged(); - } - - if (! isGprsConsistant(gprsState, ss.getState())) { - if (!mStartedGprsRegCheck && !mReportedGprsNoReg) { - mStartedGprsRegCheck = true; - - int check_period = Settings.Gservices.getInt( - phone.getContext().getContentResolver(), - Settings.Gservices.GPRS_REGISTER_CHECK_PERIOD_MS, - DEFAULT_GPRS_CHECK_PERIOD_MILLIS); - sendMessageDelayed(obtainMessage(EVENT_CHECK_REPORT_GPRS), - check_period); - } - } else { - mReportedGprsNoReg = false; - } - } - - /** - * Check if GPRS got registred while voice is registered - * - * @param gprsState for GPRS registration state, i.e. CGREG in GSM - * @param serviceState for voice registration state, i.e. CREG in GSM - * @return false if device only register to voice but not gprs - */ - private boolean isGprsConsistant (int gprsState, int serviceState) { - return !((serviceState == ServiceState.STATE_IN_SERVICE) && - (gprsState != ServiceState.STATE_IN_SERVICE)); - } - - /** - * Returns a TimeZone object based only on parameters from the NITZ string. - */ - private TimeZone getNitzTimeZone(int offset, boolean dst, long when) { - TimeZone guess = findTimeZone(offset, dst, when); - if (guess == null) { - // Couldn't find a proper timezone. Perhaps the DST data is wrong. - guess = findTimeZone(offset, !dst, when); - } - if (DBG) { - Log.d(LOG_TAG, "getNitzTimeZone returning " - + (guess == null ? guess : guess.getID())); - } - return guess; - } - - private TimeZone findTimeZone(int offset, boolean dst, long when) { - int rawOffset = offset; - if (dst) { - rawOffset -= 3600000; - } - String[] zones = TimeZone.getAvailableIDs(rawOffset); - TimeZone guess = null; - Date d = new Date(when); - for (String zone : zones) { - TimeZone tz = TimeZone.getTimeZone(zone); - if (tz.getOffset(when) == offset && - tz.inDaylightTime(d) == dst) { - guess = tz; - break; - } - } - - return guess; - } - - private void - queueNextSignalStrengthPoll() - { - if (dontPollSignalStrength) { - // The radio is telling us about signal strength changes - // we don't have to ask it - return; - } - - Message msg; - - msg = obtainMessage(); - msg.what = EVENT_POLL_SIGNAL_STRENGTH; - - long nextTime; - - // TODO Done't poll signal strength if screen is off - sendMessageDelayed(msg, POLL_PERIOD_MILLIS); - } - - /** - * send signal-strength-changed notification if rssi changed - * Called both for solicited and unsolicited signal stength updates - */ - private void - onSignalStrengthResult(AsyncResult ar) - { - int oldRSSI = rssi; - - if (ar.exception != null) { - // 99 = unknown - // most likely radio is resetting/disconnected - rssi = 99; - } else { - int[] ints = (int[])ar.result; - - // bug 658816 seems to be a case where the result is 0-length - if (ints.length != 0) { - rssi = ints[0]; - } else { - Log.e(LOG_TAG, "Bogus signal strength response"); - rssi = 99; - } - } - - if (rssi != oldRSSI) { - phone.notifySignalStrength(); - } - } - - /** code is registration state 0-5 from TS 27.007 7.2 */ - private int - regCodeToServiceState(int code) - { - switch (code) { - case 0: - case 2: // 2 is "searching" - case 3: // 3 is "registration denied" - case 4: // 4 is "unknown" no vaild in current baseband - return ServiceState.STATE_OUT_OF_SERVICE; - - case 1: - return ServiceState.STATE_IN_SERVICE; - - case 5: - // in service, roam - return ServiceState.STATE_IN_SERVICE; - - default: - Log.w(LOG_TAG, "unexpected service state " + code); - return ServiceState.STATE_OUT_OF_SERVICE; - } - } - - - /** - * code is registration state 0-5 from TS 27.007 7.2 - * returns true if registered roam, false otherwise - */ - private boolean - regCodeIsRoaming (int code) - { - // 5 is "in service -- roam" - return 5 == code; - } - - /** - * Set roaming state when gsmRoaming is true and, if operator mcc is the - * same as sim mcc, ons is different from spn - * @param gsmRoaming TS 27.007 7.2 CREG registered roaming - * @param s ServiceState hold current ons - * @return true for roaming state set - */ - private - boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) { - String spn = SystemProperties.get(PROPERTY_SIM_OPERATOR_ALPHA, "empty"); - - String onsl = s.getOperatorAlphaLong(); - String onss = s.getOperatorAlphaShort(); - - boolean equalsOnsl = onsl != null && spn.equals(onsl); - boolean equalsOnss = onss != null && spn.equals(onss); - - String simNumeric = SystemProperties.get(PROPERTY_SIM_OPERATOR_NUMERIC, ""); - String operatorNumeric = s.getOperatorNumeric(); - - boolean equalsMcc = true; - try { - equalsMcc = simNumeric.substring(0, 3). - equals(operatorNumeric.substring(0, 3)); - } catch (Exception e){ - } - - return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss)); - } - - private static - int twoDigitsAt(String s, int offset) - { - int a, b; - - a = Character.digit(s.charAt(offset), 10); - b = Character.digit(s.charAt(offset+1), 10); - - if (a < 0 || b < 0) { - - throw new RuntimeException("invalid format"); - } - - return a*10 + b; - } - - /** - * @return The current GPRS state. IN_SERVICE is the same as "attached" - * and OUT_OF_SERVICE is the same as detached. - */ - /*package*/ int getCurrentGprsState() { - return gprsState; - } - - /** - * @return true if phone is camping on a technology (eg UMTS) - * that could support voice and data simultaniously. - */ - boolean isConcurrentVoiceAndData() { - return (networkType == DATA_ACCESS_UMTS); - } - - /** - * Provides the name of the algorithmic time zone for the specified - * offset. Taken from TimeZone.java. - */ - private static String displayNameFor(int off) { - off = off / 1000 / 60; - - char[] buf = new char[9]; - buf[0] = 'G'; - buf[1] = 'M'; - buf[2] = 'T'; - - if (off < 0) { - buf[3] = '-'; - off = -off; - } else { - buf[3] = '+'; - } - - int hours = off / 60; - int minutes = off % 60; - - buf[4] = (char) ('0' + hours / 10); - buf[5] = (char) ('0' + hours % 10); - - buf[6] = ':'; - - buf[7] = (char) ('0' + minutes / 10); - buf[8] = (char) ('0' + minutes % 10); - - return new String(buf); - } - - /** - * nitzReceiveTime is time_t that the NITZ time was posted - */ - - private - void setTimeFromNITZString (String nitz, long nitzReceiveTime) - { - // "yy/mm/dd,hh:mm:ss(+/-)tz" - // tz is in number of quarter-hours - - long start = SystemClock.elapsedRealtime(); - Log.i(LOG_TAG, "NITZ: " + nitz + "," + nitzReceiveTime + - " start=" + start + " delay=" + (start - nitzReceiveTime)); - - try { - /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone - * offset as well (which we won't worry about until later) */ - Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - - c.clear(); - c.set(Calendar.DST_OFFSET, 0); - - String[] nitzSubs = nitz.split("[/:,+-]"); - - int year = 2000 + Integer.parseInt(nitzSubs[0]); - c.set(Calendar.YEAR, year); - - // month is 0 based! - int month = Integer.parseInt(nitzSubs[1]) - 1; - c.set(Calendar.MONTH, month); - - int date = Integer.parseInt(nitzSubs[2]); - c.set(Calendar.DATE, date); - - int hour = Integer.parseInt(nitzSubs[3]); - c.set(Calendar.HOUR, hour); - - int minute = Integer.parseInt(nitzSubs[4]); - c.set(Calendar.MINUTE, minute); - - int second = Integer.parseInt(nitzSubs[5]); - c.set(Calendar.SECOND, second); - - boolean sign = (nitz.indexOf('-') == -1); - - int tzOffset = Integer.parseInt(nitzSubs[6]); - - int dst = (nitzSubs.length >= 8 ) ? Integer.parseInt(nitzSubs[7]) - : 0; - - // The zone offset received from NITZ is for current local time, - // so DST correction is already applied. Don't add it again. - // - // tzOffset += dst * 4; - // - // We could unapply it if we wanted the raw offset. - - tzOffset = (sign ? 1 : -1) * tzOffset * 15 * 60 * 1000; - - TimeZone zone = null; - - // As a special extension, the Android emulator appends the name of - // the host computer's timezone to the nitz string. this is zoneinfo - // timezone name of the form Area!Location or Area!Location!SubLocation - // so we need to convert the ! into / - if (nitzSubs.length >= 9) { - String tzname = nitzSubs[8].replace('!','/'); - zone = TimeZone.getTimeZone( tzname ); - } - - String iso = SystemProperties.get(PROPERTY_OPERATOR_ISO_COUNTRY); - - if (zone == null) { - - if (mGotCountryCode) { - if (iso != null && iso.length() > 0) { - zone = TimeUtils.getTimeZone(tzOffset, dst != 0, - c.getTimeInMillis(), - iso); - } else { - // We don't have a valid iso country code. This is - // most likely because we're on a test network that's - // using a bogus MCC (eg, "001"), so get a TimeZone - // based only on the NITZ parameters. - zone = getNitzTimeZone(tzOffset, (dst != 0), c.getTimeInMillis()); - } - } - } - - if (zone == null) { - // We got the time before the country, so we don't know - // how to identify the DST rules yet. Save the information - // and hope to fix it up later. - - mNeedFixZone = true; - mZoneOffset = tzOffset; - mZoneDst = dst != 0; - mZoneTime = c.getTimeInMillis(); - } - - if (zone != null) { - if (getAutoTime()) { - setAndBroadcastNetworkSetTimeZone(zone.getID()); - } - saveNitzTimeZone(zone.getID()); - } - - String ignore = SystemProperties.get("gsm.ignore-nitz"); - if (ignore != null && ignore.equals("yes")) { - Log.i(LOG_TAG, "NITZ: Not setting clock because gsm.ignore-nitz is set"); - return; - } - - try { - mWakeLock.acquire(); - - if (getAutoTime()) { - long millisSinceNitzReceived - = SystemClock.elapsedRealtime() - nitzReceiveTime; - - if (millisSinceNitzReceived < 0) { - // Sanity check: something is wrong - Log.i(LOG_TAG, "NITZ: not setting time, clock has rolled " - + "backwards since NITZ time was received, " - + nitz); - return; - } - - if (millisSinceNitzReceived > Integer.MAX_VALUE) { - // If the time is this far off, something is wrong > 24 days! - Log.i(LOG_TAG, "NITZ: not setting time, processing has taken " - + (millisSinceNitzReceived / (1000 * 60 * 60 * 24)) - + " days"); - return; - } - - // Note: with range checks above, cast to int is safe - c.add(Calendar.MILLISECOND, (int)millisSinceNitzReceived); - - Log.i(LOG_TAG, "NITZ: Setting time of day to " + c.getTime() - + " NITZ receive delay(ms): " + millisSinceNitzReceived - + " gained(ms): " - + (c.getTimeInMillis() - System.currentTimeMillis()) - + " from " + nitz); - - SystemClock.setCurrentTimeMillis(c.getTimeInMillis()); - Log.i(LOG_TAG, "NITZ: after Setting time of day"); - } - SystemProperties.set("gsm.nitz.time", String.valueOf(c.getTimeInMillis())); - saveNitzTime(c.getTimeInMillis()); - if (Config.LOGV) { - long end = SystemClock.elapsedRealtime(); - Log.v(LOG_TAG, "NITZ: end=" + end + " dur=" + (end - start)); - } - } finally { - mWakeLock.release(); - } - } catch (RuntimeException ex) { - Log.e(LOG_TAG, "NITZ: Parsing NITZ time " + nitz, ex); - } - } - - private boolean getAutoTime() { - try { - return Settings.System.getInt(phone.getContext().getContentResolver(), - Settings.System.AUTO_TIME) > 0; - } catch (SettingNotFoundException snfe) { - return true; - } - } - - private void saveNitzTimeZone(String zoneId) { - mSavedTimeZone = zoneId; - } - - private void saveNitzTime(long time) { - mSavedTime = time; - mSavedAtTime = SystemClock.elapsedRealtime(); - } - - /** - * Set the timezone and send out a sticky broadcast so the system can - * determine if the timezone was set by the carrier. - * - * @param zoneId timezone set by carrier - */ - private void setAndBroadcastNetworkSetTimeZone(String zoneId) { - AlarmManager alarm = - (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE); - alarm.setTimeZone(zoneId); - Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE); - intent.putExtra("time-zone", zoneId); - phone.getContext().sendStickyBroadcast(intent); - } - - /** - * Set the time and Send out a sticky broadcast so the system can determine - * if the time was set by the carrier. - * - * @param time time set by network - */ - private void setAndBroadcastNetworkSetTime(long time) { - SystemClock.setCurrentTimeMillis(time); - Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIME); - intent.putExtra("time", time); - phone.getContext().sendStickyBroadcast(intent); - } - - private void revertToNitz() { - if (Settings.System.getInt(phone.getContext().getContentResolver(), - Settings.System.AUTO_TIME, 0) == 0) { - return; - } - Log.d(LOG_TAG, "Reverting to NITZ: tz='" + mSavedTimeZone - + "' mSavedTime=" + mSavedTime - + " mSavedAtTime=" + mSavedAtTime); - if (mSavedTimeZone != null && mSavedTime != 0 && mSavedAtTime != 0) { - setAndBroadcastNetworkSetTimeZone(mSavedTimeZone); - setAndBroadcastNetworkSetTime(mSavedTime - + (SystemClock.elapsedRealtime() - mSavedAtTime)); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimConstants.java b/telephony/java/com/android/internal/telephony/gsm/SimConstants.java deleted file mode 100644 index a7e3bbc..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimConstants.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public interface SimConstants { - // SIM file ids from TS 51.011 - public static final int EF_ADN = 0x6F3A; - public static final int EF_FDN = 0x6F3B; - public static final int EF_SDN = 0x6F49; - public static final int EF_EXT1 = 0x6F4A; - public static final int EF_EXT2 = 0x6F4B; - public static final int EF_EXT3 = 0x6F4C; - public static final int EF_EXT6 = 0x6fc8; // Ext record for EF[MBDN] - public static final int EF_MWIS = 0x6FCA; - public static final int EF_MBDN = 0x6fc7; - public static final int EF_PNN = 0x6fc5; - public static final int EF_SPN = 0x6F46; - public static final int EF_SMS = 0x6F3C; - public static final int EF_ICCID = 0x2fe2; - public static final int EF_AD = 0x6FAD; - public static final int EF_MBI = 0x6fc9; - public static final int EF_MSISDN = 0x6f40; - public static final int EF_SPDI = 0x6fcd; - public static final int EF_SST = 0x6f38; - public static final int EF_CFIS = 0x6FCB; - public static final int EF_IMG = 0x4f20; - - // SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6 - public static final int EF_MAILBOX_CPHS = 0x6F17; - public static final int EF_VOICE_MAIL_INDICATOR_CPHS = 0x6F11; - public static final int EF_CFF_CPHS = 0x6F13; - public static final int EF_SPN_CPHS = 0x6f14; - public static final int EF_SPN_SHORT_CPHS = 0x6f18; - public static final int EF_INFO_CPHS = 0x6f16; - - // SMS record length from TS 51.011 10.5.3 - static public final int SMS_RECORD_LENGTH = 176; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimException.java b/telephony/java/com/android/internal/telephony/gsm/SimException.java deleted file mode 100644 index 1c0daba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimException.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class SimException extends Exception -{ - SimException() - { - - } - - SimException(String s) - { - super(s); - } -} - -final class SimVmFixedException extends SimException { - SimVmFixedException() - { - - } - - SimVmFixedException(String s) - { - super(s); - } -} - -final class SimVmNotSupportedException extends SimException { - SimVmNotSupportedException() - { - - } - - SimVmNotSupportedException(String s) - { - super(s); - } -} - diff --git a/telephony/java/com/android/internal/telephony/gsm/SimFileNotFound.java b/telephony/java/com/android/internal/telephony/gsm/SimFileNotFound.java deleted file mode 100644 index 982e2fd..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimFileNotFound.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class SimFileNotFound extends SimException -{ - SimFileNotFound() - { - - } - - SimFileNotFound(String s) - { - super(s); - } - - SimFileNotFound(int ef) - { - super("SIM EF Not Found 0x" + Integer.toHexString(ef)); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimFileTypeMismatch.java b/telephony/java/com/android/internal/telephony/gsm/SimFileTypeMismatch.java deleted file mode 100644 index 72790d0..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimFileTypeMismatch.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class SimFileTypeMismatch extends SimException -{ - SimFileTypeMismatch() - { - - } - - SimFileTypeMismatch(String s) - { - super(s); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimIoResult.java b/telephony/java/com/android/internal/telephony/gsm/SimIoResult.java deleted file mode 100644 index 2c4da83..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimIoResult.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * {@hide} - */ -public class -SimIoResult -{ - int sw1; - int sw2; - byte[] payload; - - public SimIoResult(int sw1, int sw2, byte[] payload) - { - this.sw1 = sw1; - this.sw2 = sw2; - this.payload = payload; - } - - public SimIoResult(int sw1, int sw2, String hexString) - { - this(sw1, sw2, SimUtils.hexStringToBytes(hexString)); - } - - public String toString() - { - return "SimIoResponse sw1:0x" + Integer.toHexString(sw1) + " sw2:0x" - + Integer.toHexString(sw2); - } - - /** - * true if this operation was successful - * See GSM 11.11 Section 9.4 - * (the fun stuff is absent in 51.011) - */ - public boolean success() - { - return sw1 == 0x90 || sw1 == 0x91 || sw1 == 0x9e || sw1 == 0x9f; - } - - /** - * Returns exception on error or null if success - */ - public SimException getException() - { - if (success()) return null; - - switch (sw1) { - case 0x94: - if (sw2 == 0x08) { - return new SimFileTypeMismatch(); - } else { - return new SimFileNotFound(); - } - default: - return new SimException("sw1:" + sw1 + " sw2:" + sw2); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java deleted file mode 100644 index 7cc9a80..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimPhoneBookInterfaceManager.java +++ /dev/null @@ -1,278 +0,0 @@ -/* -** 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.pm.PackageManager; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.ServiceManager; -import android.telephony.PhoneNumberUtils; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * SimPhoneBookInterfaceManager to provide an inter-process communication to - * access ADN-like SIM records. - */ -public class SimPhoneBookInterfaceManager extends ISimPhoneBook.Stub { - static final String LOG_TAG = "GSM"; - static final boolean DBG = false; - - private GSMPhone phone; - private AdnRecordCache adnCache; - private final Object mLock = new Object(); - private int recordSize[]; - private boolean success; - private List<AdnRecord> records; - - private static final boolean ALLOW_SIM_OP_IN_UI_THREAD = false; - - private static final int EVENT_GET_SIZE_DONE = 1; - private static final int EVENT_LOAD_DONE = 2; - private static final int EVENT_UPDATE_DONE = 3; - - Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - switch (msg.what) { - case EVENT_GET_SIZE_DONE: - ar = (AsyncResult) msg.obj; - synchronized (mLock) { - if (ar.exception == null) { - recordSize = (int[])ar.result; - // recordSize[0] is the record length - // recordSize[1] is the total length of the EF file - // recordSize[2] is the number of records in the EF file - log("GET_RECORD_SIZE Size " + recordSize[0] + - " total " + recordSize[1] + - " #record " + recordSize[2]); - mLock.notifyAll(); - } - } - break; - case EVENT_UPDATE_DONE: - ar = (AsyncResult) msg.obj; - synchronized (mLock) { - success = (ar.exception == null); - mLock.notifyAll(); - } - break; - case EVENT_LOAD_DONE: - ar = (AsyncResult)msg.obj; - synchronized (mLock) { - if (ar.exception == null) { - records = (List<AdnRecord>) - ((ArrayList<AdnRecord>) ar.result); - } else { - if(DBG) log("Cannot load ADN records"); - if (records != null) { - records.clear(); - } - } - mLock.notifyAll(); - } - break; - } - } - }; - - public SimPhoneBookInterfaceManager(GSMPhone phone) { - this.phone = phone; - adnCache = phone.mSIMRecords.getAdnCache(); - publish(); - } - - private void publish() { - ServiceManager.addService("simphonebook", this); - } - - /** - * Replace oldAdn with newAdn in ADN-like record in EF - * - * getAdnRecordsInEf must be called at least once before this function, - * otherwise an error will be returned - * throws SecurityException if no WRITE_CONTACTS permission - * - * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN - * @param oldTag adn tag to be replaced - * @param oldPhoneNumber adn number to be replaced - * Set both oldTag and oldPhoneNubmer to "" means to replace an - * empty record, aka, insert new record - * @param newTag adn tag to be stored - * @param newPhoneNumber adn number ot be stored - * Set both newTag and newPhoneNubmer to "" means to replace the old - * record with empty one, aka, delete old record - * @param pin2 required to update EF_FDN, otherwise must be null - * @return true for success - */ - public boolean - updateAdnRecordsInEfBySearch (int efid, - String oldTag, String oldPhoneNumber, - String newTag, String newPhoneNumber, String pin2) { - - - if (phone.getContext().checkCallingOrSelfPermission( - android.Manifest.permission.WRITE_CONTACTS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException( - "Requires android.permission.WRITE_CONTACTS permission"); - } - - - if (DBG) log("updateAdnRecordsInEfBySearch: efid=" + efid + - " ("+ oldTag + "," + oldPhoneNumber + ")"+ "==>" + - " ("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2); - synchronized(mLock) { - checkThread(); - success = false; - Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); - AdnRecord oldAdn = new AdnRecord(oldTag, oldPhoneNumber); - AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber); - adnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response); - try { - mLock.wait(); - } catch (InterruptedException e) { - log("interrupted while trying to update by search"); - } - } - return success; - } - - /** - * Update an ADN-like EF record by record index - * - * This is useful for iteration the whole ADN file, such as write the whole - * phone book or erase/format the whole phonebook - * throws SecurityException if no WRITE_CONTACTS permission - * - * @param efid must be one among EF_ADN, EF_FDN, and EF_SDN - * @param newTag adn tag to be stored - * @param newPhoneNumber adn number to be stored - * Set both newTag and newPhoneNubmer to "" means to replace the old - * record with empty one, aka, delete old record - * @param index is 1-based adn record index to be updated - * @param pin2 required to update EF_FDN, otherwise must be null - * @return true for success - */ - public boolean - updateAdnRecordsInEfByIndex(int efid, String newTag, - String newPhoneNumber, int index, String pin2) { - - if (phone.getContext().checkCallingOrSelfPermission( - android.Manifest.permission.WRITE_CONTACTS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException( - "Requires android.permission.WRITE_CONTACTS permission"); - } - - if (DBG) log("updateAdnRecordsInEfByIndex: efid=" + efid + - " Index=" + index + " ==> " + - "("+ newTag + "," + newPhoneNumber + ")"+ " pin2=" + pin2); - synchronized(mLock) { - checkThread(); - success = false; - Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); - AdnRecord newAdn = new AdnRecord(newTag, newPhoneNumber); - adnCache.updateAdnByIndex(efid, newAdn, index, pin2, response); - try { - mLock.wait(); - } catch (InterruptedException e) { - log("interrupted while trying to update by index"); - } - } - return success; - } - - /** - * Get the capacity of records in efid - * - * @param efid the EF id of a ADN-like SIM - * @return int[3] array - * recordSizes[0] is the single record length - * recordSizes[1] is the total length of the EF file - * recordSizes[2] is the number of records in the EF file - */ - public int[] getAdnRecordsSize(int efid) { - if (DBG) log("getAdnRecordsSize: efid=" + efid); - synchronized(mLock) { - checkThread(); - recordSize = new int[3]; - Message response = mHandler.obtainMessage(EVENT_GET_SIZE_DONE); - phone.mSIMFileHandler.getEFLinearRecordSize(efid, response); - try { - mLock.wait(); - } catch (InterruptedException e) { - log("interrupted while trying to load from the SIM"); - } - } - - return recordSize; - } - - /** - * Loads the AdnRecords in efid and returns them as a - * List of AdnRecords - * - * throws SecurityException if no READ_CONTACTS permission - * - * @param efid the EF id of a ADN-like SIM - * @return List of AdnRecord - */ - public List<AdnRecord> getAdnRecordsInEf(int efid) { - - if (phone.getContext().checkCallingOrSelfPermission( - android.Manifest.permission.READ_CONTACTS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException( - "Requires android.permission.READ_CONTACTS permission"); - } - - if (DBG) log("getAdnRecordsInEF: efid=" + efid); - - synchronized(mLock) { - checkThread(); - Message response = mHandler.obtainMessage(EVENT_LOAD_DONE); - adnCache.requestLoadAllAdnLike(efid, response); - try { - mLock.wait(); - } catch (InterruptedException e) { - log("interrupted while trying to load from the SIM"); - } - } - return records; - } - - private void checkThread() { - if (!ALLOW_SIM_OP_IN_UI_THREAD) { - // Make sure this isn't the UI thread, since it will block - if (mHandler.getLooper().equals(Looper.myLooper())) { - Log.e(LOG_TAG, "query() called on the main UI thread!"); - throw new IllegalStateException("You cannot call query on this provder from the main UI thread."); - } - } - } - - private void log(String msg) { - Log.d(LOG_TAG, "[SpbInterfaceManager] " + msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimProvider.java b/telephony/java/com/android/internal/telephony/gsm/SimProvider.java deleted file mode 100644 index cece4ba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimProvider.java +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (C) 2006 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.ContentProvider; -import android.content.UriMatcher; -import android.content.ContentValues; -import com.android.internal.database.ArrayListCursor; -import android.database.Cursor; -import android.net.Uri; -import android.os.SystemProperties; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.text.TextUtils; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * {@hide} - */ -public class SimProvider extends ContentProvider { - private static final String TAG = "SimProvider"; - private static final boolean DBG = false; - - - private static final String[] ADDRESS_BOOK_COLUMN_NAMES = new String[] { - "name", - "number" - }; - - private static final int ADN = 1; - private static final int FDN = 2; - private static final int SDN = 3; - - private static final String STR_TAG = "tag"; - private static final String STR_NUMBER = "number"; - private static final String STR_PIN2 = "pin2"; - - private static final UriMatcher URL_MATCHER = - new UriMatcher(UriMatcher.NO_MATCH); - - static { - URL_MATCHER.addURI("sim", "adn", ADN); - URL_MATCHER.addURI("sim", "fdn", FDN); - URL_MATCHER.addURI("sim", "sdn", SDN); - } - - - private boolean mSimulator; - - @Override - public boolean onCreate() { - String device = SystemProperties.get("ro.product.device"); - if (!TextUtils.isEmpty(device)) { - mSimulator = false; - } else { - // simulator - mSimulator = true; - } - - return true; - } - - @Override - public Cursor query(Uri url, String[] projection, String selection, - String[] selectionArgs, String sort) { - ArrayList<ArrayList> results; - - if (!mSimulator) { - switch (URL_MATCHER.match(url)) { - case ADN: - results = loadFromEf(SimConstants.EF_ADN); - break; - - case FDN: - results = loadFromEf(SimConstants.EF_FDN); - break; - - case SDN: - results = loadFromEf(SimConstants.EF_SDN); - break; - - default: - throw new IllegalArgumentException("Unknown URL " + url); - } - } else { - // Fake up some data for the simulator - results = new ArrayList<ArrayList>(4); - ArrayList<String> contact; - - contact = new ArrayList<String>(); - contact.add("Ron Stevens/H"); - contact.add("512-555-5038"); - results.add(contact); - - contact = new ArrayList<String>(); - contact.add("Ron Stevens/M"); - contact.add("512-555-8305"); - results.add(contact); - - contact = new ArrayList<String>(); - contact.add("Melissa Owens"); - contact.add("512-555-8305"); - results.add(contact); - - contact = new ArrayList<String>(); - contact.add("Directory Assistence"); - contact.add("411"); - results.add(contact); - } - - return new ArrayListCursor(ADDRESS_BOOK_COLUMN_NAMES, results); - } - - @Override - public String getType(Uri url) { - switch (URL_MATCHER.match(url)) { - case ADN: - case FDN: - case SDN: - return "vnd.android.cursor.dir/sim-contact"; - - default: - throw new IllegalArgumentException("Unknown URL " + url); - } - } - - @Override - public Uri insert(Uri url, ContentValues initialValues) { - Uri resultUri; - int efType; - String pin2 = null; - - if (DBG) log("insert"); - - int match = URL_MATCHER.match(url); - switch (match) { - case ADN: - efType = SimConstants.EF_ADN; - break; - - case FDN: - efType = SimConstants.EF_FDN; - pin2 = initialValues.getAsString("pin2"); - break; - - default: - throw new UnsupportedOperationException( - "Cannot insert into URL: " + url); - } - - String tag = initialValues.getAsString("tag"); - String number = initialValues.getAsString("number"); - boolean success = addSimRecordToEf(efType, tag, number, pin2); - - if (!success) { - return null; - } - - StringBuilder buf = new StringBuilder("content://im/"); - switch (match) { - case ADN: - buf.append("adn/"); - break; - - case FDN: - buf.append("fdn/"); - break; - } - - // TODO: we need to find out the rowId for the newly added record - buf.append(0); - - resultUri = Uri.parse(buf.toString()); - - /* - // notify interested parties that an insertion happened - getContext().getContentResolver().notifyInsert( - resultUri, rowID, null); - */ - - return resultUri; - } - - private String normalizeValue(String inVal) { - int len = inVal.length(); - String retVal = inVal; - - if (inVal.charAt(0) == '\'' && inVal.charAt(len-1) == '\'') { - retVal = inVal.substring(1, len-1); - } - - return retVal; - } - - @Override - public int delete(Uri url, String where, String[] whereArgs) { - int efType; - - if (DBG) log("delete"); - - int match = URL_MATCHER.match(url); - switch (match) { - case ADN: - efType = SimConstants.EF_ADN; - break; - - case FDN: - efType = SimConstants.EF_FDN; - break; - - default: - throw new UnsupportedOperationException( - "Cannot insert into URL: " + url); - } - - // parse where clause - String tag = null; - String number = null; - String pin2 = null; - - String[] tokens = where.split("AND"); - int n = tokens.length; - - while (--n >= 0) { - String param = tokens[n]; - if (DBG) log("parsing '" + param + "'"); - - String[] pair = param.split("="); - - if (pair.length != 2) { - Log.e(TAG, "resolve: bad whereClause parameter: " + param); - continue; - } - - String key = pair[0].trim(); - String val = pair[1].trim(); - - if (STR_TAG.equals(key)) { - tag = normalizeValue(val); - } else if (STR_NUMBER.equals(key)) { - number = normalizeValue(val); - } else if (STR_PIN2.equals(key)) { - pin2 = normalizeValue(val); - } - } - - if (TextUtils.isEmpty(tag)) { - return 0; - } - - if (efType == FDN && TextUtils.isEmpty(pin2)) { - return 0; - } - - boolean success = deleteSimRecordFromEf(efType, tag, number, pin2); - if (!success) { - return 0; - } - - return 1; - } - - @Override - public int update(Uri url, ContentValues values, String where, String[] whereArgs) { - int efType; - String pin2 = null; - - if (DBG) log("update"); - - int match = URL_MATCHER.match(url); - switch (match) { - case ADN: - efType = SimConstants.EF_ADN; - break; - - case FDN: - efType = SimConstants.EF_FDN; - pin2 = values.getAsString("pin2"); - break; - - default: - throw new UnsupportedOperationException( - "Cannot insert into URL: " + url); - } - - String tag = values.getAsString("tag"); - String number = values.getAsString("number"); - String newTag = values.getAsString("newTag"); - String newNumber = values.getAsString("newNumber"); - - boolean success = updateSimRecordInEf(efType, tag, number, - newTag, newNumber, pin2); - - if (!success) { - return 0; - } - - return 1; - } - - private ArrayList<ArrayList> loadFromEf(int efType) { - ArrayList<ArrayList> results = new ArrayList<ArrayList>(); - List<AdnRecord> adnRecords = null; - - if (DBG) log("loadFromEf: efType=" + efType); - - try { - ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (simIpb != null) { - adnRecords = simIpb.getAdnRecordsInEf(efType); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - - if (adnRecords != null) { - // Load the results - - int N = adnRecords.size(); - if (DBG) log("adnRecords.size=" + N); - for (int i = 0; i < N ; i++) { - loadRecord(adnRecords.get(i), results); - } - } else { - // No results to load - Log.w(TAG, "Cannot load ADN records"); - results.clear(); - } - if (DBG) log("loadFromEf: return results"); - return results; - } - - private boolean - addSimRecordToEf(int efType, String name, String number, String pin2) { - if (DBG) log("addSimRecordToEf: efType=" + efType + ", name=" + name + - ", number=" + number); - - boolean success = false; - - // TODO: do we need to call getAdnRecordsInEf() before calling - // updateAdnRecordsInEfBySearch()? In any case, we will leave - // the UI level logic to fill that prereq if necessary. But - // hopefully, we can remove this requirement. - try { - ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (simIpb != null) { - success = simIpb.updateAdnRecordsInEfBySearch(efType, "", "", - name, number, pin2); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - if (DBG) log("addSimRecordToEf: " + success); - return success; - } - - private boolean - updateSimRecordInEf(int efType, String oldName, String oldNumber, - String newName, String newNumber,String pin2) { - if (DBG) log("updateSimRecordInEf: efType=" + efType + - ", oldname=" + oldName + ", oldnumber=" + oldNumber + - ", newname=" + newName + ", newnumber=" + newNumber); - boolean success = false; - - try { - ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (simIpb != null) { - success = simIpb.updateAdnRecordsInEfBySearch(efType, - oldName, oldNumber, newName, newNumber, pin2); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - - if (DBG) log("updateSimRecordInEf: " + success); - return success; - } - - - private boolean deleteSimRecordFromEf(int efType, - String name, String number, - String pin2) { - if (DBG) log("deleteSimRecordFromEf: efType=" + efType + - ", name=" + name + ", number=" + number + ", pin2=" + pin2); - - boolean success = false; - - try { - ISimPhoneBook simIpb = ISimPhoneBook.Stub.asInterface( - ServiceManager.getService("simphonebook")); - if (simIpb != null) { - success = simIpb.updateAdnRecordsInEfBySearch(efType, - name, number, "", "", pin2); - } - } catch (RemoteException ex) { - // ignore it - } catch (SecurityException ex) { - if (DBG) log(ex.toString()); - } - - if (DBG) log("deleteSimRecordFromEf: " + success); - return success; - } - - /** - * Loads an AdnRecord into an ArrayList. Must be called with mLock held. - * - * @param record the ADN record to load from - * @param results the array list to put the results in - */ - private void loadRecord(AdnRecord record, - ArrayList<ArrayList> results) { - if (!record.isEmpty()) { - ArrayList<String> contact = new ArrayList<String>(2); - String alphaTag = record.getAlphaTag(); - String number = record.getNumber(); - - if (DBG) log("loadRecord: " + alphaTag + ", " + number); - contact.add(alphaTag); - contact.add(number); - results.add(contact); - } - } - - private void log(String msg) { - Log.d(TAG, "[SimProvider] " + msg); - } - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java deleted file mode 100644 index c3df0d0..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java +++ /dev/null @@ -1,302 +0,0 @@ -/* -** 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.app.PendingIntent; -import android.content.Context; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.Message; -import android.os.ServiceManager; -import android.telephony.gsm.SmsManager; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * SimSmsInterfaceManager to provide an inter-process communication to - * access Sms in Sim. - */ -public class SimSmsInterfaceManager extends ISms.Stub { - static final String LOG_TAG = "GSM"; - static final boolean DBG = false; - - private GSMPhone mPhone; - 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 = (List<SmsRawData>) - 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) { - this.mPhone = phone; - ServiceManager.addService("isms", this); - } - - private void enforceReceiveAndSend(String message) { - Context context = mPhone.getContext(); - - context.enforceCallingPermission( - "android.permission.RECEIVE_SMS", message); - context.enforceCallingPermission( - "android.permission.SEND_SMS", message); - } - - /** - * Update the specified message on the SIM. - * - * @param index record index of message to update - * @param status new message status (STATUS_ON_SIM_READ, - * STATUS_ON_SIM_UNREAD, STATUS_ON_SIM_SENT, - * STATUS_ON_SIM_UNSENT, STATUS_ON_SIM_FREE) - * @param pdu the raw PDU to store - * @return success or not - * - */ - public boolean - updateMessageOnSimEf(int index, int status, byte[] pdu) { - if (DBG) log("updateMessageOnSimEf: index=" + index + - " status=" + status + " ==> " + - "("+ pdu + ")"); - enforceReceiveAndSend("Updating message on SIM"); - synchronized(mLock) { - mSuccess = false; - Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); - - if (status == SmsManager.STATUS_ON_SIM_FREE) { - // Special case FREE: call deleteSmsOnSim instead of - // manipulating the SIM record - mPhone.mCM.deleteSmsOnSim(index, response); - } else { - byte[] record = makeSmsRecordData(status, pdu); - mPhone.mSIMFileHandler.updateEFLinearFixed( SimConstants.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_SIM_READ, STATUS_ON_SIM_UNREAD, - * STATUS_ON_SIM_SENT, STATUS_ON_SIM_UNSENT) - * @return success or not - * - */ - public boolean copyMessageToSimEf(int status, byte[] pdu, byte[] smsc) { - if (DBG) log("copyMessageToSimEf: status=" + status + " ==> " + - "pdu=("+ pdu + "), smsm=(" + smsc +")"); - enforceReceiveAndSend("Copying message to SIM"); - synchronized(mLock) { - mSuccess = false; - Message response = mHandler.obtainMessage(EVENT_UPDATE_DONE); - - mPhone.mCM.writeSmsToSim(status, SimUtils.bytesToHexString(smsc), - SimUtils.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 SIM. - * - * @return list of SmsRawData of all sms on SIM - */ - public List<SmsRawData> getAllMessagesFromSimEf() { - 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.mSIMFileHandler.loadEFLinearFixedAll(SimConstants.EF_SMS, - response); - - try { - mLock.wait(); - } catch (InterruptedException e) { - log("interrupted while trying to load from the SIM"); - } - } - return mSms; - } - - /** - * Send a Raw PDU SMS - * - * @param smsc the SMSC to send the message through, or NULL for the - * defatult SMSC - * @param pdu the raw PDU to send - * @param sentIntent if not NULL this <code>Intent</code> is - * broadcast when the message is sucessfully sent, or failed. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * @param deliveryIntent if not NULL this <code>Intent</code> is - * broadcast when the message is delivered to the recipient. The - * raw pdu of the status report is in the extended data ("pdu"). - */ - public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent, - PendingIntent deliveryIntent) { - Context context = mPhone.getContext(); - - context.enforceCallingPermission( - "android.permission.SEND_SMS", - "Sending SMS message"); - if (DBG) log("sendRawPdu: smsc=" + smsc + - " pdu="+ pdu + " sentIntent" + sentIntent + - " deliveryIntent" + deliveryIntent); - mPhone.mSMS.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent); - } - - /** - * Send a multi-part text based SMS. - * - * @param destinationAddress the address to send the message to - * @param scAddress is the service center address or null to use - * the current default SMSC - * @param parts an <code>ArrayList</code> of strings that, in order, - * comprise the original message - * @param sentIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been sent. - * The result code will be <code>Activity.RESULT_OK<code> for success, - * or one of these errors: - * <code>RESULT_ERROR_GENERIC_FAILURE</code> - * <code>RESULT_ERROR_RADIO_OFF</code> - * <code>RESULT_ERROR_NULL_PDU</code>. - * @param deliveryIntents if not null, an <code>ArrayList</code> of - * <code>PendingIntent</code>s (one for each message part) that is - * broadcast when the corresponding message part has been delivered - * to the recipient. The raw pdu of the status report is in the - * extended data ("pdu"). - */ - public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts, - List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { - Context context = mPhone.getContext(); - - context.enforceCallingPermission( - "android.permission.SEND_SMS", - "Sending SMS message"); - if (DBG) log("sendMultipartText"); - mPhone.mSMS.sendMultipartText(destinationAddress, scAddress, (ArrayList<String>) parts, - (ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents); - } - - /** - * Generates an EF_SMS record from status and raw PDU. - * - * @param status Message status. See TS 51.011 10.5.3. - * @param pdu Raw message PDU. - * @return byte array for the record. - */ - private byte[] makeSmsRecordData(int status, byte[] pdu) { - byte[] data = new byte[SimConstants.SMS_RECORD_LENGTH]; - - // Status bits for this record. See TS 51.011 10.5.3 - data[0] = (byte)(status & 7); - - System.arraycopy(pdu, 0, data, 1, pdu.length); - - // Pad out with 0xFF's. - for (int j = pdu.length+1; j < SimConstants.SMS_RECORD_LENGTH; j++) { - data[j] = -1; - } - - return data; - } - - /** - * create SmsRawData lists from all sms record byte[] - * Use null to indicate "free" record - * - * @param messages List of message records from EF_SMS. - * @return SmsRawData list of all in-used records - */ - private ArrayList<SmsRawData> buildValidRawData(ArrayList<byte[]> messages) { - int count = messages.size(); - ArrayList<SmsRawData> ret; - - ret = new ArrayList<SmsRawData>(count); - - for (int i = 0; i < count; i++) { - byte[] ba = messages.get(i); - if (ba[0] == 0) { - ret.add(null); - } else { - ret.add(new SmsRawData(messages.get(i))); - } - } - - return ret; - } - - private void log(String msg) { - Log.d(LOG_TAG, "[SmsInterfaceManager] " + msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java b/telephony/java/com/android/internal/telephony/gsm/SimTlv.java deleted file mode 100644 index 00879ce..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimTlv.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2006 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; - -/** - * SIM Tag-Length-Value record - * TS 102 223 Annex C - * - * {@hide} - * - */ -public class SimTlv -{ - //***** Private Instance Variables - - byte record[]; - int tlvOffset; - int tlvLength; - int curOffset; - int curDataOffset; - int curDataLength; - boolean hasValidTlvObject; - - public SimTlv(byte[] record, int offset, int length) - { - this.record = record; - - this.tlvOffset = offset; - this.tlvLength = length; - curOffset = offset; - - hasValidTlvObject = parseCurrentTlvObject(); - } - - public boolean - nextObject() - { - if (!hasValidTlvObject) return false; - - curOffset = curDataOffset + curDataLength; - hasValidTlvObject = parseCurrentTlvObject(); - return hasValidTlvObject; - } - - public boolean - isValidObject() - { - return hasValidTlvObject; - } - - /** - * Returns the tag for the current TLV object - * Return 0 if !isValidObject() - * 0 and 0xff are invalid tag values - * valid tags range from 1 - 0xfe - */ - public int - getTag() - { - if (!hasValidTlvObject) return 0; - return record[curOffset] & 0xff; - } - - /** - * Returns data associated with current TLV object - * returns null if !isValidObject() - */ - - public byte[] - getData() - { - if (!hasValidTlvObject) return null; - - byte[] ret = new byte[curDataLength]; - System.arraycopy(record, curDataOffset, ret, 0, curDataLength); - return ret; - } - - /** - * Updates curDataLength and curDataOffset - * @return false on invalid record, true on valid record - */ - - private boolean - parseCurrentTlvObject() - { - // 0x00 and 0xff are invalid tag values - if (record[curOffset] == 0 || (record[curOffset] & 0xff) == 0xff) { - return false; - } - - try { - if ((record[curOffset + 1] & 0xff) < 0x80) { - // one byte length 0 - 0x7f - curDataLength = record[curOffset + 1] & 0xff; - curDataOffset = curOffset + 2; - } else if ((record[curOffset + 1] & 0xff) == 0x81) { - // two byte length 0x80 - 0xff - curDataLength = record[curOffset + 2] & 0xff; - curDataOffset = curOffset + 3; - } else { - return false; - } - } catch (ArrayIndexOutOfBoundsException ex) { - return false; - } - - if (curDataLength + curDataOffset > tlvOffset + tlvLength) { - return false; - } - - return true; - } - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SimUtils.java b/telephony/java/com/android/internal/telephony/gsm/SimUtils.java deleted file mode 100644 index 2eecdba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SimUtils.java +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright (C) 2006 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 java.io.UnsupportedEncodingException; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.util.Log; - -/** - * Various methods, useful for dealing with SIM data. - */ -public class SimUtils -{ - static final String LOG_TAG="GSM"; - - /** - * Many fields in GSM SIM's are stored as nibble-swizzled BCD - * - * Assumes left-justified field that may be padded right with 0xf - * values. - * - * Stops on invalid BCD value, returning string so far - */ - public static String - bcdToString(byte[] data, int offset, int length) - { - StringBuilder ret = new StringBuilder(length*2); - - for (int i = offset ; i < offset + length ; i++) { - byte b; - int v; - - v = data[i] & 0xf; - if (v > 9) break; - ret.append((char)('0' + v)); - - v = (data[i] >> 4) & 0xf; - if (v > 9) break; - ret.append((char)('0' + v)); - } - - return ret.toString(); - } - - - /** - * Decodes a GSM-style BCD byte, returning an int ranging from 0-99. - * - * In GSM land, the least significant BCD digit is stored in the most - * significant nibble. - * - * Out-of-range digits are treated as 0 for the sake of the time stamp, - * because of this: - * - * TS 23.040 section 9.2.3.11 - * "if the MS receives a non-integer value in the SCTS, it shall - * assume the digit is set to 0 but shall store the entire field - * exactly as received" - */ - public static int - bcdByteToInt(byte b) - { - int ret = 0; - - // treat out-of-range BCD values as 0 - if ((b & 0xf0) <= 0x90) { - ret = (b >> 4) & 0xf; - } - - if ((b & 0x0f) <= 0x09) { - ret += (b & 0xf) * 10; - } - - return ret; - } - - - /** - * Decodes a string field that's formatted like the EF[ADN] alpha - * identifier - * - * From TS 51.011 10.5.1: - * Coding: - * this alpha tagging shall use either - * - the SMS default 7 bit coded alphabet as defined in - * TS 23.038 [12] with bit 8 set to 0. The alpha identifier - * shall be left justified. Unused bytes shall be set to 'FF'; or - * - one of the UCS2 coded options as defined in annex B. - * - * Annex B from TS 11.11 V8.13.0: - * 1) If the first octet in the alpha string is '80', then the - * remaining octets are 16 bit UCS2 characters ... - * 2) if the first octet in the alpha string is '81', then the - * second octet contains a value indicating the number of - * characters in the string, and the third octet contains an - * 8 bit number which defines bits 15 to 8 of a 16 bit - * base pointer, where bit 16 is set to zero and bits 7 to 1 - * are also set to zero. These sixteen bits constitute a - * base pointer to a "half page" in the UCS2 code space, to be - * used with some or all of the remaining octets in the string. - * The fourth and subsequent octets contain codings as follows: - * If bit 8 of the octet is set to zero, the remaining 7 bits - * of the octet contain a GSM Default Alphabet character, - * whereas if bit 8 of the octet is set to one, then the - * remaining seven bits are an offset value added to the - * 16 bit base pointer defined earlier... - * 3) If the first octet of the alpha string is set to '82', then - * the second octet contains a value indicating the number of - * characters in the string, and the third and fourth octets - * contain a 16 bit number which defines the complete 16 bit - * base pointer to a "half page" in the UCS2 code space... - */ - public static String - adnStringFieldToString(byte[] data, int offset, int length) - { - if (length >= 1) { - if (data[offset] == (byte) 0x80) { - int ucslen = (length - 1) / 2; - String ret = null; - - try { - ret = new String(data, offset + 1, ucslen * 2, "utf-16be"); - } catch (UnsupportedEncodingException ex) { - Log.e(LOG_TAG, "implausible UnsupportedEncodingException", - ex); - } - - if (ret != null) { - // trim off trailing FFFF characters - - ucslen = ret.length(); - while (ucslen > 0 && ret.charAt(ucslen - 1) == '\uFFFF') - ucslen--; - - return ret.substring(0, ucslen); - } - } - } - - boolean isucs2 = false; - char base = '\0'; - int len = 0; - - if (length >= 3 && data[offset] == (byte) 0x81) { - len = data[offset + 1] & 0xFF; - if (len > length - 3) - len = length - 3; - - base = (char) ((data[offset + 2] & 0xFF) << 7); - offset += 3; - isucs2 = true; - } else if (length >= 4 && data[offset] == (byte) 0x82) { - len = data[offset + 1] & 0xFF; - if (len > length - 4) - len = length - 4; - - base = (char) (((data[offset + 2] & 0xFF) << 8) | - (data[offset + 3] & 0xFF)); - offset += 4; - isucs2 = true; - } - - if (isucs2) { - StringBuilder ret = new StringBuilder(); - - while (len > 0) { - // UCS2 subset case - - if (data[offset] < 0) { - ret.append((char) (base + (data[offset] & 0x7F))); - offset++; - len--; - } - - // GSM character set case - - int count = 0; - while (count < len && data[offset + count] >= 0) - count++; - - ret.append(GsmAlphabet.gsm8BitUnpackedToString(data, - offset, count)); - - offset += count; - len -= count; - } - - return ret.toString(); - } - - return GsmAlphabet.gsm8BitUnpackedToString(data, offset, length); - } - - static int - hexCharToInt(char c) - { - if (c >= '0' && c <= '9') return (c - '0'); - if (c >= 'A' && c <= 'F') return (c - 'A' + 10); - if (c >= 'a' && c <= 'f') return (c - 'a' + 10); - - throw new RuntimeException ("invalid hex char '" + c + "'"); - } - - /** - * Converts a hex String to a byte array. - * - * @param s A string of hexadecimal characters, must be an even number of - * chars long - * - * @return byte array representation - * - * @throws RuntimeException on invalid format - */ - public static byte[] - hexStringToBytes(String s) - { - byte[] ret; - - if (s == null) return null; - - int sz = s.length(); - - ret = new byte[sz/2]; - - for (int i=0 ; i <sz ; i+=2) { - ret[i/2] = (byte) ((hexCharToInt(s.charAt(i)) << 4) - | hexCharToInt(s.charAt(i+1))); - } - - return ret; - } - - - /** - * Converts a byte array into a String hexidecimal characters - * - * null returns null - */ - public static String - bytesToHexString(byte[] bytes) - { - if (bytes == null) return null; - - StringBuilder ret = new StringBuilder(2*bytes.length); - - for (int i = 0 ; i < bytes.length ; i++) { - int b; - - b = 0x0f & (bytes[i] >> 4); - - ret.append("0123456789abcdef".charAt(b)); - - b = 0x0f & bytes[i]; - - ret.append("0123456789abcdef".charAt(b)); - } - - return ret.toString(); - } - - - /** - * Convert a TS 24.008 Section 10.5.3.5a Network Name field to a string - * "offset" points to "octet 3", the coding scheme byte - * empty string returned on decode error - */ - public static String - networkNameToString(byte[] data, int offset, int length) - { - String ret; - - if ((data[offset] & 0x80) != 0x80 || length < 1) { - return ""; - } - - switch ((data[offset] >>> 4) & 0x7) { - case 0: - // SMS character set - int countSeptets; - int unusedBits = data[offset] & 7; - countSeptets = (((length - 1) * 8) - unusedBits) / 7 ; - ret = GsmAlphabet.gsm7BitPackedToString( - data, offset + 1, countSeptets); - break; - case 1: - // UCS2 - try { - ret = new String(data, - offset + 1, length - 1, "utf-16"); - } catch (UnsupportedEncodingException ex) { - ret = ""; - Log.e(LOG_TAG,"implausible UnsupportedEncodingException", ex); - } - break; - - // unsupported encoding - default: - ret = ""; - break; - } - - // "Add CI" - // "The MS should add the letters for the Country's Initials and - // a separator (e.g. a space) to the text string" - - if ((data[offset] & 0x40) != 0) { - // FIXME(mkf) add country initials here - - } - - return ret; - } - - /** - * Convert a TS 131.102 image instance of code scheme '11' into Bitmap - * @param data The raw data - * @param length The length of image body - * @return The bitmap - */ - public static Bitmap parseToBnW(byte[] data, int length){ - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int numOfPixels = width*height; - - int[] pixels = new int[numOfPixels]; - - int pixelIndex = 0; - int bitIndex = 7; - byte currentByte = 0x00; - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (pixelIndex % 8 == 0) { - currentByte = data[valueIndex++]; - bitIndex = 7; - } - pixels[pixelIndex++] = bitToRGB((currentByte >> bitIndex-- ) & 0x01); - }; - - if (pixelIndex != numOfPixels) { - Log.e(LOG_TAG, "parse end and size error"); - } - return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); - } - - private static int bitToRGB(int bit){ - if(bit == 1){ - return Color.WHITE; - } else { - return Color.BLACK; - } - } - - /** - * a TS 131.102 image instance of code scheme '11' into color Bitmap - * - * @param data The raw data - * @param length the length of image body - * @param transparency with or without transparency - * @return The color bitmap - */ - public static Bitmap parseToRGB(byte[] data, int length, - boolean transparency) { - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int bits = data[valueIndex++] & 0xFF; - int colorNumber = data[valueIndex++] & 0xFF; - int clutOffset = ((data[valueIndex++] & 0xFF) << 8) - | data[valueIndex++]; - length = length - 6; - - int[] colorIndexArray = getCLUT(data, clutOffset, colorNumber); - if (true == transparency) { - colorIndexArray[colorNumber - 1] = Color.TRANSPARENT; - } - - int[] resultArray = null; - if (0 == (8 % bits)) { - resultArray = mapTo2OrderBitColor(data, valueIndex, - (width * height), colorIndexArray, bits); - } else { - resultArray = mapToNon2OrderBitColor(data, valueIndex, - (width * height), colorIndexArray, bits); - } - - return Bitmap.createBitmap(resultArray, width, height, - Bitmap.Config.RGB_565); - } - - private static int[] mapTo2OrderBitColor(byte[] data, int valueIndex, - int length, int[] colorArray, int bits) { - if (0 != (8 % bits)) { - Log.e(LOG_TAG, "not event number of color"); - return mapToNon2OrderBitColor(data, valueIndex, length, colorArray, - bits); - } - - int mask = 0x01; - switch (bits) { - case 1: - mask = 0x01; - break; - case 2: - mask = 0x03; - break; - case 4: - mask = 0x0F; - break; - case 8: - mask = 0xFF; - break; - } - - int[] resultArray = new int[length]; - int resultIndex = 0; - int run = 8 / bits; - while (resultIndex < length) { - byte tempByte = data[valueIndex++]; - for (int runIndex = 0; runIndex < run; ++runIndex) { - int offset = run - runIndex - 1; - resultArray[resultIndex++] = colorArray[(tempByte >> (offset * bits)) - & mask]; - } - } - return resultArray; - } - - private static int[] mapToNon2OrderBitColor(byte[] data, int valueIndex, - int length, int[] colorArray, int bits) { - if (0 == (8 % bits)) { - Log.e(LOG_TAG, "not odd number of color"); - return mapTo2OrderBitColor(data, valueIndex, length, colorArray, - bits); - } - - int[] resultArray = new int[length]; - // TODO fix me: - return resultArray; - } - - private static int[] getCLUT(byte[] rawData, int offset, int number) { - if (null == rawData) { - return null; - } - - int[] result = new int[number]; - int endIndex = offset + (number * 3); // 1 color use 3 bytes - int valueIndex = offset; - int colorIndex = 0; - int alpha = 0xff << 24; - do { - result[colorIndex++] = alpha - | ((rawData[valueIndex++] & 0xFF) << 16) - | ((rawData[valueIndex++] & 0xFF) << 8) - | ((rawData[valueIndex++] & 0xFF)); - } while (valueIndex < endIndex); - return result; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsHeader.java deleted file mode 100644 index 22366ec..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsHeader.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2006 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 com.android.internal.util.HexDump; - -import java.util.ArrayList; - -/** - * This class represents a SMS user data header. - * - */ -public class SmsHeader -{ - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int CONCATENATED_8_BIT_REFERENCE = 0x00; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int SPECIAL_SMS_MESSAGE_INDICATION = 0x01; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int APPLICATION_PORT_ADDRESSING_8_BIT = 0x04; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int APPLICATION_PORT_ADDRESSING_16_BIT= 0x05; - /** See TS 23.040 9.2.3.24 for description of this element ID. */ - public static final int CONCATENATED_16_BIT_REFERENCE = 0x08; - - public static final int PORT_WAP_PUSH = 2948; - public static final int PORT_WAP_WSP = 9200; - - private byte[] m_data; - private ArrayList<Element> m_elements = new ArrayList<Element>(); - - /** - * Creates an SmsHeader object from raw user data header bytes. - * - * @param data is user data header bytes - * @return an SmsHeader object - */ - public static SmsHeader parse(byte[] data) - { - SmsHeader header = new SmsHeader(); - header.m_data = data; - - int index = 0; - while (index < data.length) - { - int id = data[index++] & 0xff; - int length = data[index++] & 0xff; - byte[] elementData = new byte[length]; - System.arraycopy(data, index, elementData, 0, length); - header.add(new Element(id, elementData)); - index += length; - } - - return header; - } - - public SmsHeader() - { - } - - /** - * Returns the list of SmsHeader Elements that make up the header. - * - * @return the list of SmsHeader Elements. - */ - public ArrayList<Element> getElements() - { - return m_elements; - } - - /** - * Add an element to the SmsHeader. - * - * @param element to add. - */ - public void add(Element element) - { - m_elements.add(element); - } - - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - - builder.append("UDH LENGTH: " + m_data.length + " octets"); - builder.append("UDH: "); - builder.append(HexDump.toHexString(m_data)); - builder.append("\n"); - - for (Element e : getElements()) { - builder.append(" 0x" + HexDump.toHexString((byte)e.getID()) + " - "); - switch (e.getID()) - { - case CONCATENATED_8_BIT_REFERENCE: - { - builder.append("Concatenated Short Message 8bit ref\n"); - byte[] data = e.getData(); - builder.append(" " + data.length + " (0x"); - builder.append(HexDump.toHexString((byte)data.length)+") Bytes - Information Element\n"); - builder.append(" " + data[0] + " : SM reference number\n"); - builder.append(" " + data[1] + " : number of messages\n"); - builder.append(" " + data[2] + " : this SM sequence number\n"); - break; - } - - case CONCATENATED_16_BIT_REFERENCE: - { - builder.append("Concatenated Short Message 16bit ref\n"); - byte[] data = e.getData(); - builder.append(" " + data.length + " (0x"); - builder.append(HexDump.toHexString((byte)data.length)+") Bytes - Information Element\n"); - builder.append(" " + (data[0] & 0xff) * 256 + (data[1] & 0xff) + - " : SM reference number\n"); - builder.append(" " + data[2] + " : number of messages\n"); - builder.append(" " + data[3] + " : this SM sequence number\n"); - break; - } - - case APPLICATION_PORT_ADDRESSING_16_BIT: - { - builder.append("Application port addressing 16bit\n"); - byte[] data = e.getData(); - - builder.append(" " + data.length + " (0x"); - builder.append(HexDump.toHexString((byte)data.length)+") Bytes - Information Element\n"); - - int source = (data[0] & 0xff) << 8; - source |= (data[1] & 0xff); - builder.append(" " + source + " : DESTINATION port\n"); - - int dest = (data[2] & 0xff) << 8; - dest |= (data[3] & 0xff); - builder.append(" " + dest + " : SOURCE port\n"); - break; - } - - default: - { - builder.append("Unknown element\n"); - break; - } - } - } - - return builder.toString(); - } - - private int calcSize() { - int size = 1; // +1 for the UDHL field - for (Element e : m_elements) { - size += e.getData().length; - size += 2; // 1 byte ID, 1 byte length - } - - return size; - } - - /** - * Converts SmsHeader object to a byte array as specified in TS 23.040 9.2.3.24. - * @return Byte array representing the SmsHeader - */ - public byte[] toByteArray() { - if (m_elements.size() == 0) return null; - - if (m_data == null) { - int size = calcSize(); - int cur = 1; - m_data = new byte[size]; - - m_data[0] = (byte) (size-1); // UDHL does not include itself - - for (Element e : m_elements) { - int length = e.getData().length; - m_data[cur++] = (byte) e.getID(); - m_data[cur++] = (byte) length; - System.arraycopy(e.getData(), 0, m_data, cur, length); - cur += length; - } - } - - return m_data; - } - - /** - * A single Element in the SMS User Data Header. - * - * See TS 23.040 9.2.3.24. - * - */ - public static class Element - { - private byte[] m_data; - private int m_id; - - public Element(int id, byte[] data) - { - m_id = id; - m_data = data; - } - - /** - * Returns the Information Element Identifier for this element. - * - * @return the IE identifier. - */ - public int getID() - { - return m_id; - } - - /** - * Returns the data portion of this element. - * - * @return element data. - */ - public byte[] getData() - { - return m_data; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.aidl b/telephony/java/com/android/internal/telephony/gsm/SmsRawData.aidl deleted file mode 100644 index 6f1a46d..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* -** 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; - -parcelable SmsRawData; diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.java b/telephony/java/com/android/internal/telephony/gsm/SmsRawData.java deleted file mode 100644 index a029d5c..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsRawData.java +++ /dev/null @@ -1,62 +0,0 @@ -/* -** 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.os.Parcelable; -import android.os.Parcel; - -/** - * A parcelable holder class of byte[] for ISms aidl implementation - */ -public class SmsRawData implements Parcelable { - byte[] data; - - //Static Methods - public static final Parcelable.Creator<SmsRawData> CREATOR - = new Parcelable.Creator<SmsRawData> (){ - public SmsRawData createFromParcel(Parcel source) { - int size; - size = source.readInt(); - byte[] data = new byte[size]; - source.readByteArray(data); - return new SmsRawData(data); - } - - public SmsRawData[] newArray(int size) { - return new SmsRawData[size]; - } - }; - - // Constructor - public SmsRawData(byte[] data) { - this.data = data; - } - - public byte[] getBytes() { - return data; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(data.length); - dest.writeByteArray(data); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsResponse.java b/telephony/java/com/android/internal/telephony/gsm/SmsResponse.java deleted file mode 100644 index c005b5f..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SmsResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 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; - -/** - * Object returned by the RIL upon successful completion of sendSMS. - * Contains message reference and ackPdu. - * - */ -class SmsResponse { - /** Message reference of the just-sent SMS. */ - int messageRef; - /** ackPdu for the just-sent SMS. */ - String ackPdu; - - SmsResponse(int messageRef, String ackPdu) { - this.messageRef = messageRef; - this.ackPdu = ackPdu; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java deleted file mode 100644 index 11ad52d..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/SuppServiceNotification.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 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.telephony.PhoneNumberUtils; - -/** - * Represents a Supplementary Service Notification received from the network. - * - * {@hide} - */ -public class SuppServiceNotification { - /** Type of notification: 0 = MO; 1 = MT */ - public int notificationType; - /** TS 27.007 7.17 "code1" or "code2" */ - public int code; - /** TS 27.007 7.17 "index" */ - public int index; - /** TS 27.007 7.17 "type" (MT only) */ - public int type; - /** TS 27.007 7.17 "number" (MT only) */ - public String number; - - static public final int MO_CODE_UNCONDITIONAL_CF_ACTIVE = 0; - static public final int MO_CODE_SOME_CF_ACTIVE = 1; - static public final int MO_CODE_CALL_FORWARDED = 2; - static public final int MO_CODE_CALL_IS_WAITING = 3; - static public final int MO_CODE_CUG_CALL = 4; - static public final int MO_CODE_OUTGOING_CALLS_BARRED = 5; - static public final int MO_CODE_INCOMING_CALLS_BARRED = 6; - static public final int MO_CODE_CLIR_SUPPRESSION_REJECTED = 7; - static public final int MO_CODE_CALL_DEFLECTED = 8; - - static public final int MT_CODE_FORWARDED_CALL = 0; - static public final int MT_CODE_CUG_CALL = 1; - static public final int MT_CODE_CALL_ON_HOLD = 2; - static public final int MT_CODE_CALL_RETRIEVED = 3; - static public final int MT_CODE_MULTI_PARTY_CALL = 4; - static public final int MT_CODE_ON_HOLD_CALL_RELEASED = 5; - static public final int MT_CODE_FORWARD_CHECK_RECEIVED = 6; - static public final int MT_CODE_CALL_CONNECTING_ECT = 7; - static public final int MT_CODE_CALL_CONNECTED_ECT = 8; - static public final int MT_CODE_DEFLECTED_CALL = 9; - static public final int MT_CODE_ADDITIONAL_CALL_FORWARDED = 10; - - public String toString() - { - return super.toString() + " mobile" - + (notificationType == 0 ? " originated " : " terminated ") - + " code: " + code - + " index: " + index - + " \"" - + PhoneNumberUtils.stringFromStringAndTOA(number, type) + "\" "; - } - -} diff --git a/telephony/java/com/android/internal/telephony/gsm/TelephonyEventLog.java b/telephony/java/com/android/internal/telephony/gsm/TelephonyEventLog.java deleted file mode 100644 index 1e583f0..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/TelephonyEventLog.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2008 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; - -/* This class contains the details related to Telephony Event Logging */ -public final class TelephonyEventLog { - - /* Event log tags */ - public static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100; - public static final int EVENT_LOG_RADIO_RESET_COUNTDOWN_TRIGGERED = 50101; - public static final int EVENT_LOG_RADIO_RESET = 50102; - public static final int EVENT_LOG_PDP_RESET = 50103; - public static final int EVENT_LOG_REREGISTER_NETWORK = 50104; - public static final int EVENT_LOG_RADIO_PDP_SETUP_FAIL = 50105; - public static final int EVENT_LOG_CALL_DROP = 50106; - public static final int EVENT_LOG_CGREG_FAIL = 50107; - public static final int EVENT_DATA_STATE_RADIO_OFF = 50108; - public static final int EVENT_LOG_PDP_NETWORK_DROP = 50109; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java b/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java deleted file mode 100644 index d4e1f72..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/VoiceMailConstants.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2006 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.os.Environment; -import android.util.Xml; -import android.util.Log; - -import java.util.HashMap; -import java.io.FileReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import com.android.internal.util.XmlUtils; - -/** - * {@hide} - */ -class VoiceMailConstants { - private HashMap<String, String[]> CarrierVmMap; - - - static final String LOG_TAG = "GSM"; - static final String PARTNER_VOICEMAIL_PATH ="etc/voicemail-conf.xml"; - - static final int NAME = 0; - static final int NUMBER = 1; - static final int TAG = 2; - static final int SIZE = 3; - - VoiceMailConstants () { - CarrierVmMap = new HashMap<String, String[]>(); - loadVoiceMail(); - } - - boolean containsCarrier(String carrier) { - return CarrierVmMap.containsKey(carrier); - } - - String getCarrierName(String carrier) { - String[] data = CarrierVmMap.get(carrier); - return data[NAME]; - } - - String getVoiceMailNumber(String carrier) { - String[] data = CarrierVmMap.get(carrier); - return data[NUMBER]; - } - - String getVoiceMailTag(String carrier) { - String[] data = CarrierVmMap.get(carrier); - return data[TAG]; - } - - private void loadVoiceMail() { - FileReader vmReader; - - final File vmFile = new File(Environment.getRootDirectory(), - PARTNER_VOICEMAIL_PATH); - - try { - vmReader = new FileReader(vmFile); - } catch (FileNotFoundException e) { - Log.w(LOG_TAG, "Can't open " + - Environment.getRootDirectory() + "/" + PARTNER_VOICEMAIL_PATH); - return; - } - - try { - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(vmReader); - - XmlUtils.beginDocument(parser, "voicemail"); - - while (true) { - XmlUtils.nextElement(parser); - - String name = parser.getName(); - if (!"voicemail".equals(name)) { - break; - } - - String[] data = new String[SIZE]; - String numeric = parser.getAttributeValue(null, "numeric"); - data[NAME] = parser.getAttributeValue(null, "carrier"); - data[NUMBER] = parser.getAttributeValue(null, "vmnumber"); - data[TAG] = parser.getAttributeValue(null, "vmtag"); - - CarrierVmMap.put(numeric, data); - } - } catch (XmlPullParserException e) { - Log.w(LOG_TAG, "Exception in Voicemail parser " + e); - } catch (IOException e) { - Log.w(LOG_TAG, "Exception in Voicemail parser " + e); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/package.html b/telephony/java/com/android/internal/telephony/gsm/package.html deleted file mode 100755 index 4b1cf99..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/package.html +++ /dev/null @@ -1,6 +0,0 @@ -<HTML> -<BODY> -Provides classes to control or read data from GSM phones. -@hide -</BODY> -</HTML> diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java b/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java deleted file mode 100644 index c002729..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/AppInterface.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -/** - * Interface for communication between STK App and STK Telephony - * - * {@hide} - */ -public interface AppInterface { - - /* - * Intent's actions which are broadcasted by the Telephony once a new STK - * proactive command, session end arrive. - */ - public static final String STK_CMD_ACTION = - "android.intent.action.stk.command"; - public static final String STK_SESSION_END_ACTION = - "android.intent.action.stk.session_end"; - - /* - * Callback function from app to telephony to pass a result code and user's - * input back to the SIM. - */ - void onCmdResponse(StkResponseMessage resMsg); - - /* - * Enumeration for representing "Type of Command" of proactive commands. - * Those are the only commands which are supported by the Telephony. Any app - * implementation should support those. - */ - public static enum CommandType { - DISPLAY_TEXT(0x21), - GET_INKEY(0x22), - GET_INPUT(0x23), - LAUNCH_BROWSER(0x15), - PLAY_TONE(0x20), - REFRESH(0x01), - SELECT_ITEM(0x24), - SEND_SS(0x11), - SEND_USSD(0x12), - SEND_SMS(0x13), - SEND_DTMF(0x14), - SET_UP_EVENT_LIST(0x05), - SET_UP_IDLE_MODE_TEXT(0x28), - SET_UP_MENU(0x25), - SET_UP_CALL(0x10); - - private int mValue; - - CommandType(int value) { - mValue = value; - } - - public int value() { - return mValue; - } - - /** - * Create a CommandType object. - * - * @param value Integer value to be converted to a CommandType object. - * @return CommandType object whose "Type of Command" value is {@code - * value}. If no CommandType object has that value, null is - * returned. - */ - public static CommandType fromInt(int value) { - for (CommandType e : CommandType.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java b/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java deleted file mode 100644 index 26c2175..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/BerTlv.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -import java.util.List; - -/** - * Class for representing BER-TLV objects. - * - * @see "ETSI TS 102 223 Annex C" for more information. - * - * {@hide} - */ -class BerTlv { - private int mTag = BER_UNKNOWN_TAG; - private List<ComprehensionTlv> mCompTlvs = null; - - public static final int BER_UNKNOWN_TAG = 0x00; - public static final int BER_PROACTIVE_COMMAND_TAG = 0xd0; - public static final int BER_MENU_SELECTION_TAG = 0xd3; - public static final int BER_EVENT_DOWNLOAD_TAG = 0xd6; - - private BerTlv(int tag, List<ComprehensionTlv> ctlvs) { - mTag = tag; - mCompTlvs = ctlvs; - } - - /** - * Gets a list of ComprehensionTlv objects contained in this BER-TLV object. - * - * @return A list of COMPREHENSION-TLV object - */ - public List<ComprehensionTlv> getComprehensionTlvs() { - return mCompTlvs; - } - - /** - * Gets a tag id of the BER-TLV object. - * - * @return A tag integer. - */ - public int getTag() { - return mTag; - } - - /** - * Decodes a BER-TLV object from a byte array. - * - * @param data A byte array to decode from - * @return A BER-TLV object decoded - * @throws ResultException - */ - public static BerTlv decode(byte[] data) throws ResultException { - int curIndex = 0; - int endIndex = data.length; - int tag, length = 0; - - try { - /* tag */ - tag = data[curIndex++] & 0xff; - if (tag == BER_PROACTIVE_COMMAND_TAG) { - /* length */ - int temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - length = temp; - } else if (temp == 0x81) { - temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - length = temp; - } else { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else { - if (ComprehensionTlvTag.COMMAND_DETAILS.value() == (tag & ~0x80)) { - tag = BER_UNKNOWN_TAG; - curIndex = 0; - } - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } catch (ResultException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - /* COMPREHENSION-TLVs */ - if (endIndex - curIndex < length) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - List<ComprehensionTlv> ctlvs = ComprehensionTlv.decodeMany(data, - curIndex); - - return new BerTlv(tag, ctlvs); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java deleted file mode 100644 index 168361a..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandDetails.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -abstract class ValueObject { - abstract ComprehensionTlvTag getTag(); -} - -/** - * Class for Command Detailes object of proactive commands from SIM. - * {@hide} - */ -class CommandDetails extends ValueObject implements Parcelable { - public boolean compRequired; - public int commandNumber; - public int typeOfCommand; - public int commandQualifier; - - public ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.COMMAND_DETAILS; - } - - CommandDetails() { - } - - public boolean compareTo(CommandDetails other) { - return (this.compRequired == other.compRequired && - this.commandNumber == other.commandNumber && - this.commandQualifier == other.commandQualifier && - this.typeOfCommand == other.typeOfCommand); - } - - public CommandDetails(Parcel in) { - compRequired = true; - commandNumber = in.readInt(); - typeOfCommand = in.readInt(); - commandQualifier = in.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(commandNumber); - dest.writeInt(typeOfCommand); - dest.writeInt(commandQualifier); - } - - public static final Parcelable.Creator<CommandDetails> CREATOR = - new Parcelable.Creator<CommandDetails>() { - public CommandDetails createFromParcel(Parcel in) { - return new CommandDetails(in); - } - - public CommandDetails[] newArray(int size) { - return new CommandDetails[size]; - } - }; - - public int describeContents() { - return 0; - } -} - -class DeviceIdentities extends ValueObject { - public int sourceId; - public int destinationId; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.DEVICE_IDENTITIES; - } -} - -// Container class to hold icon identifier value. -class IconId extends ValueObject { - int recordNumber; - boolean selfExplanatory; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.ICON_ID; - } -} - -// Container class to hold item icon identifier list value. -class ItemsIconId extends ValueObject { - int [] recordNumbers; - boolean selfExplanatory; - - ComprehensionTlvTag getTag() { - return ComprehensionTlvTag.ITEM_ICON_ID_LIST; - } -}
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java deleted file mode 100644 index 60e8148..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParams.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.graphics.Bitmap; - -/** - * Container class for proactive command parameters. - * - */ -class CommandParams { - CommandDetails cmdDet; - - CommandParams(CommandDetails cmdDet) { - this.cmdDet = cmdDet; - } - - AppInterface.CommandType getCommandType() { - return AppInterface.CommandType.fromInt(cmdDet.typeOfCommand); - } - - boolean setIcon(Bitmap icon) { return true; } -} - -class DisplayTextParams extends CommandParams { - TextMessage textMsg; - - DisplayTextParams(CommandDetails cmdDet, TextMessage textMsg) { - super(cmdDet); - this.textMsg = textMsg; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && textMsg != null) { - textMsg.icon = icon; - return true; - } - return false; - } -} - -class LaunchBrowserParams extends CommandParams { - TextMessage confirmMsg; - LaunchBrowserMode mode; - String url; - - LaunchBrowserParams(CommandDetails cmdDet, TextMessage confirmMsg, - String url, LaunchBrowserMode mode) { - super(cmdDet); - this.confirmMsg = confirmMsg; - this.mode = mode; - this.url = url; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && confirmMsg != null) { - confirmMsg.icon = icon; - return true; - } - return false; - } -} - -class PlayToneParams extends CommandParams { - TextMessage textMsg; - ToneSettings settings; - - PlayToneParams(CommandDetails cmdDet, TextMessage textMsg, - Tone tone, Duration duration, boolean vibrate) { - super(cmdDet); - this.textMsg = textMsg; - this.settings = new ToneSettings(duration, tone, vibrate); - } - - boolean setIcon(Bitmap icon) { - if (icon != null && textMsg != null) { - textMsg.icon = icon; - return true; - } - return false; - } -} - -class CallSetupParams extends CommandParams { - TextMessage confirmMsg; - TextMessage callMsg; - - CallSetupParams(CommandDetails cmdDet, TextMessage confirmMsg, - TextMessage callMsg) { - super(cmdDet); - this.confirmMsg = confirmMsg; - this.callMsg = callMsg; - } - - boolean setIcon(Bitmap icon) { - if (icon == null) { - return false; - } - if (confirmMsg != null && confirmMsg.icon == null) { - confirmMsg.icon = icon; - return true; - } else if (callMsg != null && callMsg.icon == null) { - callMsg.icon = icon; - return true; - } - return false; - } -} - -class SelectItemParams extends CommandParams { - Menu menu = null; - boolean loadTitleIcon = false; - - SelectItemParams(CommandDetails cmdDet, Menu menu, boolean loadTitleIcon) { - super(cmdDet); - this.menu = menu; - this.loadTitleIcon = loadTitleIcon; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && menu != null) { - if (loadTitleIcon && menu.titleIcon == null) { - menu.titleIcon = icon; - } else { - for (Item item : menu.items) { - if (item.icon != null) { - continue; - } - item.icon = icon; - break; - } - } - return true; - } - return false; - } -} - -class GetInputParams extends CommandParams { - Input input = null; - - GetInputParams(CommandDetails cmdDet, Input input) { - super(cmdDet); - this.input = input; - } - - boolean setIcon(Bitmap icon) { - if (icon != null && input != null) { - input.icon = icon; - } - return true; - } -} - - diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java b/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java deleted file mode 100644 index eb354e9..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/CommandParamsFactory.java +++ /dev/null @@ -1,866 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.graphics.Bitmap; -import android.os.Handler; -import android.os.Message; - -import com.android.internal.telephony.gsm.GsmAlphabet; -import com.android.internal.telephony.gsm.SIMFileHandler; - -import java.util.Iterator; -import java.util.List; - -/** - * Factory class, used for decoding raw byte arrays, received from baseband, - * into a CommandParams object. - * - */ -class CommandParamsFactory extends Handler { - private static CommandParamsFactory sInstance = null; - private IconLoader mIconLoader; - private CommandParams mCmdParams = null; - private int mIconLoadState = LOAD_NO_ICON; - private RilMessageDecoder mCaller = null; - - // constants - static final int MSG_ID_LOAD_ICON_DONE = 1; - - // loading icons state parameters. - static final int LOAD_NO_ICON = 0; - static final int LOAD_SINGLE_ICON = 1; - static final int LOAD_MULTI_ICONS = 2; - - // Command Qualifier values for refresh command - static final int REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE = 0x00; - static final int REFRESH_NAA_INIT_AND_FILE_CHANGE = 0x02; - static final int REFRESH_NAA_INIT = 0x03; - static final int REFRESH_UICC_RESET = 0x04; - - static synchronized CommandParamsFactory getInstance(RilMessageDecoder caller, - SIMFileHandler fh) { - if (sInstance != null) { - return sInstance; - } - if (fh != null) { - return new CommandParamsFactory(caller, fh); - } - return null; - } - - private CommandParamsFactory(RilMessageDecoder caller, SIMFileHandler fh) { - mCaller = caller; - mIconLoader = IconLoader.getInstance(this, fh); - } - - private CommandDetails processCommandDetails(List<ComprehensionTlv> ctlvs) { - CommandDetails cmdDet = null; - - if (ctlvs != null) { - // Search for the Command Details object. - ComprehensionTlv ctlvCmdDet = searchForTag( - ComprehensionTlvTag.COMMAND_DETAILS, ctlvs); - if (ctlvCmdDet != null) { - try { - cmdDet = ValueParser.retrieveCommandDetails(ctlvCmdDet); - } catch (ResultException e) { - StkLog.d(this, "Failed to procees command details"); - } - } - } - return cmdDet; - } - - void make(BerTlv berTlv) { - if (berTlv == null) { - return; - } - // reset global state parameters. - mCmdParams = null; - mIconLoadState = LOAD_NO_ICON; - // only proactive command messages are processed. - if (berTlv.getTag() != BerTlv.BER_PROACTIVE_COMMAND_TAG) { - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - return; - } - boolean cmdPending = false; - List<ComprehensionTlv> ctlvs = berTlv.getComprehensionTlvs(); - // process command dtails from the tlv list. - CommandDetails cmdDet = processCommandDetails(ctlvs); - if (cmdDet == null) { - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - return; - } - - // extract command type enumeration from the raw value stored inside - // the Command Details object. - AppInterface.CommandType cmdType = AppInterface.CommandType - .fromInt(cmdDet.typeOfCommand); - if (cmdType == null) { - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - return; - } - - try { - switch (cmdType) { - case SET_UP_MENU: - cmdPending = processSelectItem(cmdDet, ctlvs); - break; - case SELECT_ITEM: - cmdPending = processSelectItem(cmdDet, ctlvs); - break; - case DISPLAY_TEXT: - cmdPending = processDisplayText(cmdDet, ctlvs); - break; - case SET_UP_IDLE_MODE_TEXT: - cmdPending = processSetUpIdleModeText(cmdDet, ctlvs); - break; - case GET_INKEY: - cmdPending = processGetInkey(cmdDet, ctlvs); - break; - case GET_INPUT: - cmdPending = processGetInput(cmdDet, ctlvs); - break; - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - cmdPending = processEventNotify(cmdDet, ctlvs); - break; - case SET_UP_CALL: - cmdPending = processSetupCall(cmdDet, ctlvs); - break; - case REFRESH: - processRefresh(cmdDet, ctlvs); - cmdPending = false; - break; - case LAUNCH_BROWSER: - cmdPending = processLaunchBrowser(cmdDet, ctlvs); - break; - case PLAY_TONE: - cmdPending = processPlayTone(cmdDet, ctlvs); - break; - default: - // unsupported proactive commands - mCmdParams = new CommandParams(cmdDet); - sendCmdParams(ResultCode.CMD_TYPE_NOT_UNDERSTOOD); - return; - } - } catch (ResultException e) { - mCmdParams = new CommandParams(cmdDet); - sendCmdParams(e.result()); - return; - } - if (!cmdPending) { - sendCmdParams(ResultCode.OK); - } - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_ID_LOAD_ICON_DONE: - sendCmdParams(setIcons(msg.obj)); - break; - } - } - - private ResultCode setIcons(Object data) { - Bitmap[] icons = null; - int iconIndex = 0; - - if (data == null) { - return ResultCode.PRFRMD_ICON_NOT_DISPLAYED; - } - switch(mIconLoadState) { - case LOAD_SINGLE_ICON: - mCmdParams.setIcon((Bitmap) data); - break; - case LOAD_MULTI_ICONS: - icons = (Bitmap[]) data; - // set each item icon. - for (Bitmap icon : icons) { - mCmdParams.setIcon(icon); - } - break; - } - return ResultCode.OK; - } - - private void sendCmdParams(ResultCode resCode) { - mCaller.sendMessageParamsDecoded(resCode, mCmdParams); - } - - /** - * Search for a COMPREHENSION-TLV object with the given tag from a list - * - * @param tag A tag to search for - * @param ctlvs List of ComprehensionTlv objects used to search in - * - * @return A ComprehensionTlv object that has the tag value of {@code tag}. - * If no object is found with the tag, null is returned. - */ - private ComprehensionTlv searchForTag(ComprehensionTlvTag tag, - List<ComprehensionTlv> ctlvs) { - Iterator<ComprehensionTlv> iter = ctlvs.iterator(); - return searchForNextTag(tag, iter); - } - - /** - * Search for the next COMPREHENSION-TLV object with the given tag from a - * list iterated by {@code iter}. {@code iter} points to the object next to - * the found object when this method returns. Used for searching the same - * list for similar tags, usually item id. - * - * @param tag A tag to search for - * @param iter Iterator for ComprehensionTlv objects used for search - * - * @return A ComprehensionTlv object that has the tag value of {@code tag}. - * If no object is found with the tag, null is returned. - */ - private ComprehensionTlv searchForNextTag(ComprehensionTlvTag tag, - Iterator<ComprehensionTlv> iter) { - int tagValue = tag.value(); - while (iter.hasNext()) { - ComprehensionTlv ctlv = iter.next(); - if (ctlv.getTag() == tagValue) { - return ctlv; - } - } - return null; - } - - /** - * Processes DISPLAY_TEXT proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processDisplayText(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) - throws ResultException { - - StkLog.d(this, "process DisplayText"); - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveTextString(ctlv); - } - // If the tlv object doesn't exist or the it is a null object reply - // with command not understood. - if (textMsg.text == null) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - ctlv = searchForTag(ComprehensionTlvTag.IMMEDIATE_RESPONSE, ctlvs); - if (ctlv != null) { - textMsg.responseNeeded = false; - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - // parse tone duration - ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); - if (ctlv != null) { - textMsg.duration = ValueParser.retrieveDuration(ctlv); - } - - // Parse command qualifier parameters. - textMsg.isHighPriority = (cmdDet.commandQualifier & 0x01) != 0; - textMsg.userClear = (cmdDet.commandQualifier & 0x80) != 0; - - mCmdParams = new DisplayTextParams(cmdDet, textMsg); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes SET_UP_IDLE_MODE_TEXT proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processSetUpIdleModeText(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - - StkLog.d(this, "process SetUpIdleModeText"); - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveTextString(ctlv); - } - // load icons only when text exist. - if (textMsg.text != null) { - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - } - - mCmdParams = new DisplayTextParams(cmdDet, textMsg); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes GET_INKEY proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processGetInkey(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - - StkLog.d(this, "process GetInkey"); - - Input input = new Input(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - input.text = ValueParser.retrieveTextString(ctlv); - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - } - - input.minLen = 1; - input.maxLen = 1; - - input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; - input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; - input.yesNo = (cmdDet.commandQualifier & 0x04) != 0; - input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; - - mCmdParams = new GetInputParams(cmdDet, input); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes GET_INPUT proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processGetInput(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - - StkLog.d(this, "process GetInput"); - - Input input = new Input(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TEXT_STRING, - ctlvs); - if (ctlv != null) { - input.text = ValueParser.retrieveTextString(ctlv); - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - ctlv = searchForTag(ComprehensionTlvTag.RESPONSE_LENGTH, ctlvs); - if (ctlv != null) { - try { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - input.minLen = rawValue[valueIndex] & 0xff; - input.maxLen = rawValue[valueIndex + 1] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - ctlv = searchForTag(ComprehensionTlvTag.DEFAULT_TEXT, ctlvs); - if (ctlv != null) { - input.defaultText = ValueParser.retrieveTextString(ctlv); - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - } - - input.digitOnly = (cmdDet.commandQualifier & 0x01) == 0; - input.ucs2 = (cmdDet.commandQualifier & 0x02) != 0; - input.echo = (cmdDet.commandQualifier & 0x04) == 0; - input.packed = (cmdDet.commandQualifier & 0x08) != 0; - input.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; - - mCmdParams = new GetInputParams(cmdDet, input); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes REFRESH proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - */ - private boolean processRefresh(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) { - - StkLog.d(this, "process Refresh"); - - // REFRESH proactive command is rerouted by the baseband and handled by - // the telephony layer. IDLE TEXT should be removed for a REFRESH command - // with "initialization" or "reset" - switch (cmdDet.commandQualifier) { - case REFRESH_NAA_INIT_AND_FULL_FILE_CHANGE: - case REFRESH_NAA_INIT_AND_FILE_CHANGE: - case REFRESH_NAA_INIT: - case REFRESH_UICC_RESET: - mCmdParams = new DisplayTextParams(cmdDet, null); - break; - } - return false; - } - - /** - * Processes SELECT_ITEM proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processSelectItem(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - - StkLog.d(this, "process SelectItem"); - - Menu menu = new Menu(); - IconId titleIconId = null; - ItemsIconId itemsIconId = null; - Iterator<ComprehensionTlv> iter = ctlvs.iterator(); - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, - ctlvs); - if (ctlv != null) { - menu.title = ValueParser.retrieveAlphaId(ctlv); - } - - while (true) { - ctlv = searchForNextTag(ComprehensionTlvTag.ITEM, iter); - if (ctlv != null) { - menu.items.add(ValueParser.retrieveItem(ctlv)); - } else { - break; - } - } - - // We must have at least one menu item. - if (menu.items.size() == 0) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - ctlv = searchForTag(ComprehensionTlvTag.ITEM_ID, ctlvs); - if (ctlv != null) { - // STK items are listed 1...n while list start at 0, need to - // subtract one. - menu.defaultItem = ValueParser.retrieveItemId(ctlv) - 1; - } - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - mIconLoadState = LOAD_SINGLE_ICON; - titleIconId = ValueParser.retrieveIconId(ctlv); - menu.titleIconSelfExplanatory = titleIconId.selfExplanatory; - } - - ctlv = searchForTag(ComprehensionTlvTag.ITEM_ICON_ID_LIST, ctlvs); - if (ctlv != null) { - mIconLoadState = LOAD_MULTI_ICONS; - itemsIconId = ValueParser.retrieveItemsIconId(ctlv); - menu.itemsIconSelfExplanatory = itemsIconId.selfExplanatory; - } - - boolean presentTypeSpecified = (cmdDet.commandQualifier & 0x01) != 0; - if (presentTypeSpecified) { - if ((cmdDet.commandQualifier & 0x02) == 0) { - menu.presentationType = PresentationType.DATA_VALUES; - } else { - menu.presentationType = PresentationType.NAVIGATION_OPTIONS; - } - } - menu.softKeyPreferred = (cmdDet.commandQualifier & 0x04) != 0; - menu.helpAvailable = (cmdDet.commandQualifier & 0x80) != 0; - - mCmdParams = new SelectItemParams(cmdDet, menu, titleIconId != null); - - // Load icons data if needed. - switch(mIconLoadState) { - case LOAD_NO_ICON: - return false; - case LOAD_SINGLE_ICON: - mIconLoader.loadIcon(titleIconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - break; - case LOAD_MULTI_ICONS: - int[] recordNumbers = itemsIconId.recordNumbers; - if (titleIconId != null) { - // Create a new array for all the icons (title and items). - recordNumbers = new int[itemsIconId.recordNumbers.length + 1]; - recordNumbers[0] = titleIconId.recordNumber; - System.arraycopy(itemsIconId.recordNumbers, 0, recordNumbers, - 1, itemsIconId.recordNumbers.length); - } - mIconLoader.loadIcons(recordNumbers, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - break; - } - return true; - } - - /** - * Processes EVENT_NOTIFY message from baseband. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - */ - private boolean processEventNotify(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - - StkLog.d(this, "process EventNotify"); - - TextMessage textMsg = new TextMessage(); - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, - ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveAlphaId(ctlv); - } else { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - - textMsg.responseNeeded = false; - mCmdParams = new DisplayTextParams(cmdDet, textMsg); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes SET_UP_EVENT_LIST proactive command from the SIM card. - * - * @param cmdDet Command Details object retrieved. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - */ - private boolean processSetUpEventList(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) { - - StkLog.d(this, "process SetUpEventList"); - // - // ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.EVENT_LIST, - // ctlvs); - // if (ctlv != null) { - // try { - // byte[] rawValue = ctlv.getRawValue(); - // int valueIndex = ctlv.getValueIndex(); - // int valueLen = ctlv.getLength(); - // - // } catch (IndexOutOfBoundsException e) {} - // } - return true; - } - - /** - * Processes LAUNCH_BROWSER proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - * @throws ResultException - */ - private boolean processLaunchBrowser(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - - StkLog.d(this, "process LaunchBrowser"); - - TextMessage confirmMsg = new TextMessage(); - IconId iconId = null; - String url = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.URL, ctlvs); - if (ctlv != null) { - try { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int valueLen = ctlv.getLength(); - if (valueLen > 0) { - url = GsmAlphabet.gsm8BitUnpackedToString(rawValue, - valueIndex, valueLen); - } else { - url = null; - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - // parse alpha identifier. - ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); - if (ctlv != null) { - confirmMsg.text = ValueParser.retrieveAlphaId(ctlv); - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - confirmMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - - // parse command qualifier value. - LaunchBrowserMode mode; - switch (cmdDet.commandQualifier) { - case 0x00: - default: - mode = LaunchBrowserMode.LAUNCH_IF_NOT_ALREADY_LAUNCHED; - break; - case 0x02: - mode = LaunchBrowserMode.USE_EXISTING_BROWSER; - break; - case 0x03: - mode = LaunchBrowserMode.LAUNCH_NEW_BROWSER; - break; - } - - mCmdParams = new LaunchBrowserParams(cmdDet, confirmMsg, url, mode); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes PLAY_TONE proactive command from the SIM card. - * - * @param cmdDet Command Details container object. - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required.t - * @throws ResultException - */ - private boolean processPlayTone(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - - StkLog.d(this, "process PlayTone"); - - Tone tone = null; - TextMessage textMsg = new TextMessage(); - Duration duration = null; - IconId iconId = null; - - ComprehensionTlv ctlv = searchForTag(ComprehensionTlvTag.TONE, ctlvs); - if (ctlv != null) { - // Nothing to do for null objects. - if (ctlv.getLength() > 0) { - try { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int toneVal = rawValue[valueIndex]; - tone = Tone.fromInt(toneVal); - } catch (IndexOutOfBoundsException e) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - } - // parse alpha identifier - ctlv = searchForTag(ComprehensionTlvTag.ALPHA_ID, ctlvs); - if (ctlv != null) { - textMsg.text = ValueParser.retrieveAlphaId(ctlv); - } - // parse tone duration - ctlv = searchForTag(ComprehensionTlvTag.DURATION, ctlvs); - if (ctlv != null) { - duration = ValueParser.retrieveDuration(ctlv); - } - // parse icon identifier - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - iconId = ValueParser.retrieveIconId(ctlv); - textMsg.iconSelfExplanatory = iconId.selfExplanatory; - } - - boolean vibrate = (cmdDet.commandQualifier & 0x01) != 0x00; - - textMsg.responseNeeded = false; - mCmdParams = new PlayToneParams(cmdDet, textMsg, tone, duration, vibrate); - - if (iconId != null) { - mIconLoadState = LOAD_SINGLE_ICON; - mIconLoader.loadIcon(iconId.recordNumber, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } - - /** - * Processes SETUP_CALL proactive command from the SIM card. - * - * @param cmdDet Command Details object retrieved from the proactive command - * object - * @param ctlvs List of ComprehensionTlv objects following Command Details - * object and Device Identities object within the proactive command - * @return true if the command is processing is pending and additional - * asynchronous processing is required. - */ - private boolean processSetupCall(CommandDetails cmdDet, - List<ComprehensionTlv> ctlvs) throws ResultException { - StkLog.d(this, "process SetupCall"); - - Iterator<ComprehensionTlv> iter = ctlvs.iterator(); - ComprehensionTlv ctlv = null; - // User confirmation phase message. - TextMessage confirmMsg = new TextMessage(); - // Call set up phase message. - TextMessage callMsg = new TextMessage(); - IconId confirmIconId = null; - IconId callIconId = null; - - // get confirmation message string. - ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter); - if (ctlv != null) { - confirmMsg.text = ValueParser.retrieveAlphaId(ctlv); - } - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - confirmIconId = ValueParser.retrieveIconId(ctlv); - confirmMsg.iconSelfExplanatory = confirmIconId.selfExplanatory; - } - - // get call set up message string. - ctlv = searchForNextTag(ComprehensionTlvTag.ALPHA_ID, iter); - if (ctlv != null) { - callMsg.text = ValueParser.retrieveAlphaId(ctlv); - } - - ctlv = searchForTag(ComprehensionTlvTag.ICON_ID, ctlvs); - if (ctlv != null) { - callIconId = ValueParser.retrieveIconId(ctlv); - callMsg.iconSelfExplanatory = callIconId.selfExplanatory; - } - - mCmdParams = new CallSetupParams(cmdDet, confirmMsg, callMsg); - - if (confirmIconId != null || callIconId != null) { - mIconLoadState = LOAD_MULTI_ICONS; - int[] recordNumbers = new int[2]; - recordNumbers[0] = confirmIconId != null - ? confirmIconId.recordNumber : -1; - recordNumbers[1] = callIconId != null ? callIconId.recordNumber - : -1; - - mIconLoader.loadIcons(recordNumbers, this - .obtainMessage(MSG_ID_LOAD_ICON_DONE)); - return true; - } - return false; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java b/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java deleted file mode 100644 index 833ff3c..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ComprehensionTlv.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -import java.util.ArrayList; -import java.util.List; - - -/** - * Class for representing COMPREHENSION-TLV objects. - * - * @see "ETSI TS 101 220 subsection 7.1.1" - * - * {@hide} - */ -class ComprehensionTlv { - private int mTag; - private boolean mCr; - private int mLength; - private int mValueIndex; - private byte[] mRawValue; - - /** - * Constructor. Private on purpose. Use - * {@link #decodeMany(byte[], int) decodeMany} or - * {@link #decode(byte[], int) decode} method. - * - * @param tag The tag for this object - * @param cr Comprehension Required flag - * @param length Length of the value - * @param data Byte array containing the value - * @param valueIndex Index in data at which the value starts - */ - protected ComprehensionTlv(int tag, boolean cr, int length, byte[] data, - int valueIndex) { - mTag = tag; - mCr = cr; - mLength = length; - mValueIndex = valueIndex; - mRawValue = data; - } - - public int getTag() { - return mTag; - } - - public boolean isComprehensionRequired() { - return mCr; - } - - public int getLength() { - return mLength; - } - - public int getValueIndex() { - return mValueIndex; - } - - public byte[] getRawValue() { - return mRawValue; - } - - /** - * Parses a list of COMPREHENSION-TLV objects from a byte array. - * - * @param data A byte array containing data to be parsed - * @param startIndex Index in data at which to start parsing - * @return A list of COMPREHENSION-TLV objects parsed - * @throws ResultException - */ - public static List<ComprehensionTlv> decodeMany(byte[] data, int startIndex) - throws ResultException { - ArrayList<ComprehensionTlv> items = new ArrayList<ComprehensionTlv>(); - int endIndex = data.length; - while (startIndex < endIndex) { - ComprehensionTlv ctlv = ComprehensionTlv.decode(data, startIndex); - items.add(ctlv); - startIndex = ctlv.mValueIndex + ctlv.mLength; - } - - return items; - } - - /** - * Parses an COMPREHENSION-TLV object from a byte array. - * - * @param data A byte array containing data to be parsed - * @param startIndex Index in data at which to start parsing - * @return A COMPREHENSION-TLV object parsed - * @throws ResultException - */ - public static ComprehensionTlv decode(byte[] data, int startIndex) - throws ResultException { - try { - int curIndex = startIndex; - int endIndex = data.length; - - /* tag */ - int tag; - boolean cr; // Comprehension required flag - int temp = data[curIndex++] & 0xff; - switch (temp) { - case 0: - case 0xff: - case 0x80: - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - - case 0x7f: // tag is in three-byte format - tag = ((data[curIndex] & 0xff) << 8) - | (data[curIndex + 1] & 0xff); - cr = (tag & 0x8000) != 0; - tag &= ~0x8000; - curIndex += 2; - break; - - default: // tag is in single-byte format - tag = temp; - cr = (tag & 0x80) != 0; - tag &= ~0x80; - break; - } - - /* length */ - int length; - temp = data[curIndex++] & 0xff; - if (temp < 0x80) { - length = temp; - } else if (temp == 0x81) { - length = data[curIndex++] & 0xff; - if (length < 0x80) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else if (temp == 0x82) { - length = ((data[curIndex] & 0xff) << 8) - | (data[curIndex + 1] & 0xff); - curIndex += 2; - if (length < 0x100) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else if (temp == 0x83) { - length = ((data[curIndex] & 0xff) << 16) - | ((data[curIndex + 1] & 0xff) << 8) - | (data[curIndex + 2] & 0xff); - curIndex += 3; - if (length < 0x10000) { - throw new ResultException( - ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } else { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return new ComprehensionTlv(tag, cr, length, data, curIndex); - - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java b/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java deleted file mode 100644 index 9d8cc97..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Duration.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -import android.os.Parcel; -import android.os.Parcelable; - - -/** - * Class for representing "Duration" object for STK. - * - * {@hide} - */ -public class Duration implements Parcelable { - public int timeInterval; - public TimeUnit timeUnit; - - public enum TimeUnit { - MINUTE(0x00), - SECOND(0x01), - TENTH_SECOND(0x02); - - private int mValue; - - TimeUnit(int value) { - mValue = value; - } - - public int value() { - return mValue; - } - } - - /** - * @param timeInterval Between 1 and 255 inclusive. - */ - public Duration(int timeInterval, TimeUnit timeUnit) { - this.timeInterval = timeInterval; - this.timeUnit = timeUnit; - } - - private Duration(Parcel in) { - timeInterval = in.readInt(); - timeUnit = TimeUnit.values()[in.readInt()]; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(timeInterval); - dest.writeInt(timeUnit.ordinal()); - } - - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<Duration> CREATOR = new Parcelable.Creator<Duration>() { - public Duration createFromParcel(Parcel in) { - return new Duration(in); - } - - public Duration[] newArray(int size) { - return new Duration[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java b/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java deleted file mode 100644 index bd4f49f..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/FontSize.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Enumeration for representing text font size. - * - * {@hide} - */ -public enum FontSize { - NORMAL(0x0), - LARGE(0x1), - SMALL(0x2); - - private int mValue; - - FontSize(int value) { - mValue = value; - } - - /** - * Create a FontSize object. - * @param value Integer value to be converted to a FontSize object. - * @return FontSize object whose value is {@code value}. If no - * FontSize object has that value, null is returned. - */ - public static FontSize fromInt(int value) { - for (FontSize e : FontSize.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java b/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java deleted file mode 100644 index a63d1ca..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/IconLoader.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -import com.android.internal.telephony.gsm.SIMFileHandler; - -import android.graphics.Bitmap; -import android.graphics.Color; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import java.util.HashMap; - -/** - * Class for loading icons from the SIM card. Has two states: single, for loading - * one icon. Multi, for loading icons list. - * - */ -class IconLoader extends Handler { - // members - private int mState = STATE_SINGLE_ICON; - private ImageDescriptor mId = null; - private Bitmap mCurrentIcon = null; - private int mRecordNumber; - private SIMFileHandler mSimFH = null; - private Message mEndMsg = null; - private byte[] mIconData = null; - // multi icons state members - private int[] mRecordNumbers = null; - private int mCurrentRecordIndex = 0; - private Bitmap[] mIcons = null; - private HashMap<Integer, Bitmap> mIconsCache = null; - - private static IconLoader sLoader = null; - - // Loader state values. - private static final int STATE_SINGLE_ICON = 1; - private static final int STATE_MULTI_ICONS = 2; - - // Finished loading single record from a linear-fixed EF-IMG. - private static final int EVENT_READ_EF_IMG_RECOED_DONE = 1; - // Finished loading single icon from a Transparent DF-Graphics. - private static final int EVENT_READ_ICON_DONE = 2; - // Finished loading single colour icon lookup table. - private static final int EVENT_READ_CLUT_DONE = 3; - - // Color lookup table offset inside the EF. - private static final int CLUT_LOCATION_OFFSET = 4; - // CLUT entry size, {Red, Green, Black} - private static final int CLUT_ENTRY_SIZE = 3; - - - private IconLoader(Looper looper , SIMFileHandler fh) { - super(looper); - mSimFH = fh; - - mIconsCache = new HashMap<Integer, Bitmap>(50); - } - - static IconLoader getInstance(Handler caller, SIMFileHandler fh) { - if (sLoader != null) { - return sLoader; - } - if (fh != null) { - HandlerThread thread = new HandlerThread("Stk Icon Loader"); - thread.start(); - return new IconLoader(thread.getLooper(), fh); - } - return null; - } - - void loadIcons(int[] recordNumbers, Message msg) { - if (recordNumbers == null || recordNumbers.length == 0 || msg == null) { - return; - } - mEndMsg = msg; - // initialize multi icons load variables. - mIcons = new Bitmap[recordNumbers.length]; - mRecordNumbers = recordNumbers; - mCurrentRecordIndex = 0; - mState = STATE_MULTI_ICONS; - startLoadingIcon(recordNumbers[0]); - } - - void loadIcon(int recordNumber, Message msg) { - if (msg == null) { - return; - } - mEndMsg = msg; - mState = STATE_SINGLE_ICON; - startLoadingIcon(recordNumber); - } - - private void startLoadingIcon(int recordNumber) { - // Reset the load variables. - mId = null; - mIconData = null; - mCurrentIcon = null; - mRecordNumber = recordNumber; - - // make sure the icon was not already loaded and saved in the local cache. - if (mIconsCache.containsKey(recordNumber)) { - mCurrentIcon = mIconsCache.get(recordNumber); - postIcon(); - return; - } - - // start the first phase ==> loading Image Descriptor. - readId(); - } - - @Override - public void handleMessage(Message msg) { - AsyncResult ar; - - try { - switch (msg.what) { - case EVENT_READ_EF_IMG_RECOED_DONE: - ar = (AsyncResult) msg.obj; - if (handleImageDescriptor((byte[]) ar.result)) { - readIconData(); - } else { - throw new Exception("Unable to parse image descriptor"); - } - break; - case EVENT_READ_ICON_DONE: - ar = (AsyncResult) msg.obj; - byte[] rawData = ((byte[]) ar.result); - if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_BASIC) { - mCurrentIcon = parseToBnW(rawData, rawData.length); - mIconsCache.put(mRecordNumber, mCurrentIcon); - postIcon(); - } else if (mId.codingScheme == ImageDescriptor.CODING_SCHEME_COLOUR) { - mIconData = rawData; - readClut(); - } - break; - case EVENT_READ_CLUT_DONE: - ar = (AsyncResult) msg.obj; - byte [] clut = ((byte[]) ar.result); - mCurrentIcon = parseToRGB(mIconData, mIconData.length, - false, clut); - mIconsCache.put(mRecordNumber, mCurrentIcon); - postIcon(); - break; - } - } catch (Exception e) { - StkLog.d(this, "Icon load failed"); - // post null icon back to the caller. - postIcon(); - } - } - - /** - * Handles Image descriptor parsing and required processing. This is the - * first step required to handle retrieving icons from the SIM. - * - * @param data byte [] containing Image Instance descriptor as defined in - * TS 51.011. - */ - private boolean handleImageDescriptor(byte[] rawData) { - mId = ImageDescriptor.parse(rawData, 1); - if (mId == null) { - return false; - } - return true; - } - - // Start reading colour lookup table from SIM card. - private void readClut() { - int length = mIconData[3] * CLUT_ENTRY_SIZE; - Message msg = this.obtainMessage(EVENT_READ_CLUT_DONE); - mSimFH.loadEFImgTransparent(mId.imageId, - mIconData[CLUT_LOCATION_OFFSET], - mIconData[CLUT_LOCATION_OFFSET + 1], length, msg); - } - - // Start reading Image Descriptor from SIM card. - private void readId() { - if (mRecordNumber < 0) { - mCurrentIcon = null; - postIcon(); - return; - } - Message msg = this.obtainMessage(EVENT_READ_EF_IMG_RECOED_DONE); - mSimFH.loadEFImgLinearFixed(mRecordNumber, msg); - } - - // Start reading icon bytes array from SIM card. - private void readIconData() { - Message msg = this.obtainMessage(EVENT_READ_ICON_DONE); - mSimFH.loadEFImgTransparent(mId.imageId, 0, 0, mId.length ,msg); - } - - // When all is done pass icon back to caller. - private void postIcon() { - if (mState == STATE_SINGLE_ICON) { - mEndMsg.obj = mCurrentIcon; - mEndMsg.sendToTarget(); - } else if (mState == STATE_MULTI_ICONS) { - mIcons[mCurrentRecordIndex++] = mCurrentIcon; - // If not all icons were loaded, start loading the next one. - if (mCurrentRecordIndex < mRecordNumbers.length) { - startLoadingIcon(mRecordNumbers[mCurrentRecordIndex]); - } else { - mEndMsg.obj = mIcons; - mEndMsg.sendToTarget(); - } - } - } - - /** - * Convert a TS 131.102 image instance of code scheme '11' into Bitmap - * @param data The raw data - * @param length The length of image body - * @return The bitmap - */ - public static Bitmap parseToBnW(byte[] data, int length){ - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int numOfPixels = width*height; - - int[] pixels = new int[numOfPixels]; - - int pixelIndex = 0; - int bitIndex = 7; - byte currentByte = 0x00; - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (pixelIndex % 8 == 0) { - currentByte = data[valueIndex++]; - bitIndex = 7; - } - pixels[pixelIndex++] = bitToBnW((currentByte >> bitIndex-- ) & 0x01); - } - - if (pixelIndex != numOfPixels) { - StkLog.d("IconLoader", "parseToBnW; size error"); - } - return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); - } - - /** - * Decode one bit to a black and white color: - * 0 is black - * 1 is white - * @param bit to decode - * @return RGB color - */ - private static int bitToBnW(int bit){ - if(bit == 1){ - return Color.WHITE; - } else { - return Color.BLACK; - } - } - - /** - * a TS 131.102 image instance of code scheme '11' into color Bitmap - * - * @param data The raw data - * @param length the length of image body - * @param transparency with or without transparency - * @param clut coulor lookup table - * @return The color bitmap - */ - public static Bitmap parseToRGB(byte[] data, int length, - boolean transparency, byte[] clut) { - int valueIndex = 0; - int width = data[valueIndex++] & 0xFF; - int height = data[valueIndex++] & 0xFF; - int bitsPerImg = data[valueIndex++] & 0xFF; - int numOfClutEntries = data[valueIndex++] & 0xFF; - - if (true == transparency) { - clut[numOfClutEntries - 1] = Color.TRANSPARENT; - } - - int numOfPixels = width * height; - int[] pixels = new int[numOfPixels]; - - valueIndex = 6; - int pixelIndex = 0; - int bitsStartOffset = 8 - bitsPerImg; - int bitIndex = bitsStartOffset; - byte currentByte = data[valueIndex++]; - int mask = getMask(bitsPerImg); - boolean bitsOverlaps = (8 % bitsPerImg == 0); - while (pixelIndex < numOfPixels) { - // reassign data and index for every byte (8 bits). - if (bitIndex < 0) { - currentByte = data[valueIndex++]; - bitIndex = bitsOverlaps ? (bitsStartOffset) : (bitIndex * -1); - } - int clutEntry = ((currentByte >> bitIndex) & mask); - int clutIndex = clutEntry * CLUT_ENTRY_SIZE; - pixels[pixelIndex++] = Color.rgb(clut[clutIndex], - clut[clutIndex + 1], clut[clutIndex + 2]); - bitIndex -= bitsPerImg; - } - - return Bitmap.createBitmap(pixels, width, height, - Bitmap.Config.ARGB_8888); - } - - /** - * Calculate bit mask for a given number of bits. The mask should enable to - * make a bitwise and to the given number of bits. - * @param numOfBits number of bits to calculate mask for. - * @return bit mask - */ - private static int getMask(int numOfBits) { - int mask = 0x00; - - switch (numOfBits) { - case 1: - mask = 0x01; - break; - case 2: - mask = 0x03; - break; - case 3: - mask = 0x07; - break; - case 4: - mask = 0x0F; - break; - case 5: - mask = 0x1F; - break; - case 6: - mask = 0x3F; - break; - case 7: - mask = 0x7F; - break; - case 8: - mask = 0xFF; - break; - } - return mask; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java b/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java deleted file mode 100644 index 7120a37..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ImageDescriptor.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -/** - * {@hide} - */ -public class ImageDescriptor { - // members - int width; - int height; - int codingScheme; - int imageId; - int highOffset; - int lowOffset; - int length; - - // constants - static final int CODING_SCHEME_BASIC = 0x11; - static final int CODING_SCHEME_COLOUR = 0x21; - - public static final int ID_LENGTH = 9; - - ImageDescriptor() { - width = 0; - height = 0; - codingScheme = 0; - imageId = 0; - highOffset = 0; - lowOffset = 0; - length = 0; - } - - /** - * Extract descriptor information about image instance. - * - * @param rawData - * @param valueIndex - * @return ImageDescriptor - */ - static ImageDescriptor parse(byte[] rawData, int valueIndex) { - ImageDescriptor d = new ImageDescriptor(); - try { - d.width = rawData[valueIndex++] & 0xff; - d.height = rawData[valueIndex++] & 0xff; - d.codingScheme = rawData[valueIndex++] & 0xff; - - // parse image id - d.imageId = (rawData[valueIndex++] & 0xff) << 8; - d.imageId |= rawData[valueIndex++] & 0xff; - // parse offset - d.highOffset = (rawData[valueIndex++] & 0xff); // high byte offset - d.lowOffset = rawData[valueIndex++] & 0xff; // low byte offset - - d.length = ((rawData[valueIndex++] & 0xff) << 8 | (rawData[valueIndex++] & 0xff)); - } catch (IndexOutOfBoundsException e) { - StkLog.d("ImageDescripter", "parse; failed parsing image descriptor"); - d = null; - } - return d; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java b/telephony/java/com/android/internal/telephony/gsm/stk/Input.java deleted file mode 100644 index 1f0d971..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Input.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Container class for STK GET INPUT, GET IN KEY commands parameters. - * - */ -public class Input implements Parcelable { - public String text; - public String defaultText; - public Bitmap icon; - public int minLen; - public int maxLen; - public boolean ucs2; - public boolean packed; - public boolean digitOnly; - public boolean echo; - public boolean yesNo; - public boolean helpAvailable; - - Input() { - text = ""; - defaultText = null; - icon = null; - minLen = 0; - maxLen = 1; - ucs2 = false; - packed = false; - digitOnly = false; - echo = false; - yesNo = false; - helpAvailable = false; - } - - private Input(Parcel in) { - text = in.readString(); - defaultText = in.readString(); - icon = in.readParcelable(null); - minLen = in.readInt(); - maxLen = in.readInt(); - ucs2 = in.readInt() == 1 ? true : false; - packed = in.readInt() == 1 ? true : false; - digitOnly = in.readInt() == 1 ? true : false; - echo = in.readInt() == 1 ? true : false; - yesNo = in.readInt() == 1 ? true : false; - helpAvailable = in.readInt() == 1 ? true : false; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(text); - dest.writeString(defaultText); - dest.writeParcelable(icon, 0); - dest.writeInt(minLen); - dest.writeInt(maxLen); - dest.writeInt(ucs2 ? 1 : 0); - dest.writeInt(packed ? 1 : 0); - dest.writeInt(digitOnly ? 1 : 0); - dest.writeInt(echo ? 1 : 0); - dest.writeInt(yesNo ? 1 : 0); - dest.writeInt(helpAvailable ? 1 : 0); - } - - public static final Parcelable.Creator<Input> CREATOR = new Parcelable.Creator<Input>() { - public Input createFromParcel(Parcel in) { - return new Input(in); - } - - public Input[] newArray(int size) { - return new Input[size]; - } - }; - - boolean setIcon(Bitmap Icon) { return true; } -}
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java b/telephony/java/com/android/internal/telephony/gsm/stk/Item.java deleted file mode 100644 index b2f338c..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Item.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Represents an Item COMPREHENSION-TLV object. - * - * {@hide} - */ -public class Item implements Parcelable { - /** Identifier of the item. */ - public int id; - /** Text string of the item. */ - public String text; - /** Icon of the item */ - public Bitmap icon; - - public Item(int id, String text) { - this.id = id; - this.text = text; - this.icon = null; - } - - public Item(Parcel in) { - id = in.readInt(); - text = in.readString(); - icon = in.readParcelable(null); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(id); - dest.writeString(text); - dest.writeParcelable(icon, flags); - } - - public static final Parcelable.Creator<Item> CREATOR = new Parcelable.Creator<Item>() { - public Item createFromParcel(Parcel in) { - return new Item(in); - } - - public Item[] newArray(int size) { - return new Item[size]; - } - }; - - public String toString() { - return text; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java b/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java deleted file mode 100644 index 302273c..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/LaunchBrowserMode.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Browser launch mode for LAUNCH BROWSER proactive command. - * - * {@hide} - */ -public enum LaunchBrowserMode { - /** Launch browser if not already launched. */ - LAUNCH_IF_NOT_ALREADY_LAUNCHED, - /** - * Use the existing browser (the browser shall not use the active existing - * secured session). - */ - USE_EXISTING_BROWSER, - /** Close the existing browser session and launch new browser session. */ - LAUNCH_NEW_BROWSER; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java b/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java deleted file mode 100644 index 40a6b37..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Menu.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; - -/** - * Container class for STK menu (SET UP MENU, SELECT ITEM) parameters. - * - */ -public class Menu implements Parcelable { - public List<Item> items; - public List<TextAttribute> titleAttrs; - public PresentationType presentationType; - public String title; - public Bitmap titleIcon; - public int defaultItem; - public boolean softKeyPreferred; - public boolean helpAvailable; - public boolean titleIconSelfExplanatory; - public boolean itemsIconSelfExplanatory; - - public Menu() { - // Create an empty list. - items = new ArrayList<Item>(); - title = null; - titleAttrs = null; - defaultItem = 0; - softKeyPreferred = false; - helpAvailable = false; - titleIconSelfExplanatory = false; - itemsIconSelfExplanatory = false; - titleIcon = null; - // set default style to be navigation menu. - presentationType = PresentationType.NAVIGATION_OPTIONS; - } - - private Menu(Parcel in) { - title = in.readString(); - titleIcon = in.readParcelable(null); - // rebuild items list. - items = new ArrayList<Item>(); - int size = in.readInt(); - for (int i=0; i<size; i++) { - Item item = in.readParcelable(null); - items.add(item); - } - defaultItem = in.readInt(); - softKeyPreferred = in.readInt() == 1 ? true : false; - helpAvailable = in.readInt() == 1 ? true : false; - titleIconSelfExplanatory = in.readInt() == 1 ? true : false; - itemsIconSelfExplanatory = in.readInt() == 1 ? true : false; - presentationType = PresentationType.values()[in.readInt()]; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(title); - dest.writeParcelable(titleIcon, flags); - // write items list to the parcel. - int size = items.size(); - dest.writeInt(size); - for (int i=0; i<size; i++) { - dest.writeParcelable(items.get(i), flags); - } - dest.writeInt(defaultItem); - dest.writeInt(softKeyPreferred ? 1 : 0); - dest.writeInt(helpAvailable ? 1 : 0); - dest.writeInt(titleIconSelfExplanatory ? 1 : 0); - dest.writeInt(itemsIconSelfExplanatory ? 1 : 0); - dest.writeInt(presentationType.ordinal()); - } - - public static final Parcelable.Creator<Menu> CREATOR = new Parcelable.Creator<Menu>() { - public Menu createFromParcel(Parcel in) { - return new Menu(in); - } - - public Menu[] newArray(int size) { - return new Menu[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java b/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java deleted file mode 100644 index 71bdcdc..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/PresentationType.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Presentation types for SELECT TYPE proactive command. - * - * {@hide} - */ -public enum PresentationType { - /** Presentation type is not specified */ - NOT_SPECIFIED, - /** Presentation as a choice of data values */ - DATA_VALUES, - /** Presentation as a choice of navigation options */ - NAVIGATION_OPTIONS; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java deleted file mode 100644 index 9afa063..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ResponseData.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2006-2007 Google Inc. - * - * 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.stk; - -import com.android.internal.telephony.gsm.EncodeException; -import com.android.internal.telephony.gsm.GsmAlphabet; - -import java.io.ByteArrayOutputStream; -import java.io.UnsupportedEncodingException; - -abstract class ResponseData { - /** - * Format the data appropriate for TERMINAL RESPONSE and write it into - * the ByteArrayOutputStream object. - */ - public abstract void format(ByteArrayOutputStream buf); -} - -class SelectItemResponseData extends ResponseData { - // members - private int id; - - public SelectItemResponseData(int id) { - super(); - this.id = id; - } - - @Override - public void format(ByteArrayOutputStream buf) { - // Item identifier object - int tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); - buf.write(tag); // tag - buf.write(1); // length - buf.write(id); // identifier of item chosen - } -} - -class GetInkeyInputResponseData extends ResponseData { - // members - private boolean mIsUcs2; - private boolean mIsPacked; - private boolean mIsYesNo; - private boolean mYesNoResponse; - public String mInData; - - // GetInKey Yes/No response characters constants. - protected static final byte GET_INKEY_YES = 0x01; - protected static final byte GET_INKEY_NO = 0x00; - - public GetInkeyInputResponseData(String inData, boolean ucs2, boolean packed) { - super(); - this.mIsUcs2 = ucs2; - this.mIsPacked = packed; - this.mInData = inData; - this.mIsYesNo = false; - } - - public GetInkeyInputResponseData(boolean yesNoResponse) { - super(); - this.mIsUcs2 = false; - this.mIsPacked = false; - this.mInData = ""; - this.mIsYesNo = true; - this.mYesNoResponse = yesNoResponse; - } - - @Override - public void format(ByteArrayOutputStream buf) { - if (buf == null) { - return; - } - - // Text string object - int tag = 0x80 | ComprehensionTlvTag.TEXT_STRING.value(); - buf.write(tag); // tag - - byte[] data; - - if (mIsYesNo) { - data = new byte[1]; - data[0] = mYesNoResponse ? GET_INKEY_YES : GET_INKEY_NO; - } else if (mInData != null && mInData.length() > 0) { - try { - if (mIsUcs2) { - data = mInData.getBytes("UTF-16"); - } else if (mIsPacked) { - int size = mInData.length(); - - byte[] tempData = GsmAlphabet - .stringToGsm7BitPacked(mInData); - data = new byte[size]; - // Since stringToGsm7BitPacked() set byte 0 in the - // returned byte array to the count of septets used... - // copy to a new array without byte 0. - System.arraycopy(tempData, 1, data, 0, size); - } else { - data = GsmAlphabet.stringToGsm8BitPacked(mInData); - } - } catch (UnsupportedEncodingException e) { - data = new byte[0]; - } catch (EncodeException e) { - data = new byte[0]; - } - } else { - data = new byte[0]; - } - - // length - one more for data coding scheme. - buf.write(data.length + 1); - - // data coding scheme - if (mIsUcs2) { - buf.write(0x08); // UCS2 - } else if (mIsPacked) { - buf.write(0x00); // 7 bit packed - } else { - buf.write(0x04); // 8 bit unpacked - } - - for (byte b : data) { - buf.write(b); - } - } -} - - diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java deleted file mode 100644 index b96a524..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultCode.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Enumeration for the return code in TERMINAL RESPONSE. - * To get the actual return code for each enum value, call {@link #code() code} - * method. - * - * {@hide} - */ -public enum ResultCode { - - /* - * Results '0X' and '1X' indicate that the command has been performed. - */ - - /** Command performed successfully */ - OK(0x00), - - /** Command performed with partial comprehension */ - PRFRMD_WITH_PARTIAL_COMPREHENSION(0x01), - - /** Command performed, with missing information */ - PRFRMD_WITH_MISSING_INFO(0x02), - - /** REFRESH performed with additional EFs read */ - PRFRMD_WITH_ADDITIONAL_EFS_READ(0x03), - - /** - * Command performed successfully, but requested icon could not be - * displayed - */ - PRFRMD_ICON_NOT_DISPLAYED(0x04), - - /** Command performed, but modified by call control by NAA */ - PRFRMD_MODIFIED_BY_NAA(0x05), - - /** Command performed successfully, limited service */ - PRFRMD_LIMITED_SERVICE(0x06), - - /** Command performed with modification */ - PRFRMD_WITH_MODIFICATION(0x07), - - /** REFRESH performed but indicated NAA was not active */ - PRFRMD_NAA_NOT_ACTIVE(0x08), - - /** Command performed successfully, tone not played */ - PRFRMD_TONE_NOT_PLAYED(0x09), - - /** Proactive UICC session terminated by the user */ - UICC_SESSION_TERM_BY_USER(0x10), - - /** Backward move in the proactive UICC session requested by the user */ - BACKWARD_MOVE_BY_USER(0x11), - - /** No response from user */ - NO_RESPONSE_FROM_USER(0x12), - - /** Help information required by the user */ - HELP_INFO_REQUIRED(0x13), - - /** USSD or SS transaction terminated by the user */ - USSD_SS_SESSION_TERM_BY_USER(0x14), - - - /* - * Results '2X' indicate to the UICC that it may be worth re-trying the - * command at a later opportunity. - */ - - /** Terminal currently unable to process command */ - TERMINAL_CRNTLY_UNABLE_TO_PROCESS(0x20), - - /** Network currently unable to process command */ - NETWORK_CRNTLY_UNABLE_TO_PROCESS(0x21), - - /** User did not accept the proactive command */ - USER_NOT_ACCEPT(0x22), - - /** User cleared down call before connection or network release */ - USER_CLEAR_DOWN_CALL(0x23), - - /** Action in contradiction with the current timer state */ - CONTRADICTION_WITH_TIMER(0x24), - - /** Interaction with call control by NAA, temporary problem */ - NAA_CALL_CONTROL_TEMPORARY(0x25), - - /** Launch browser generic error code */ - LAUNCH_BROWSER_ERROR(0x26), - - /** MMS temporary problem. */ - MMS_TEMPORARY(0x27), - - - /* - * Results '3X' indicate that it is not worth the UICC re-trying with an - * identical command, as it will only get the same response. However, the - * decision to retry lies with the application. - */ - - /** Command beyond terminal's capabilities */ - BEYOND_TERMINAL_CAPABILITY(0x30), - - /** Command type not understood by terminal */ - CMD_TYPE_NOT_UNDERSTOOD(0x31), - - /** Command data not understood by terminal */ - CMD_DATA_NOT_UNDERSTOOD(0x32), - - /** Command number not known by terminal */ - CMD_NUM_NOT_KNOWN(0x33), - - /** SS Return Error */ - SS_RETURN_ERROR(0x34), - - /** SMS RP-ERROR */ - SMS_RP_ERROR(0x35), - - /** Error, required values are missing */ - REQUIRED_VALUES_MISSING(0x36), - - /** USSD Return Error */ - USSD_RETURN_ERROR(0x37), - - /** MultipleCard commands error */ - MULTI_CARDS_CMD_ERROR(0x38), - - /** - * Interaction with call control by USIM or MO short message control by - * USIM, permanent problem - */ - USIM_CALL_CONTROL_PERMANENT(0x39), - - /** Bearer Independent Protocol error */ - BIP_ERROR(0x3a), - - /** Access Technology unable to process command */ - ACCESS_TECH_UNABLE_TO_PROCESS(0x3b), - - /** Frames error */ - FRAMES_ERROR(0x3c), - - /** MMS Error */ - MMS_ERROR(0x3d); - - - private int mCode; - - ResultCode(int code) { - mCode = code; - } - - /** - * Retrieves the actual result code that this object represents. - * @return Actual result code - */ - public int value() { - return mCode; - } - - public static ResultCode fromInt(int value) { - for (ResultCode r : ResultCode.values()) { - if (r.mCode == value) { - return r; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java b/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java deleted file mode 100644 index 2eb16c9..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ResultException.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Class for errors in the Result object. - * - * {@hide} - */ -public class ResultException extends StkException { - private ResultCode mResult; - private int mAdditionalInfo; - - public ResultException(ResultCode result) { - super(); - - // ETSI TS 102 223, 8.12 -- For the general results '20', '21', '26', - // '38', '39', '3A', '3C', and '3D', it is mandatory for the terminal - // to provide a specific cause value as additional information. - switch (result) { - case TERMINAL_CRNTLY_UNABLE_TO_PROCESS: // 0x20 - case NETWORK_CRNTLY_UNABLE_TO_PROCESS: // 0x21 - case LAUNCH_BROWSER_ERROR: // 0x26 - case MULTI_CARDS_CMD_ERROR: // 0x38 - case USIM_CALL_CONTROL_PERMANENT: // 0x39 - case BIP_ERROR: // 0x3a - case FRAMES_ERROR: // 0x3c - case MMS_ERROR: // 0x3d - throw new AssertionError( - "For result code, " + result + - ", additional information must be given!"); - } - - mResult = result; - mAdditionalInfo = -1; - } - - public ResultException(ResultCode result, int additionalInfo) { - super(); - - if (additionalInfo < 0) { - throw new AssertionError( - "Additional info must be greater than zero!"); - } - - mResult = result; - mAdditionalInfo = additionalInfo; - } - - public ResultCode result() { - return mResult; - } - - public boolean hasAdditionalInfo() { - return mAdditionalInfo >= 0; - } - - public int additionalInfo() { - return mAdditionalInfo; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java b/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java deleted file mode 100644 index 5d82473..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/RilMessageDecoder.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import com.android.internal.telephony.gsm.SIMFileHandler; -import com.android.internal.telephony.gsm.SimUtils; - -import android.os.Handler; -import android.os.HandlerState; -import android.os.HandlerStateMachine; -import android.os.Message; - -/** - * Class used for queuing raw ril messages, decoding them into CommanParams - * objects and sending the result back to the STK Service. - */ -class RilMessageDecoder extends HandlerStateMachine { - - // constants - private static final int START = 1; - private static final int CMD_PARAMS_READY = 2; - - // members - private static RilMessageDecoder sInstance = null; - private CommandParamsFactory mCmdParamsFactory = null; - private RilMessage mCurrentRilMessage = null; - private Handler mCaller = null; - - // States - private StateStart mStateStart = new StateStart(); - private StateCmdParamsReady mStateCmdParamsReady = new StateCmdParamsReady(); - - /** - * Get the singleton instance, constructing if necessary. - * - * @param caller - * @param fh - * @return RilMesssageDecoder - */ - public static synchronized RilMessageDecoder getInstance(Handler caller, SIMFileHandler fh) { - if (sInstance == null) { - sInstance = new RilMessageDecoder(caller, fh); - } - return sInstance; - } - - /** - * Start decoding the message parameters, - * when complete MSG_ID_RIL_MSG_DECODED will be returned to caller. - * - * @param rilMsg - */ - public void sendStartDecodingMessageParams(RilMessage rilMsg) { - Message msg = obtainMessage(START); - msg.obj = rilMsg; - sendMessage(msg); - } - - /** - * The command parameters have been decoded. - * - * @param resCode - * @param cmdParams - */ - public void sendMessageParamsDecoded(ResultCode resCode, CommandParams cmdParams) { - Message msg = obtainMessage(RilMessageDecoder.CMD_PARAMS_READY); - msg.arg1 = resCode.value(); - msg.obj = cmdParams; - sendMessage(msg); - } - - private void sendCmdForExecution(RilMessage rilMsg) { - Message msg = mCaller.obtainMessage(StkService.MSG_ID_RIL_MSG_DECODED, - new RilMessage(rilMsg)); - msg.sendToTarget(); - } - - private RilMessageDecoder(Handler caller, SIMFileHandler fh) { - super("RilMessageDecoder"); - setDbg(false); - setInitialState(mStateStart); - - mCaller = caller; - mCmdParamsFactory = CommandParamsFactory.getInstance(this, fh); - } - - private class StateStart extends HandlerState { - @Override public void processMessage(Message msg) { - if (msg.what == START) { - if (decodeMessageParams((RilMessage)msg.obj)) { - transitionTo(mStateCmdParamsReady); - } - } else { - StkLog.d(this, "StateStart unexpected expecting START=" + - START + " got " + msg.what); - } - } - } - - private class StateCmdParamsReady extends HandlerState { - @Override public void processMessage(Message msg) { - if (msg.what == CMD_PARAMS_READY) { - mCurrentRilMessage.mResCode = ResultCode.fromInt(msg.arg1); - mCurrentRilMessage.mData = msg.obj; - sendCmdForExecution(mCurrentRilMessage); - transitionTo(mStateStart); - } else { - StkLog.d(this, "StateCmdParamsReady expecting CMD_PARAMS_READY=" - + CMD_PARAMS_READY + " got " + msg.what); - deferMessage(msg); - } - } - } - - private boolean decodeMessageParams(RilMessage rilMsg) { - boolean decodingStarted; - - mCurrentRilMessage = rilMsg; - switch(rilMsg.mId) { - case StkService.MSG_ID_SESSION_END: - case StkService.MSG_ID_CALL_SETUP: - mCurrentRilMessage.mResCode = ResultCode.OK; - sendCmdForExecution(mCurrentRilMessage); - decodingStarted = false; - break; - case StkService.MSG_ID_PROACTIVE_COMMAND: - case StkService.MSG_ID_EVENT_NOTIFY: - case StkService.MSG_ID_REFRESH: - byte[] rawData = null; - try { - rawData = SimUtils.hexStringToBytes((String) rilMsg.mData); - } catch (Exception e) { - // zombie messages are dropped - StkLog.d(this, "decodeMessageParams dropping zombie messages"); - decodingStarted = false; - break; - } - try { - // Start asynch parsing of the command parameters. - mCmdParamsFactory.make(BerTlv.decode(rawData)); - decodingStarted = true; - } catch (ResultException e) { - // send to Service for proper RIL communication. - mCurrentRilMessage.mResCode = e.result(); - sendCmdForExecution(mCurrentRilMessage); - decodingStarted = false; - } - break; - default: - decodingStarted = false; - break; - } - return decodingStarted; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java deleted file mode 100644 index 62a778e..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkCmdMessage.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Class used to pass STK messages from telephony to application. Application - * should call getXXX() to get commands's specific values. - * - */ -public class StkCmdMessage implements Parcelable { - // members - CommandDetails mCmdDet; - private TextMessage mTextMsg; - private Menu mMenu; - private Input mInput; - private BrowserSettings mBrowserSettings = null; - private ToneSettings mToneSettings = null; - private CallSettings mCallSettings = null; - - /* - * Container for Launch Browser command settings. - */ - public class BrowserSettings { - public String url; - public LaunchBrowserMode mode; - } - - /* - * Container for Call Setup command settings. - */ - public class CallSettings { - public TextMessage confirmMsg; - public TextMessage callMsg; - } - - StkCmdMessage(CommandParams cmdParams) { - mCmdDet = cmdParams.cmdDet; - switch(getCmdType()) { - case SET_UP_MENU: - case SELECT_ITEM: - mMenu = ((SelectItemParams) cmdParams).menu; - break; - case DISPLAY_TEXT: - case SET_UP_IDLE_MODE_TEXT: - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - mTextMsg = ((DisplayTextParams) cmdParams).textMsg; - break; - case GET_INPUT: - case GET_INKEY: - mInput = ((GetInputParams) cmdParams).input; - break; - case LAUNCH_BROWSER: - mTextMsg = ((LaunchBrowserParams) cmdParams).confirmMsg; - mBrowserSettings = new BrowserSettings(); - mBrowserSettings.url = ((LaunchBrowserParams) cmdParams).url; - mBrowserSettings.mode = ((LaunchBrowserParams) cmdParams).mode; - break; - case PLAY_TONE: - PlayToneParams params = (PlayToneParams) cmdParams; - mToneSettings = params.settings; - mTextMsg = params.textMsg; - break; - case SET_UP_CALL: - mCallSettings = new CallSettings(); - mCallSettings.confirmMsg = ((CallSetupParams) cmdParams).confirmMsg; - mCallSettings.callMsg = ((CallSetupParams) cmdParams).callMsg; - break; - } - } - - public StkCmdMessage(Parcel in) { - mCmdDet = in.readParcelable(null); - mTextMsg = in.readParcelable(null); - mMenu = in.readParcelable(null); - mInput = in.readParcelable(null); - switch (getCmdType()) { - case LAUNCH_BROWSER: - mBrowserSettings = new BrowserSettings(); - mBrowserSettings.url = in.readString(); - mBrowserSettings.mode = LaunchBrowserMode.values()[in.readInt()]; - break; - case PLAY_TONE: - mToneSettings = in.readParcelable(null); - break; - case SET_UP_CALL: - mCallSettings = new CallSettings(); - mCallSettings.confirmMsg = in.readParcelable(null); - mCallSettings.callMsg = in.readParcelable(null); - break; - } - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(mCmdDet, 0); - dest.writeParcelable(mTextMsg, 0); - dest.writeParcelable(mMenu, 0); - dest.writeParcelable(mInput, 0); - switch(getCmdType()) { - case LAUNCH_BROWSER: - dest.writeString(mBrowserSettings.url); - dest.writeInt(mBrowserSettings.mode.ordinal()); - break; - case PLAY_TONE: - dest.writeParcelable(mToneSettings, 0); - break; - case SET_UP_CALL: - dest.writeParcelable(mCallSettings.confirmMsg, 0); - dest.writeParcelable(mCallSettings.callMsg, 0); - break; - } - } - - public static final Parcelable.Creator<StkCmdMessage> CREATOR = new Parcelable.Creator<StkCmdMessage>() { - public StkCmdMessage createFromParcel(Parcel in) { - return new StkCmdMessage(in); - } - - public StkCmdMessage[] newArray(int size) { - return new StkCmdMessage[size]; - } - }; - - public int describeContents() { - return 0; - } - - /* external API to be used by application */ - public AppInterface.CommandType getCmdType() { - return AppInterface.CommandType.fromInt(mCmdDet.typeOfCommand); - } - - public Menu getMenu() { - return mMenu; - } - - public Input geInput() { - return mInput; - } - - public TextMessage geTextMessage() { - return mTextMsg; - } - - public BrowserSettings getBrowserSettings() { - return mBrowserSettings; - } - - public ToneSettings getToneSettings() { - return mToneSettings; - } - - public CallSettings getCallSettings() { - return mCallSettings; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java deleted file mode 100644 index 86de366..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -import android.util.AndroidException; - - -/** - * Base class for all the exceptions in STK service. - * - * {@hide} - */ -class StkException extends AndroidException { - public StkException() { - super(); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java deleted file mode 100644 index f6e5685..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkLog.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.util.Log; - -public abstract class StkLog { - static final boolean DEBUG = true; - - public static void d(Object caller, String msg) { - if (!DEBUG) { - return; - } - - String className = caller.getClass().getName(); - Log.d("STK", className.substring(className.lastIndexOf('.') + 1) + ": " - + msg); - } - - public static void d(String caller, String msg) { - if (!DEBUG) { - return; - } - - Log.d("STK", caller + ": " + msg); - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java deleted file mode 100644 index 04a52e6..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkResponseMessage.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 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.stk; - -public class StkResponseMessage { - CommandDetails cmdDet = null; - ResultCode resCode = ResultCode.OK; - int usersMenuSelection = 0; - String usersInput = null; - boolean usersYesNoSelection = false; - boolean usersConfirm = false; - - public StkResponseMessage(StkCmdMessage cmdMsg) { - this.cmdDet = cmdMsg.mCmdDet; - } - - public void setResultCode(ResultCode resCode) { - this.resCode = resCode; - } - - public void setMenuSelection(int selection) { - this.usersMenuSelection = selection; - } - - public void setInput(String input) { - this.usersInput = input; - } - - public void setYesNo(boolean yesNo) { - usersYesNoSelection = yesNo; - } - - public void setConfirmation(boolean confirm) { - usersConfirm = confirm; - } - - CommandDetails getCmdDetails() { - return cmdDet; - } - }
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java b/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java deleted file mode 100644 index c0c4ceb..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/StkService.java +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.content.Context; -import android.content.Intent; -import android.os.AsyncResult; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Message; - -import com.android.internal.telephony.gsm.CommandsInterface; -import com.android.internal.telephony.gsm.GsmSimCard; -import com.android.internal.telephony.gsm.SIMFileHandler; -import com.android.internal.telephony.gsm.SIMRecords; -import com.android.internal.telephony.gsm.SimUtils; - -import android.util.Config; - -import java.io.ByteArrayOutputStream; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -/** - * Enumeration for representing the tag value of COMPREHENSION-TLV objects. If - * you want to get the actual value, call {@link #value() value} method. - * - * {@hide} - */ -enum ComprehensionTlvTag { - COMMAND_DETAILS(0x01), - DEVICE_IDENTITIES(0x02), - RESULT(0x03), - DURATION(0x04), - ALPHA_ID(0x05), - USSD_STRING(0x0a), - TEXT_STRING(0x0d), - TONE(0x0e), - ITEM(0x0f), - ITEM_ID(0x10), - RESPONSE_LENGTH(0x11), - FILE_LIST(0x12), - HELP_REQUEST(0x15), - DEFAULT_TEXT(0x17), - EVENT_LIST(0x19), - ICON_ID(0x1e), - ITEM_ICON_ID_LIST(0x1f), - IMMEDIATE_RESPONSE(0x2b), - LANGUAGE(0x2d), - URL(0x31), - BROWSER_TERMINATION_CAUSE(0x34), - TEXT_ATTRIBUTE(0x50); - - private int mValue; - - ComprehensionTlvTag(int value) { - mValue = value; - } - - /** - * Returns the actual value of this COMPREHENSION-TLV object. - * - * @return Actual tag value of this object - */ - public int value() { - return mValue; - } - - public static ComprehensionTlvTag fromInt(int value) { - for (ComprehensionTlvTag e : ComprehensionTlvTag.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} - -class RilMessage { - int mId; - Object mData; - ResultCode mResCode; - - RilMessage(int msgId, String rawData) { - mId = msgId; - mData = rawData; - } - - RilMessage(RilMessage other) { - this.mId = other.mId; - this.mData = other.mData; - this.mResCode = other.mResCode; - } -} - -/** - * Class that implements SIM Toolkit Telephony Service. Interacts with the RIL - * and application. - * - * {@hide} - */ -public class StkService extends Handler implements AppInterface { - - // Service members. - private static StkService sInstance; - private CommandsInterface mCmdIf; - private SIMRecords mSimRecords; - private Context mContext; - private StkCmdMessage mCurrntCmd = null; - private StkCmdMessage mMenuCmd = null; - - private RilMessageDecoder mMsgDecoder = null; - - // Service constants. - static final int MSG_ID_SESSION_END = 1; - static final int MSG_ID_PROACTIVE_COMMAND = 2; - static final int MSG_ID_EVENT_NOTIFY = 3; - static final int MSG_ID_CALL_SETUP = 4; - static final int MSG_ID_REFRESH = 5; - static final int MSG_ID_RESPONSE = 6; - - static final int MSG_ID_RIL_MSG_DECODED = 10; - - // Events to signal SIM presence or absent in the device. - private static final int MSG_ID_SIM_LOADED = 20; - - private static final int DEV_ID_KEYPAD = 0x01; - private static final int DEV_ID_DISPLAY = 0x02; - private static final int DEV_ID_EARPIECE = 0x03; - private static final int DEV_ID_UICC = 0x81; - private static final int DEV_ID_TERMINAL = 0x82; - private static final int DEV_ID_NETWORK = 0x83; - - /* Intentionally private for singleton */ - private StkService(CommandsInterface ci, SIMRecords sr, Context context, - SIMFileHandler fh, GsmSimCard sc) { - if (ci == null || sr == null || context == null || fh == null - || sc == null) { - throw new NullPointerException( - "Service: Input parameters must not be null"); - } - mCmdIf = ci; - mContext = context; - - // Get the RilMessagesDecoder for decoding the messages. - mMsgDecoder = RilMessageDecoder.getInstance(this, fh); - - // Register ril events handling. - mCmdIf.setOnStkSessionEnd(this, MSG_ID_SESSION_END, null); - mCmdIf.setOnStkProactiveCmd(this, MSG_ID_PROACTIVE_COMMAND, null); - mCmdIf.setOnStkEvent(this, MSG_ID_EVENT_NOTIFY, null); - mCmdIf.setOnStkCallSetUp(this, MSG_ID_CALL_SETUP, null); - //mCmdIf.setOnSimRefresh(this, MSG_ID_REFRESH, null); - - mSimRecords = sr; - - // Register for SIM ready event. - mSimRecords.registerForRecordsLoaded(this, MSG_ID_SIM_LOADED, null); - } - - private void handleRilMsg(RilMessage rilMsg) { - if (rilMsg == null) { - return; - } - - // dispatch messages - CommandParams cmdParams = null; - switch (rilMsg.mId) { - case MSG_ID_EVENT_NOTIFY: - if (rilMsg.mResCode == ResultCode.OK) { - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - handleProactiveCommand(cmdParams); - } - } - break; - case MSG_ID_PROACTIVE_COMMAND: - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - if (rilMsg.mResCode == ResultCode.OK) { - handleProactiveCommand(cmdParams); - } else { - // for proactive commands that couldn't be decoded - // successfully respond with the code generated by the - // message decoder. - sendTerminalResponse(cmdParams.cmdDet, rilMsg.mResCode, - false, 0, null); - } - } - break; - case MSG_ID_REFRESH: - cmdParams = (CommandParams) rilMsg.mData; - if (cmdParams != null) { - handleProactiveCommand(cmdParams); - } - break; - case MSG_ID_SESSION_END: - handleSessionEnd(); - break; - case MSG_ID_CALL_SETUP: - // prior event notify command supplied all the information - // needed for set up call processing. - break; - } - } - - /** - * Handles RIL_UNSOL_STK_PROACTIVE_COMMAND unsolicited command from RIL. - * Sends valid proactive command data to the application using intents. - * - */ - private void handleProactiveCommand(CommandParams cmdParams) { - StkLog.d(this, cmdParams.getCommandType().name()); - - StkCmdMessage cmdMsg = new StkCmdMessage(cmdParams); - switch (cmdParams.getCommandType()) { - case SET_UP_MENU: - if (removeMenu(cmdMsg.getMenu())) { - mMenuCmd = null; - } else { - mMenuCmd = cmdMsg; - } - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, 0, - null); - break; - case DISPLAY_TEXT: - // when application is not required to respond, send an immediate - // response. - if (!cmdMsg.geTextMessage().responseNeeded) { - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, - 0, null); - } - break; - case REFRESH: - // ME side only handles refresh commands which meant to remove IDLE - // MODE TEXT. - cmdParams.cmdDet.typeOfCommand = CommandType.SET_UP_IDLE_MODE_TEXT - .value(); - break; - case SET_UP_IDLE_MODE_TEXT: - sendTerminalResponse(cmdParams.cmdDet, ResultCode.OK, false, - 0, null); - break; - case LAUNCH_BROWSER: - case SELECT_ITEM: - case GET_INPUT: - case GET_INKEY: - case SEND_DTMF: - case SEND_SMS: - case SEND_SS: - case SEND_USSD: - case PLAY_TONE: - case SET_UP_CALL: - // nothing to do on telephony! - break; - default: - StkLog.d(this, "Unsupported command"); - return; - } - mCurrntCmd = cmdMsg; - Intent intent = new Intent(AppInterface.STK_CMD_ACTION); - intent.putExtra("STK CMD", cmdMsg); - mContext.sendBroadcast(intent); - } - - /** - * Handles RIL_UNSOL_STK_SESSION_END unsolicited command from RIL. - * - */ - private void handleSessionEnd() { - StkLog.d(this, "SESSION END"); - - mCurrntCmd = mMenuCmd; - Intent intent = new Intent(AppInterface.STK_SESSION_END_ACTION); - mContext.sendBroadcast(intent); - } - - private void sendTerminalResponse(CommandDetails cmdDet, - ResultCode resultCode, boolean includeAdditionalInfo, - int additionalInfo, ResponseData resp) { - - if (cmdDet == null) { - return; - } - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // command details - int tag = ComprehensionTlvTag.COMMAND_DETAILS.value(); - if (cmdDet.compRequired) { - tag |= 0x80; - } - buf.write(tag); - buf.write(0x03); // length - buf.write(cmdDet.commandNumber); - buf.write(cmdDet.typeOfCommand); - buf.write(cmdDet.commandQualifier); - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(DEV_ID_TERMINAL); // source device id - buf.write(DEV_ID_UICC); // destination device id - - // result - tag = 0x80 | ComprehensionTlvTag.RESULT.value(); - buf.write(tag); - int length = includeAdditionalInfo ? 2 : 1; - buf.write(length); - buf.write(resultCode.value()); - - // additional info - if (includeAdditionalInfo) { - buf.write(additionalInfo); - } - - // Fill optional data for each corresponding command - if (resp != null) { - resp.format(buf); - } - - byte[] rawData = buf.toByteArray(); - String hexString = SimUtils.bytesToHexString(rawData); - if (Config.LOGD) { - StkLog.d(this, "TERMINAL RESPONSE: " + hexString); - } - - mCmdIf.sendTerminalResponse(hexString, null); - } - - - private void sendMenuSelection(int menuId, boolean helpRequired) { - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // tag - int tag = BerTlv.BER_MENU_SELECTION_TAG; - buf.write(tag); - - // length - buf.write(0x00); // place holder - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(DEV_ID_KEYPAD); // source device id - buf.write(DEV_ID_UICC); // destination device id - - // item identifier - tag = 0x80 | ComprehensionTlvTag.ITEM_ID.value(); - buf.write(tag); - buf.write(0x01); // length - buf.write(menuId); // menu identifier chosen - - // help request - if (helpRequired) { - tag = ComprehensionTlvTag.HELP_REQUEST.value(); - buf.write(tag); - buf.write(0x00); // length - } - - byte[] rawData = buf.toByteArray(); - - // write real length - int len = rawData.length - 2; // minus (tag + length) - rawData[1] = (byte) len; - - String hexString = SimUtils.bytesToHexString(rawData); - - mCmdIf.sendEnvelope(hexString, null); - } - - private void eventDownload(int event, int sourceId, int destinationId, - byte[] additionalInfo, boolean oneShot) { - - ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - // tag - int tag = BerTlv.BER_EVENT_DOWNLOAD_TAG; - buf.write(tag); - - // length - buf.write(0x00); // place holder, assume length < 128. - - // event list - tag = 0x80 | ComprehensionTlvTag.EVENT_LIST.value(); - buf.write(tag); - buf.write(0x01); // length - buf.write(event); // event value - - // device identities - tag = 0x80 | ComprehensionTlvTag.DEVICE_IDENTITIES.value(); - buf.write(tag); - buf.write(0x02); // length - buf.write(sourceId); // source device id - buf.write(destinationId); // destination device id - - // additional information - if (additionalInfo != null) { - for (byte b : additionalInfo) { - buf.write(b); - } - } - - byte[] rawData = buf.toByteArray(); - - // write real length - int len = rawData.length - 2; // minus (tag + length) - rawData[1] = (byte) len; - - String hexString = SimUtils.bytesToHexString(rawData); - - mCmdIf.sendEnvelope(hexString, null); - } - - /** - * Used for instantiating the Service from the GsmPhone constructor. - * - * @param ci CommandsInterface object - * @param sr SIMRecords object - * @param context phone app context - * @param fh SIM file handler - * @param sc GSM SIM card - * @return The only Service object in the system - */ - public static StkService getInstance(CommandsInterface ci, SIMRecords sr, - Context context, SIMFileHandler fh, GsmSimCard sc) { - if (sInstance == null) { - if (ci == null || sr == null || context == null || fh == null - || sc == null) { - return null; - } - HandlerThread thread = new HandlerThread("Stk Telephony service"); - thread.start(); - sInstance = new StkService(ci, sr, context, fh, sc); - } - return sInstance; - } - - /** - * Used by application to get an AppInterface object. - * - * @return The only Service object in the system - */ - public static AppInterface getInstance() { - return getInstance(null, null, null, null, null); - } - - @Override - public void handleMessage(Message msg) { - - switch (msg.what) { - case MSG_ID_SESSION_END: - case MSG_ID_PROACTIVE_COMMAND: - case MSG_ID_EVENT_NOTIFY: - case MSG_ID_REFRESH: - StkLog.d(this, "ril message arrived"); - String data = null; - if (msg.obj != null) { - AsyncResult ar = (AsyncResult) msg.obj; - if (ar != null && ar.result != null) { - try { - data = (String) ar.result; - } catch (ClassCastException e) { - break; - } - } - } - mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, data)); - break; - case MSG_ID_CALL_SETUP: - mMsgDecoder.sendStartDecodingMessageParams(new RilMessage(msg.what, null)); - break; - case MSG_ID_SIM_LOADED: - break; - case MSG_ID_RIL_MSG_DECODED: - handleRilMsg((RilMessage) msg.obj); - break; - case MSG_ID_RESPONSE: - handleCmdResponse((StkResponseMessage) msg.obj); - break; - default: - throw new AssertionError("Unrecognized STK command: " + msg.what); - } - } - - public synchronized void onCmdResponse(StkResponseMessage resMsg) { - if (resMsg == null) { - return; - } - // queue a response message. - Message msg = this.obtainMessage(MSG_ID_RESPONSE, resMsg); - msg.sendToTarget(); - } - - private boolean validateResponse(StkResponseMessage resMsg) { - if (mCurrntCmd != null) { - return (resMsg.cmdDet.compareTo(mCurrntCmd.mCmdDet)); - } - return false; - } - - private boolean removeMenu(Menu menu) { - try { - if (menu.items.size() == 1 && menu.items.get(0) == null) { - return true; - } - } catch (NullPointerException e) { - StkLog.d(this, "Unable to get Menu's items size"); - return true; - } - return false; - } - - private void handleCmdResponse(StkResponseMessage resMsg) { - // Make sure the response details match the last valid command. An invalid - // response is a one that doesn't have a corresponding proactive command - // and sending it can "confuse" the baseband/ril. - // One reason for out of order responses can be UI glitches. For example, - // if the application launch an activity, and that activity is stored - // by the framework inside the history stack. That activity will be - // available for relaunch using the latest application dialog - // (long press on the home button). Relaunching that activity can send - // the same command's result again to the StkService and can cause it to - // get out of sync with the SIM. - if (!validateResponse(resMsg)) { - return; - } - ResponseData resp = null; - boolean helpRequired = false; - CommandDetails cmdDet = resMsg.getCmdDetails(); - - switch (resMsg.resCode) { - case HELP_INFO_REQUIRED: - helpRequired = true; - // fall through - case OK: - case PRFRMD_WITH_PARTIAL_COMPREHENSION: - case PRFRMD_WITH_MISSING_INFO: - case PRFRMD_WITH_ADDITIONAL_EFS_READ: - case PRFRMD_ICON_NOT_DISPLAYED: - case PRFRMD_MODIFIED_BY_NAA: - case PRFRMD_LIMITED_SERVICE: - case PRFRMD_WITH_MODIFICATION: - case PRFRMD_NAA_NOT_ACTIVE: - case PRFRMD_TONE_NOT_PLAYED: - switch (AppInterface.CommandType.fromInt(cmdDet.typeOfCommand)) { - case SET_UP_MENU: - helpRequired = resMsg.resCode == ResultCode.HELP_INFO_REQUIRED; - sendMenuSelection(resMsg.usersMenuSelection, helpRequired); - return; - case SELECT_ITEM: - resp = new SelectItemResponseData(resMsg.usersMenuSelection); - break; - case GET_INPUT: - case GET_INKEY: - Input input = mCurrntCmd.geInput(); - if (!input.yesNo) { - // when help is requested there is no need to send the text - // string object. - if (!helpRequired) { - resp = new GetInkeyInputResponseData(resMsg.usersInput, - input.ucs2, input.packed); - } - } else { - resp = new GetInkeyInputResponseData( - resMsg.usersYesNoSelection); - } - break; - case DISPLAY_TEXT: - case LAUNCH_BROWSER: - break; - case SET_UP_CALL: - mCmdIf.handleCallSetupRequestFromSim(resMsg.usersConfirm, null); - // No need to send terminal response for SET UP CALL. The user's - // confirmation result is send back using a dedicated ril message - // invoked by the CommandInterface call above. - mCurrntCmd = null; - return; - } - break; - case NO_RESPONSE_FROM_USER: - case UICC_SESSION_TERM_BY_USER: - case BACKWARD_MOVE_BY_USER: - resp = null; - break; - default: - return; - } - sendTerminalResponse(cmdDet, resMsg.resCode, false, 0, resp); - mCurrntCmd = null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java deleted file mode 100644 index c5dd50e..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAlignment.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Enumeration for representing text alignment. - * - * {@hide} - */ -public enum TextAlignment { - LEFT(0x0), - CENTER(0x1), - RIGHT(0x2), - /** Language dependent (default) */ - DEFAULT(0x3); - - private int mValue; - - TextAlignment(int value) { - mValue = value; - } - - /** - * Create a TextAlignment object. - * @param value Integer value to be converted to a TextAlignment object. - * @return TextAlignment object whose value is {@code value}. If no - * TextAlignment object has that value, null is returned. - */ - public static TextAlignment fromInt(int value) { - for (TextAlignment e : TextAlignment.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java deleted file mode 100644 index ace4300..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextAttribute.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Class for representing text attributes for SIM Toolkit. - * - * {@hide} - */ -public class TextAttribute { - public int start; - public int length; - public TextAlignment align; - public FontSize size; - public boolean bold; - public boolean italic; - public boolean underlined; - public boolean strikeThrough; - public TextColor color; - - public TextAttribute(int start, int length, TextAlignment align, - FontSize size, boolean bold, boolean italic, boolean underlined, - boolean strikeThrough, TextColor color) { - this.start = start; - this.length = length; - this.align = align; - this.size = size; - this.bold = bold; - this.italic = italic; - this.underlined = underlined; - this.strikeThrough = strikeThrough; - this.color = color; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java deleted file mode 100644 index 126fc62..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextColor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - - -/** - * Enumeration for representing text color. - * - * {@hide} - */ -public enum TextColor { - BLACK(0x0), - DARK_GRAY(0x1), - DARK_RED(0x2), - DARK_YELLOW(0x3), - DARK_GREEN(0x4), - DARK_CYAN(0x5), - DARK_BLUE(0x6), - DARK_MAGENTA(0x7), - GRAY(0x8), - WHITE(0x9), - BRIGHT_RED(0xa), - BRIGHT_YELLOW(0xb), - BRIGHT_GREEN(0xc), - BRIGHT_CYAN(0xd), - BRIGHT_BLUE(0xe), - BRIGHT_MAGENTA(0xf); - - private int mValue; - - TextColor(int value) { - mValue = value; - } - - /** - * Create a TextColor object. - * @param value Integer value to be converted to a TextColor object. - * @return TextColor object whose value is {@code value}. If no TextColor - * object has that value, null is returned. - */ - public static TextColor fromInt(int value) { - for (TextColor e : TextColor.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java b/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java deleted file mode 100644 index 3b6a09a..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/TextMessage.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.graphics.Bitmap; -import android.os.Parcel; -import android.os.Parcelable; - -public class TextMessage implements Parcelable { - public String title = ""; - public String text = null; - public Bitmap icon = null; - public boolean iconSelfExplanatory = false; - public boolean isHighPriority = false; - public boolean responseNeeded = true; - public boolean userClear = false; - public Duration duration = null; - - TextMessage() { - } - - private TextMessage(Parcel in) { - title = in.readString(); - text = in.readString(); - icon = in.readParcelable(null); - iconSelfExplanatory = in.readInt() == 1 ? true : false; - isHighPriority = in.readInt() == 1 ? true : false; - responseNeeded = in.readInt() == 1 ? true : false; - userClear = in.readInt() == 1 ? true : false; - duration = in.readParcelable(null); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(title); - dest.writeString(text); - dest.writeParcelable(icon, 0); - dest.writeInt(iconSelfExplanatory ? 1 : 0); - dest.writeInt(isHighPriority ? 1 : 0); - dest.writeInt(responseNeeded ? 1 : 0); - dest.writeInt(userClear ? 1 : 0); - dest.writeParcelable(duration, 0); - } - - public static final Parcelable.Creator<TextMessage> CREATOR = new Parcelable.Creator<TextMessage>() { - public TextMessage createFromParcel(Parcel in) { - return new TextMessage(in); - } - - public TextMessage[] newArray(int size) { - return new TextMessage[size]; - } - }; -}
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java b/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java deleted file mode 100644 index b64e777..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/Tone.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2006 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.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Enumeration for representing the tone values for use with PLAY TONE - * proactive commands. - * - * {@hide} - */ -public enum Tone implements Parcelable { - // Standard supervisory tones - - /** - * Dial tone. - */ - DIAL(0x01), - - /** - * Called subscriber busy. - */ - BUSY(0x02), - - /** - * Congestion. - */ - CONGESTION(0x03), - - /** - * Radio path acknowledge. - */ - RADIO_PATH_ACK(0x04), - - /** - * Radio path not available / Call dropped. - */ - RADIO_PATH_NOT_AVAILABLE(0x05), - - /** - * Error/Special information. - */ - ERROR_SPECIAL_INFO(0x06), - - /** - * Call waiting tone. - */ - CALL_WAITING(0x07), - - /** - * Ringing tone. - */ - RINGING(0x08), - - // Terminal proprietary tones - - /** - * General beep. - */ - GENERAL_BEEP(0x10), - - /** - * Positive acknowledgement tone. - */ - POSITIVE_ACK(0x11), - - /** - * Negative acknowledgement tone. - */ - NEGATIVE_ACK(0x12), - - /** - * Ringing tone as selected by the user for incoming speech call. - */ - INCOMING_SPEECH_CALL(0x13), - - /** - * Alert tone as selected by the user for incoming SMS. - */ - INCOMING_SMS(0x14), - - /** - * Critical alert. - * This tone is to be used in critical situations. The terminal shall make - * every effort to alert the user when this tone is indicated independent - * from the volume setting in the terminal. - */ - CRITICAL_ALERT(0x15), - - /** - * Vibrate only, if available. - */ - VIBRATE_ONLY(0x20), - - // Themed tones - - /** - * Happy tone. - */ - HAPPY(0x30), - - /** - * Sad tone. - */ - SAD(0x31), - - /** - * Urgent action tone. - */ - URGENT(0x32), - - /** - * Question tone. - */ - QUESTION(0x33), - - /** - * Message received tone. - */ - MESSAGE_RECEIVED(0x34), - - // Melody tones - MELODY_1(0x40), - MELODY_2(0x41), - MELODY_3(0x42), - MELODY_4(0x43), - MELODY_5(0x44), - MELODY_6(0x45), - MELODY_7(0x46), - MELODY_8(0x47); - - private int mValue; - - Tone(int value) { - mValue = value; - } - - /** - * Create a Tone object. - * @param value Integer value to be converted to a Tone object. - * @return Tone object whose value is {@code value}. If no Tone object has - * that value, null is returned. - */ - public static Tone fromInt(int value) { - for (Tone e : Tone.values()) { - if (e.mValue == value) { - return e; - } - } - return null; - } - - Tone(Parcel in) { - mValue = in.readInt(); - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(ordinal()); - } - - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator<Tone> CREATOR = new Parcelable.Creator<Tone>() { - public Tone createFromParcel(Parcel in) { - return Tone.values()[in.readInt()]; - } - - public Tone[] newArray(int size) { - return new Tone[size]; - } - }; -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java b/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java deleted file mode 100644 index bbc925e..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ToneSettings.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 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.stk; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Container class for PlayTone commands parameters. - * - */ -public class ToneSettings implements Parcelable { - public Duration duration; - public Tone tone; - public boolean vibrate; - - public ToneSettings(Duration duration, Tone tone, boolean vibrate) { - this.duration = duration; - this.tone = tone; - this.vibrate = vibrate; - } - - private ToneSettings(Parcel in) { - duration = in.readParcelable(null); - tone = in.readParcelable(null); - vibrate = in.readInt() == 1; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(duration, 0); - dest.writeParcelable(tone, 0); - dest.writeInt(vibrate ? 1 : 0); - } - - public static final Parcelable.Creator<ToneSettings> CREATOR = new Parcelable.Creator<ToneSettings>() { - public ToneSettings createFromParcel(Parcel in) { - return new ToneSettings(in); - } - - public ToneSettings[] newArray(int size) { - return new ToneSettings[size]; - } - }; -}
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java b/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java deleted file mode 100644 index 2cf87ba..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/ValueParser.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2006-2007 Google Inc. - * - * 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.stk; - -import com.android.internal.telephony.gsm.GsmAlphabet; -import com.android.internal.telephony.gsm.SimUtils; -import com.android.internal.telephony.gsm.stk.Duration.TimeUnit; - -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; - -abstract class ValueParser { - - /** - * Search for a Command Details object from a list. - * - * @param ctlvs List of ComprehensionTlv objects used for search - * @return An CtlvCommandDetails object found from the objects. If no - * Command Details object is found, ResultException is thrown. - * @throws ResultException - */ - static CommandDetails retrieveCommandDetails(ComprehensionTlv ctlv) - throws ResultException { - - CommandDetails cmdDet = new CommandDetails(); - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - cmdDet.compRequired = ctlv.isComprehensionRequired(); - cmdDet.commandNumber = rawValue[valueIndex] & 0xff; - cmdDet.typeOfCommand = rawValue[valueIndex + 1] & 0xff; - cmdDet.commandQualifier = rawValue[valueIndex + 2] & 0xff; - return cmdDet; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - /** - * Search for a Device Identities object from a list. - * - * @param ctlvs List of ComprehensionTlv objects used for search - * @return An CtlvDeviceIdentities object found from the objects. If no - * Command Details object is found, ResultException is thrown. - * @throws ResultException - */ - static DeviceIdentities retrieveDeviceIdentities(ComprehensionTlv ctlv) - throws ResultException { - - DeviceIdentities devIds = new DeviceIdentities(); - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - devIds.sourceId = rawValue[valueIndex] & 0xff; - devIds.destinationId = rawValue[valueIndex + 1] & 0xff; - return devIds; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.REQUIRED_VALUES_MISSING); - } - } - - /** - * Retrieves Duration information from the Duration COMPREHENSION-TLV - * object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return A Duration object - * @throws ResultException - */ - static Duration retrieveDuration(ComprehensionTlv ctlv) throws ResultException { - int timeInterval = 0; - TimeUnit timeUnit = TimeUnit.SECOND; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - - try { - timeUnit = TimeUnit.values()[(rawValue[valueIndex] & 0xff)]; - timeInterval = rawValue[valueIndex + 1] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - return new Duration(timeInterval, timeUnit); - } - - /** - * Retrieves Item information from the COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return An Item - * @throws ResultException - */ - static Item retrieveItem(ComprehensionTlv ctlv) throws ResultException { - Item item = null; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - - if (length != 0) { - int textLen = length - 1; - - try { - int id = rawValue[valueIndex] & 0xff; - String text = SimUtils.adnStringFieldToString(rawValue, - valueIndex + 1, textLen); - item = new Item(id, text); - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - - return item; - } - - /** - * Retrieves Item id information from the COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return An Item id - * @throws ResultException - */ - static int retrieveItemId(ComprehensionTlv ctlv) throws ResultException { - int id = 0; - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - - try { - id = rawValue[valueIndex] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return id; - } - - /** - * Retrieves icon id from an Icon Identifier COMPREHENSION-TLV object - * - * @param ctlv An Icon Identifier COMPREHENSION-TLV object - * @return IconId instance - * @throws ResultException - */ - static IconId retrieveIconId(ComprehensionTlv ctlv) throws ResultException { - IconId id = new IconId(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - try { - id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; - id.recordNumber = rawValue[valueIndex] & 0xff; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return id; - } - - /** - * Retrieves item icons id from an Icon Identifier List COMPREHENSION-TLV - * object - * - * @param ctlv An Item Icon List Identifier COMPREHENSION-TLV object - * @return ItemsIconId instance - * @throws ResultException - */ - static ItemsIconId retrieveItemsIconId(ComprehensionTlv ctlv) - throws ResultException { - StkLog.d("ValueParser", "retrieveItemsIconId:"); - ItemsIconId id = new ItemsIconId(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int numOfItems = ctlv.getLength() - 1; - id.recordNumbers = new int[numOfItems]; - - try { - // get icon self-explanatory - id.selfExplanatory = (rawValue[valueIndex++] & 0xff) == 0x00; - - for (int index = 0; index < numOfItems;) { - id.recordNumbers[index++] = rawValue[valueIndex++]; - } - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - return id; - } - - /** - * Retrieves text attribute information from the Text Attribute - * COMPREHENSION-TLV object. - * - * @param ctlv A Text Attribute COMPREHENSION-TLV object - * @return A list of TextAttribute objects - * @throws ResultException - */ - static List<TextAttribute> retrieveTextAttribute(ComprehensionTlv ctlv) - throws ResultException { - ArrayList<TextAttribute> lst = new ArrayList<TextAttribute>(); - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - - if (length != 0) { - // Each attribute is consisted of four bytes - int itemCount = length / 4; - - try { - for (int i = 0; i < itemCount; i++, valueIndex += 4) { - int start = rawValue[valueIndex] & 0xff; - int textLength = rawValue[valueIndex + 1] & 0xff; - int format = rawValue[valueIndex + 2] & 0xff; - int colorValue = rawValue[valueIndex + 3] & 0xff; - - int alignValue = format & 0x03; - TextAlignment align = TextAlignment.fromInt(alignValue); - - int sizeValue = (format >> 2) & 0x03; - FontSize size = FontSize.fromInt(sizeValue); - if (size == null) { - // Font size value is not defined. Use default. - size = FontSize.NORMAL; - } - - boolean bold = (format & 0x10) != 0; - boolean italic = (format & 0x20) != 0; - boolean underlined = (format & 0x40) != 0; - boolean strikeThrough = (format & 0x80) != 0; - - TextColor color = TextColor.fromInt(colorValue); - - TextAttribute attr = new TextAttribute(start, textLength, - align, size, bold, italic, underlined, - strikeThrough, color); - lst.add(attr); - } - - return lst; - - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - return null; - } - - - /** - * Retrieves alpha identifier from an Alpha Identifier COMPREHENSION-TLV - * object. - * - * @param ctlv An Alpha Identifier COMPREHENSION-TLV object - * @return String corresponding to the alpha identifier - * @throws ResultException - */ - static String retrieveAlphaId(ComprehensionTlv ctlv) throws ResultException { - - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - int length = ctlv.getLength(); - if (length != 0) { - try { - return SimUtils.adnStringFieldToString(rawValue, valueIndex, - length); - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } - return null; - } - - /** - * Retrieves text from the Text COMPREHENSION-TLV object, and decodes it - * into a Java String. - * - * @param ctlv A Text COMPREHENSION-TLV object - * @return A Java String object decoded from the Text object - * @throws ResultException - */ - static String retrieveTextString(ComprehensionTlv ctlv) throws ResultException { - byte[] rawValue = ctlv.getRawValue(); - int valueIndex = ctlv.getValueIndex(); - byte codingScheme = 0x00; - String text = null; - int textLen = ctlv.getLength(); - - // In case the text length is 0, return a null string. - if (textLen == 0) { - return text; - } else { - // one byte is coding scheme - textLen -= 1; - } - - try { - codingScheme = (byte) (rawValue[valueIndex] & 0x0c); - - if (codingScheme == 0x00) { // GSM 7-bit packed - text = GsmAlphabet.gsm7BitPackedToString(rawValue, - valueIndex + 1, (textLen * 8) / 7); - } else if (codingScheme == 0x04) { // GSM 8-bit unpacked - text = GsmAlphabet.gsm8BitUnpackedToString(rawValue, - valueIndex + 1, textLen); - } else if (codingScheme == 0x08) { // UCS2 - text = new String(rawValue, valueIndex + 1, textLen, "UTF-16"); - } else { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - - return text; - } catch (IndexOutOfBoundsException e) { - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } catch (UnsupportedEncodingException e) { - // This should never happen. - throw new ResultException(ResultCode.CMD_DATA_NOT_UNDERSTOOD); - } - } -} diff --git a/telephony/java/com/android/internal/telephony/gsm/stk/package.html b/telephony/java/com/android/internal/telephony/gsm/stk/package.html deleted file mode 100644 index c285b57..0000000 --- a/telephony/java/com/android/internal/telephony/gsm/stk/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<HTML> -<BODY> -Provides classes for SIM Toolkit Service. -</BODY> -</HTML> diff --git a/telephony/java/com/android/internal/telephony/package.html b/telephony/java/com/android/internal/telephony/package.html deleted file mode 100644 index 6377c18..0000000 --- a/telephony/java/com/android/internal/telephony/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<html> -<body> -{@hide} -</body> -</html> diff --git a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java b/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java deleted file mode 100644 index 25d2026..0000000 --- a/telephony/java/com/android/internal/telephony/test/ModelInterpreter.java +++ /dev/null @@ -1,741 +0,0 @@ -/* - * Copyright (C) 2006 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.test; - -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.InetSocketAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.List; - -// Also in ATChannel.java -class LineReader -{ - /** - * Not threadsafe - * Assumes input is ASCII - */ - - //***** Constants - - // For what it's worth, this is also the size of an - // OMAP CSMI mailbox - static final int BUFFER_SIZE = 0x1000; - - // just to prevent constant allocations - byte buffer[] = new byte[BUFFER_SIZE]; - - //***** Instance Variables - - InputStream inStream; - - LineReader (InputStream s) - { - inStream = s; - } - - String - getNextLine() - { - return getNextLine(false); - } - - String - getNextLineCtrlZ() - { - return getNextLine(true); - } - - /** - * Note: doesn't return the last incomplete line read on EOF, since - * it doesn't typically matter anyway - * - * Returns NULL on EOF - */ - - String - getNextLine(boolean ctrlZ) - { - int i = 0; - - try { - for (;;) { - int result; - - result = inStream.read(); - - if (result < 0) { - return null; - } - - if (ctrlZ && result == 0x1a) { - break; - } else if (result == '\r' || result == '\n') { - if (i == 0) { - // Skip leading cr/lf - continue; - } else { - break; - } - } - - buffer[i++] = (byte)result; - } - } catch (IOException ex) { - return null; - } catch (IndexOutOfBoundsException ex) { - System.err.println("ATChannel: buffer overflow"); - } - - try { - return new String(buffer, 0, i, "US-ASCII"); - } catch (UnsupportedEncodingException ex) { - System.err.println("ATChannel: implausable UnsupportedEncodingException"); - return null; - } - } -} - - - -class InterpreterEx extends Exception -{ - public - InterpreterEx (String result) - { - this.result = result; - } - - String result; -} - -public class ModelInterpreter - implements Runnable, SimulatedRadioControl -{ - static final int MAX_CALLS = 6; - - /** number of msec between dialing -> alerting and alerting->active */ - static final int CONNECTING_PAUSE_MSEC = 5 * 100; - - static final String LOG_TAG = "ModelInterpreter"; - - //***** Instance Variables - - InputStream in; - OutputStream out; - LineReader lineReader; - ServerSocket ss; - - private String finalResponse; - - SimulatedGsmCallState simulatedCallState; - - HandlerThread mHandlerThread; - - int pausedResponseCount; - Object pausedResponseMonitor = new Object(); - - //***** Events - - static final int PROGRESS_CALL_STATE = 1; - - //***** Constructor - - public - ModelInterpreter (InputStream in, OutputStream out) - { - this.in = in; - this.out = out; - - init(); - } - - public - ModelInterpreter (InetSocketAddress sa) throws java.io.IOException - { - ss = new ServerSocket(); - - ss.setReuseAddress(true); - ss.bind(sa); - - init(); - } - - private void - init() - { - new Thread(this, "ModelInterpreter").start(); - mHandlerThread = new HandlerThread("ModelInterpreter"); - mHandlerThread.start(); - Looper looper = mHandlerThread.getLooper(); - simulatedCallState = new SimulatedGsmCallState(looper); - } - - //***** Runnable Implementation - - public void run() - { - for (;;) { - if (ss != null) { - Socket s; - - try { - s = ss.accept(); - } catch (java.io.IOException ex) { - Log.w(LOG_TAG, - "IOException on socket.accept(); stopping", ex); - return; - } - - try { - in = s.getInputStream(); - out = s.getOutputStream(); - } catch (java.io.IOException ex) { - Log.w(LOG_TAG, - "IOException on accepted socket(); re-listening", ex); - continue; - } - - Log.i(LOG_TAG, "New connection accepted"); - } - - - lineReader = new LineReader (in); - - println ("Welcome"); - - for (;;) { - String line; - - line = lineReader.getNextLine(); - - //System.out.println("MI<< " + line); - - if (line == null) { - break; - } - - synchronized(pausedResponseMonitor) { - while (pausedResponseCount > 0) { - try { - pausedResponseMonitor.wait(); - } catch (InterruptedException ex) { - } - } - } - - synchronized (this) { - try { - finalResponse = "OK"; - processLine(line); - println(finalResponse); - } catch (InterpreterEx ex) { - println(ex.result); - } catch (RuntimeException ex) { - ex.printStackTrace(); - println("ERROR"); - } - } - } - - Log.i(LOG_TAG, "Disconnected"); - - if (ss == null) { - // no reconnect in this case - break; - } - } - } - - - //***** Instance Methods - - /** Start the simulated phone ringing */ - public void - triggerRing(String number) - { - synchronized (this) { - boolean success; - - success = simulatedCallState.triggerRing(number); - - if (success) { - println ("RING"); - } - } - } - - /** If a call is DIALING or ALERTING, progress it to the next state */ - public void - progressConnectingCallState() - { - simulatedCallState.progressConnectingCallState(); - } - - - /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */ - public void - progressConnectingToActive() - { - simulatedCallState.progressConnectingToActive(); - } - - /** automatically progress mobile originated calls to ACTIVE. - * default to true - */ - public void - setAutoProgressConnectingCall(boolean b) - { - simulatedCallState.setAutoProgressConnectingCall(b); - } - - public void - setNextDialFailImmediately(boolean b) - { - simulatedCallState.setNextDialFailImmediately(b); - } - - public void setNextCallFailCause(int gsmCause) - { - //FIXME implement - } - - - /** hangup ringing, dialing, or actuve calls */ - public void - triggerHangupForeground() - { - boolean success; - - success = simulatedCallState.triggerHangupForeground(); - - if (success) { - println ("NO CARRIER"); - } - } - - /** hangup holding calls */ - public void - triggerHangupBackground() - { - boolean success; - - success = simulatedCallState.triggerHangupBackground(); - - if (success) { - println ("NO CARRIER"); - } - } - - /** hangup all */ - - public void - triggerHangupAll() - { - boolean success; - - success = simulatedCallState.triggerHangupAll(); - - if (success) { - println ("NO CARRIER"); - } - } - - public void - sendUnsolicited (String unsol) - { - synchronized (this) { - println(unsol); - } - } - - public void triggerSsn(int a, int b) {} - public void triggerIncomingUssd(String statusCode, String message) {} - - public void - triggerIncomingSMS(String message) - { -/************** - StringBuilder pdu = new StringBuilder(); - - pdu.append ("00"); //SMSC address - 0 bytes - - pdu.append ("04"); // Message type indicator - - // source address: +18005551212 - pdu.append("918100551521F0"); - - // protocol ID and data coding scheme - pdu.append("0000"); - - Calendar c = Calendar.getInstance(); - - pdu.append (c. - - - - synchronized (this) { - println("+CMT: ,1\r" + pdu.toString()); - } - -**************/ - } - - public void - pauseResponses() - { - synchronized(pausedResponseMonitor) { - pausedResponseCount++; - } - } - - public void - resumeResponses() - { - synchronized(pausedResponseMonitor) { - pausedResponseCount--; - - if (pausedResponseCount == 0) { - pausedResponseMonitor.notifyAll(); - } - } - } - - //***** Private Instance Methods - - private void - onAnswer() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.onAnswer(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - onHangup() throws InterpreterEx - { - boolean success = false; - - success = simulatedCallState.onAnswer(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - - finalResponse = "NO CARRIER"; - } - - private void - onCHLD(String command) throws InterpreterEx - { - // command starts with "+CHLD=" - char c0; - char c1 = 0; - boolean success; - - c0 = command.charAt(6); - - if (command.length() >= 8) { - c1 = command.charAt(7); - } - - success = simulatedCallState.onChld(c0, c1); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - releaseHeldOrUDUB() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.releaseHeldOrUDUB(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - releaseActiveAcceptHeldOrWaiting() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.releaseActiveAcceptHeldOrWaiting(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - switchActiveAndHeldOrWaiting() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.switchActiveAndHeldOrWaiting(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - separateCall(int index) throws InterpreterEx - { - boolean success; - - success = simulatedCallState.separateCall(index); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - conference() throws InterpreterEx - { - boolean success; - - success = simulatedCallState.conference(); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - onDial(String command) throws InterpreterEx - { - boolean success; - - success = simulatedCallState.onDial(command.substring(1)); - - if (!success) { - throw new InterpreterEx("ERROR"); - } - } - - private void - onCLCC() throws InterpreterEx - { - List<String> lines; - - lines = simulatedCallState.getClccLines(); - - for (int i = 0, s = lines.size() ; i < s ; i++) { - println (lines.get(i)); - } - } - - private void - onSMSSend(String command) throws InterpreterEx - { - String pdu; - - print ("> "); - pdu = lineReader.getNextLineCtrlZ(); - - println("+CMGS: 1"); - } - - void - processLine (String line) throws InterpreterEx - { - String[] commands; - - commands = splitCommands(line); - - for (int i = 0; i < commands.length ; i++) { - String command = commands[i]; - - if (command.equals("A")) { - onAnswer(); - } else if (command.equals("H")) { - onHangup(); - } else if (command.startsWith("+CHLD=")) { - onCHLD(command); - } else if (command.equals("+CLCC")) { - onCLCC(); - } else if (command.startsWith("D")) { - onDial(command); - } else if (command.startsWith("+CMGS=")) { - onSMSSend(command); - } else { - boolean found = false; - - for (int j = 0; j < sDefaultResponses.length ; j++) { - if (command.equals(sDefaultResponses[j][0])) { - String r = sDefaultResponses[j][1]; - if (r != null) { - println(r); - } - found = true; - break; - } - } - - if (!found) { - throw new InterpreterEx ("ERROR"); - } - } - } - } - - - String[] - splitCommands(String line) throws InterpreterEx - { - if (!line.startsWith ("AT")) { - throw new InterpreterEx("ERROR"); - } - - if (line.length() == 2) { - // Just AT by itself - return new String[0]; - } - - String ret[] = new String[1]; - - //TODO fix case here too - ret[0] = line.substring(2); - - return ret; -/**** - try { - // i = 2 to skip over AT - for (int i = 2, s = line.length() ; i < s ; i++) { - // r"|([A-RT-Z]\d?)" # Normal commands eg ATA or I0 - // r"|(&[A-Z]\d*)" # & commands eg &C - // r"|(S\d+(=\d+)?)" # S registers - // r"((\+|%)\w+(\?|=([^;]+(;|$)))?)" # extended command eg +CREG=2 - - - } - } catch (StringIndexOutOfBoundsException ex) { - throw new InterpreterEx ("ERROR"); - } -***/ - } - - void - println (String s) - { - synchronized(this) { - try { - byte[] bytes = s.getBytes("US-ASCII"); - - //System.out.println("MI>> " + s); - - out.write(bytes); - out.write('\r'); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - } - - void - print (String s) - { - synchronized(this) { - try { - byte[] bytes = s.getBytes("US-ASCII"); - - //System.out.println("MI>> " + s + " (no <cr>)"); - - out.write(bytes); - } catch (IOException ex) { - ex.printStackTrace(); - } - } - } - - - public void - shutdown() - { - Looper looper = mHandlerThread.getLooper(); - if (looper != null) { - looper.quit(); - } - - try { - in.close(); - } catch (IOException ex) { - } - try { - out.close(); - } catch (IOException ex) { - } - } - - - static final String [][] sDefaultResponses = { - {"E0Q0V1", null}, - {"+CMEE=2", null}, - {"+CREG=2", null}, - {"+CGREG=2", null}, - {"+CCWA=1", null}, - {"+COPS=0", null}, - {"+CFUN=1", null}, - {"+CGMI", "+CGMI: Android Model AT Interpreter\r"}, - {"+CGMM", "+CGMM: Android Model AT Interpreter\r"}, - {"+CGMR", "+CGMR: 1.0\r"}, - {"+CGSN", "000000000000000\r"}, - {"+CIMI", "320720000000000\r"}, - {"+CSCS=?", "+CSCS: (\"HEX\",\"UCS2\")\r"}, - {"+CFUN?", "+CFUN: 1\r"}, - {"+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?", - "+COPS: 0,0,\"Android\"\r" - + "+COPS: 0,1,\"Android\"\r" - + "+COPS: 0,2,\"310995\"\r"}, - {"+CREG?", "+CREG: 2,5, \"0113\", \"6614\"\r"}, - {"+CGREG?", "+CGREG: 2,0\r"}, - {"+CSQ", "+CSQ: 16,99\r"}, - {"+CNMI?", "+CNMI: 1,2,2,1,1\r"}, - {"+CLIR?", "+CLIR: 1,3\r"}, - {"%CPVWI=2", "%CPVWI: 0\r"}, - {"+CUSD=1,\"#646#\"", "+CUSD=0,\"You have used 23 minutes\"\r"}, - {"+CRSM=176,12258,0,0,10", "+CRSM: 144,0,981062200050259429F6\r"}, - {"+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000A2FE204000FF55501020000\r"}, - - /* EF[ADN] */ - {"+CRSM=192,28474,0,0,15", "+CRSM: 144,0,0000005a6f3a040011f5220102011e\r"}, - {"+CRSM=178,28474,1,4,30", "+CRSM: 144,0,437573746f6d65722043617265ffffff07818100398799f7ffffffffffff\r"}, - {"+CRSM=178,28474,2,4,30", "+CRSM: 144,0,566f696365204d61696cffffffffffff07918150367742f3ffffffffffff\r"}, - {"+CRSM=178,28474,3,4,30", "+CRSM: 144,0,4164676a6dffffffffffffffffffffff0b918188551512c221436587ff01\r"}, - {"+CRSM=178,28474,4,4,30", "+CRSM: 144,0,810101c1ffffffffffffffffffffffff068114455245f8ffffffffffffff\r"}, - /* EF[EXT1] */ - {"+CRSM=192,28490,0,0,15", "+CRSM: 144,0,000000416f4a040011f5550102010d\r"}, - {"+CRSM=178,28490,1,4,13", "+CRSM: 144,0,0206092143658709ffffffffff\r"} - }; -} diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java b/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java deleted file mode 100644 index 33c1679..0000000 --- a/telephony/java/com/android/internal/telephony/test/SimulatedCommands.java +++ /dev/null @@ -1,1354 +0,0 @@ -/* - * Copyright (C) 2006 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.test; - - -import android.os.AsyncResult; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.gsm.BaseCommands; -import com.android.internal.telephony.gsm.CallFailCause; -import com.android.internal.telephony.gsm.CommandException; -import com.android.internal.telephony.gsm.CommandsInterface; -import com.android.internal.telephony.gsm.PDPContextState; -import com.android.internal.telephony.gsm.SuppServiceNotification; - -import java.util.ArrayList; - -public final class SimulatedCommands extends BaseCommands - implements CommandsInterface, SimulatedRadioControl -{ - private final static String LOG_TAG = "SIM"; - - private enum SimLockState { - NONE, - REQUIRE_PIN, - REQUIRE_PUK, - SIM_PERM_LOCKED - }; - - private enum SimFdnState { - NONE, - REQUIRE_PIN2, - REQUIRE_PUK2, - SIM_PERM_LOCKED - }; - - private final static SimLockState INITIAL_LOCK_STATE = SimLockState.NONE; - private final static String DEFAULT_SIM_PIN_CODE = "1234"; - private final static String SIM_PUK_CODE = "12345678"; - private final static SimFdnState INITIAL_FDN_STATE = SimFdnState.NONE; - private final static String DEFAULT_SIM_PIN2_CODE = "5678"; - private final static String SIM_PUK2_CODE = "87654321"; - - //***** Instance Variables - - SimulatedGsmCallState simulatedCallState; - HandlerThread mHandlerThread; - SimLockState mSimLockedState; - boolean mSimLockEnabled; - int mPinUnlockAttempts; - int mPukUnlockAttempts; - String mPinCode; - SimFdnState mSimFdnEnabledState; - boolean mSimFdnEnabled; - int mPin2UnlockAttempts; - int mPuk2UnlockAttempts; - int mNetworkType; - String mPin2Code; - boolean mSsnNotifyOn = false; - - int pausedResponseCount; - ArrayList<Message> pausedResponses = new ArrayList<Message>(); - - int nextCallFailCause = CallFailCause.NORMAL_CLEARING; - - //***** Constructor - - public - SimulatedCommands() { - super(null); // Don't log statistics - mHandlerThread = new HandlerThread("SimulatedCommands"); - mHandlerThread.start(); - Looper looper = mHandlerThread.getLooper(); - - simulatedCallState = new SimulatedGsmCallState(looper); - - setRadioState(RadioState.RADIO_OFF); - mSimLockedState = INITIAL_LOCK_STATE; - mSimLockEnabled = (mSimLockedState != SimLockState.NONE); - mPinCode = DEFAULT_SIM_PIN_CODE; - mSimFdnEnabledState = INITIAL_FDN_STATE; - mSimFdnEnabled = (mSimFdnEnabledState != SimFdnState.NONE); - mPin2Code = DEFAULT_SIM_PIN2_CODE; - } - - //***** CommandsInterface implementation - - public void getSimStatus(Message result) - { - switch (mState) { - case SIM_READY: - resultSuccess(result, SimStatus.SIM_READY); - break; - - case SIM_LOCKED_OR_ABSENT: - returnSimLockedStatus(result); - break; - - default: - resultSuccess(result, SimStatus.SIM_NOT_READY); - break; - } - } - - private void returnSimLockedStatus(Message result) { - switch (mSimLockedState) { - case REQUIRE_PIN: - Log.i(LOG_TAG, "[SimCmd] returnSimLockedStatus: SIM_PIN"); - resultSuccess(result, SimStatus.SIM_PIN); - break; - - case REQUIRE_PUK: - Log.i(LOG_TAG, "[SimCmd] returnSimLockedStatus: SIM_PUK"); - resultSuccess(result, SimStatus.SIM_PUK); - break; - - default: - Log.i(LOG_TAG, - "[SimCmd] returnSimLockedStatus: mSimLockedState==NONE !?"); - break; - } - } - - public void supplySimPin(String pin, Message result) { - if (mSimLockedState != SimLockState.REQUIRE_PIN) { - Log.i(LOG_TAG, "[SimCmd] supplySimPin: wrong state, state=" + - mSimLockedState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (pin != null && pin.equals(mPinCode)) { - Log.i(LOG_TAG, "[SimCmd] supplySimPin: success!"); - setRadioState(RadioState.SIM_READY); - mPinUnlockAttempts = 0; - mSimLockedState = SimLockState.NONE; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPinUnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplySimPin: failed! attempt=" + - mPinUnlockAttempts); - if (mPinUnlockAttempts >= 3) { - Log.i(LOG_TAG, "[SimCmd] supplySimPin: set state to REQUIRE_PUK"); - mSimLockedState = SimLockState.REQUIRE_PUK; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void supplySimPuk(String puk, String newPin, Message result) { - if (mSimLockedState != SimLockState.REQUIRE_PUK) { - Log.i(LOG_TAG, "[SimCmd] supplySimPuk: wrong state, state=" + - mSimLockedState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (puk != null && puk.equals(SIM_PUK_CODE)) { - Log.i(LOG_TAG, "[SimCmd] supplySimPuk: success!"); - setRadioState(RadioState.SIM_READY); - mSimLockedState = SimLockState.NONE; - mPukUnlockAttempts = 0; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPukUnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplySimPuk: failed! attempt=" + - mPukUnlockAttempts); - if (mPukUnlockAttempts >= 10) { - Log.i(LOG_TAG, "[SimCmd] supplySimPuk: set state to SIM_PERM_LOCKED"); - mSimLockedState = SimLockState.SIM_PERM_LOCKED; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void supplySimPin2(String pin2, Message result) { - if (mSimFdnEnabledState != SimFdnState.REQUIRE_PIN2) { - Log.i(LOG_TAG, "[SimCmd] supplySimPin2: wrong state, state=" + - mSimFdnEnabledState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (pin2 != null && pin2.equals(mPin2Code)) { - Log.i(LOG_TAG, "[SimCmd] supplySimPin2: success!"); - mPin2UnlockAttempts = 0; - mSimFdnEnabledState = SimFdnState.NONE; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPin2UnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplySimPin2: failed! attempt=" + - mPin2UnlockAttempts); - if (mPin2UnlockAttempts >= 3) { - Log.i(LOG_TAG, "[SimCmd] supplySimPin2: set state to REQUIRE_PUK2"); - mSimFdnEnabledState = SimFdnState.REQUIRE_PUK2; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void supplySimPuk2(String puk2, String newPin2, Message result) { - if (mSimFdnEnabledState != SimFdnState.REQUIRE_PUK2) { - Log.i(LOG_TAG, "[SimCmd] supplySimPuk2: wrong state, state=" + - mSimLockedState); - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - return; - } - - if (puk2 != null && puk2.equals(SIM_PUK2_CODE)) { - Log.i(LOG_TAG, "[SimCmd] supplySimPuk2: success!"); - mSimFdnEnabledState = SimFdnState.NONE; - mPuk2UnlockAttempts = 0; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - mPuk2UnlockAttempts ++; - - Log.i(LOG_TAG, "[SimCmd] supplySimPuk2: failed! attempt=" + - mPuk2UnlockAttempts); - if (mPuk2UnlockAttempts >= 10) { - Log.i(LOG_TAG, "[SimCmd] supplySimPuk2: set state to SIM_PERM_LOCKED"); - mSimFdnEnabledState = SimFdnState.SIM_PERM_LOCKED; - } - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void changeSimPin(String oldPin, String newPin, Message result) { - if (oldPin != null && oldPin.equals(mPinCode)) { - mPinCode = newPin; - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] changeSimPin: pin failed!"); - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void changeSimPin2(String oldPin2, String newPin2, Message result) { - if (oldPin2 != null && oldPin2.equals(mPin2Code)) { - mPin2Code = newPin2; - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] changeSimPin: pin2 failed!"); - - CommandException ex = new CommandException( - CommandException.Error.PASSWORD_INCORRECT); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - } - - public void - changeBarringPassword(String facility, String oldPwd, String newPwd, Message result) - { - unimplemented(result); - } - - public void - setSuppServiceNotifications(boolean enable, Message result) - { - resultSuccess(result, null); - - if (enable && mSsnNotifyOn) { - Log.w(LOG_TAG, "Supp Service Notifications already enabled!"); - } - - mSsnNotifyOn = enable; - } - - /** - * (AsyncResult)response.obj).result will be an Integer representing - * the sum of enabled serivice classes (sum of SERVICE_CLASS_*) - * - * @param facility one of CB_FACILTY_* - * @param pin password or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - */ - - public void queryFacilityLock (String facility, String pin, - int serviceClass, Message result) { - if (facility != null && - facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) { - if (result != null) { - int[] r = new int[1]; - r[0] = (mSimLockEnabled ? 1 : 0); - Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: SIM is " + - (r[0] == 0 ? "unlocked" : "locked")); - AsyncResult.forMessage(result, r, null); - result.sendToTarget(); - } - return; - } else if (facility != null && - facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) { - if (result != null) { - int[] r = new int[1]; - r[0] = (mSimFdnEnabled ? 1 : 0); - Log.i(LOG_TAG, "[SimCmd] queryFacilityLock: FDN is " + - (r[0] == 0 ? "disabled" : "enabled")); - AsyncResult.forMessage(result, r, null); - result.sendToTarget(); - } - return; - } - - unimplemented(result); - } - - /** - * @param facility one of CB_FACILTY_* - * @param lockEnabled true if SIM lock is enabled - * @param pin the SIM pin or "" if not required - * @param serviceClass is a sum of SERVICE_CLASS_* - */ - public void setFacilityLock (String facility, boolean lockEnabled, - String pin, int serviceClass, - Message result) { - if (facility != null && - facility.equals(CommandsInterface.CB_FACILITY_BA_SIM)) { - if (pin != null && pin.equals(mPinCode)) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin is valid"); - mSimLockEnabled = lockEnabled; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin failed!"); - - CommandException ex = new CommandException( - CommandException.Error.GENERIC_FAILURE); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - - return; - } else if (facility != null && - facility.equals(CommandsInterface.CB_FACILITY_BA_FD)) { - if (pin != null && pin.equals(mPin2Code)) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 is valid"); - mSimFdnEnabled = lockEnabled; - - if (result != null) { - AsyncResult.forMessage(result, null, null); - result.sendToTarget(); - } - - return; - } - - if (result != null) { - Log.i(LOG_TAG, "[SimCmd] setFacilityLock: pin2 failed!"); - - CommandException ex = new CommandException( - CommandException.Error.GENERIC_FAILURE); - AsyncResult.forMessage(result, null, ex); - result.sendToTarget(); - } - - return; - } - - unimplemented(result); - } - - public void supplyNetworkDepersonalization(String netpin, Message result) { - unimplemented(result); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result contains a List of DriverCall - * The ar.result List is sorted by DriverCall.index - */ - public void getCurrentCalls (Message result) - { - if (mState == RadioState.SIM_READY) { - //Log.i("GSM", "[SimCmds] getCurrentCalls"); - resultSuccess(result, simulatedCallState.getDriverCalls()); - } else { - //Log.i("GSM", "[SimCmds] getCurrentCalls: SIM not ready!"); - resultFail(result, - new CommandException( - CommandException.Error.RADIO_NOT_AVAILABLE)); - } - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result contains a List of PDPContextState - */ - public void getPDPContextList(Message result) - { - resultSuccess(result, new ArrayList<PDPContextState>(0)); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - * - * CLIR_DEFAULT == on "use subscription default value" - * CLIR_SUPPRESSION == on "CLIR suppression" (allow CLI presentation) - * CLIR_INVOCATION == on "CLIR invocation" (restrict CLI presentation) - */ - public void dial (String address, int clirMode, Message result) - { - simulatedCallState.onDial(address); - - resultSuccess(result, null); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is String containing IMSI on success - */ - public void getIMSI(Message result) - { - resultSuccess(result, "012345678901234"); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is String containing IMEI on success - */ - public void getIMEI(Message result) - { - resultSuccess(result, "012345678901234"); - } - - /** - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is String containing IMEISV on success - */ - public void getIMEISV(Message result) - { - resultSuccess(result, "99"); - } - - /** - * Hang up one individual connection. - * returned message - * retMsg.obj = AsyncResult ar - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - * - * 3GPP 22.030 6.5.5 - * "Releases a specific active call X" - */ - public void hangupConnection (int gsmIndex, Message result) - { - boolean success; - - success = simulatedCallState.onChld('1', (char)('0'+gsmIndex)); - - if (!success){ - Log.i("GSM", "[SimCmd] hangupConnection: resultFail"); - resultFail(result, new RuntimeException("Hangup Error")); - } else { - Log.i("GSM", "[SimCmd] hangupConnection: resultSuccess"); - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Releases all held calls or sets User Determined User Busy (UDUB) - * for a waiting call." - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void hangupWaitingOrBackground (Message result) - { - boolean success; - - success = simulatedCallState.onChld('0', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Releases all active calls (if any exist) and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void hangupForegroundResumeBackground (Message result) - { - boolean success; - - success = simulatedCallState.onChld('1', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls (if any exist) on hold and accepts - * the other (held or waiting) call." - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void switchWaitingOrHoldingAndActive (Message result) - { - boolean success; - - success = simulatedCallState.onChld('2', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Adds a held call to the conversation" - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void conference (Message result) - { - boolean success; - - success = simulatedCallState.onChld('3', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Connects the two calls and disconnects the subscriber from both calls" - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void explicitCallTransfer (Message result) - { - boolean success; - - success = simulatedCallState.onChld('4', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * 3GPP 22.030 6.5.5 - * "Places all active calls on hold except call X with which - * communication shall be supported." - */ - public void separateConnection (int gsmIndex, Message result) - { - boolean success; - - char ch = (char)(gsmIndex + '0'); - success = simulatedCallState.onChld('2', ch); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void acceptCall (Message result) - { - boolean success; - - success = simulatedCallState.onAnswer(); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * also known as UDUB - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void rejectCall (Message result) - { - boolean success; - - success = simulatedCallState.onChld('0', '\0'); - - if (!success){ - resultFail(result, new RuntimeException("Hangup Error")); - } else { - resultSuccess(result, null); - } - } - - /** - * cause code returned as Integer in Message.obj.response - * Returns integer cause code defined in TS 24.008 - * Annex H or closest approximation. - * Most significant codes: - * - Any defined in 22.001 F.4 (for generating busy/congestion) - * - Cause 68: ACM >= ACMMax - */ - public void getLastCallFailCause (Message result) - { - int[] ret = new int[1]; - - ret[0] = nextCallFailCause; - resultSuccess(result, ret); - } - - public void - getLastPdpFailCause (Message result) - { - unimplemented(result); - } - - public void setMute (boolean enableMute, Message result) {unimplemented(result);} - - public void getMute (Message result) {unimplemented(result);} - - /** - * response.obj is an AsyncResult - * response.obj.result is an int[2] - * response.obj.result[0] is received signal strength (0-31, 99) - * response.obj.result[1] is bit error rate (0-7, 99) - * as defined in TS 27.007 8.5 - */ - public void getSignalStrength (Message result) - { - int ret[] = new int[2]; - - ret[0] = 23; - ret[1] = 0; - - resultSuccess(result, ret); - } - - /** - * Assign a specified band for RF configuration. - * - * @param bandMode one of BM_*_BAND - * @param result is callback message - */ - public void setBandMode (int bandMode, Message result) { - resultSuccess(result, null); - } - - /** - * Query the list of band mode supported by RF. - * - * @param result is callback message - * ((AsyncResult)response.obj).result is an int[] with every - * element representing one avialable BM_*_BAND - */ - public void queryAvailableBandMode (Message result) { - int ret[] = new int [4]; - - ret[0] = 4; - ret[1] = Phone.BM_US_BAND; - ret[2] = Phone.BM_JPN_BAND; - ret[3] = Phone.BM_AUS_BAND; - - resultSuccess(result, ret); - } - - /** - * {@inheritDoc} - */ - public void sendTerminalResponse(String contents, Message response) { - resultSuccess(response, null); - } - - /** - * {@inheritDoc} - */ - public void sendEnvelope(String contents, Message response) { - resultSuccess(response, null); - } - - /** - * {@inheritDoc} - */ - public void handleCallSetupRequestFromSim( - boolean accept, Message response) { - resultSuccess(response, null); - } - - /** - * response.obj.result is an String[3] - * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2 - * response.obj.result[1] is LAC if registered or NULL if not - * response.obj.result[2] is CID if registered or NULL if not - * valid LAC are 0x0000 - 0xffff - * valid CID are 0x00000000 - 0xffffffff - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" above - */ - public void getRegistrationState (Message result) - { - String ret[] = new String[3]; - - ret[0] = "5"; // registered roam - ret[1] = null; - ret[2] = null; - - resultSuccess(result, ret); - } - - /** - * response.obj.result is an String[4] - * response.obj.result[0] is registration state 0-5 from TS 27.007 7.2 - * response.obj.result[1] is LAC if registered or NULL if not - * response.obj.result[2] is CID if registered or NULL if not - * response.obj.result[3] indicates the available radio technology, where: - * 0 == unknown - * 1 == GPRS only - * 2 == EDGE - * 3 == UMTS - * - * valid LAC are 0x0000 - 0xffff - * valid CID are 0x00000000 - 0xffffffff - * - * Please note that registration state 4 ("unknown") is treated - * as "out of service" in the Android telephony system - */ - public void getGPRSRegistrationState (Message result) - { - String ret[] = new String[4]; - - ret[0] = "5"; // registered roam - ret[1] = null; - ret[2] = null; - ret[3] = "2"; - - resultSuccess(result, ret); - } - - /** - * response.obj.result is a String[3] - * response.obj.result[0] is long alpha or null if unregistered - * response.obj.result[1] is short alpha or null if unregistered - * response.obj.result[2] is numeric or null if unregistered - */ - public void getOperator(Message result) - { - String[] ret = new String[3]; - - ret[0] = "El Telco Loco"; - ret[1] = "Telco Loco"; - ret[2] = "001001"; - - resultSuccess(result, ret); - } - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void sendDtmf(char c, Message result) - { - resultSuccess(result, null); - } - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void startDtmf(char c, Message result) - { - resultSuccess(result, null); - } - - /** - * ar.exception carries exception on failure - * ar.userObject contains the orignal value of result.obj - * ar.result is null on success and failure - */ - public void stopDtmf(Message result) - { - resultSuccess(result, null); - } - - /** - * smscPDU is smsc address in PDU form GSM BCD format prefixed - * by a length byte (as expected by TS 27.005) or NULL for default SMSC - * pdu is SMS in PDU format as an ASCII hex string - * less the SMSC address - */ - public void sendSMS (String smscPDU, String pdu, Message result) {unimplemented(result);} - - public void deleteSmsOnSim(int index, Message response) { - Log.d(LOG_TAG, "Delete message at index " + index); - unimplemented(response); - } - - public void writeSmsToSim(int status, String smsc, String pdu, Message response) { - Log.d(LOG_TAG, "Write SMS to SIM with status " + status); - unimplemented(response); - } - - - public void setupDefaultPDP(String apn, String user, String password, Message result) { - unimplemented(result); - } - - public void deactivateDefaultPDP(int cid, Message result) {unimplemented(result);} - - public void setPreferredNetworkType(int networkType , Message result) { - mNetworkType = networkType; - resultSuccess(result, null); - } - - public void getPreferredNetworkType(Message result) { - int ret[] = new int[1]; - - ret[0] = mNetworkType; - resultSuccess(result, ret); - } - - public void getNeighboringCids(Message result) { - int ret[] = new int[7]; - - ret[0] = 6; - for (int i = 1; i<7; i++) { - ret[i] = i; - } - resultSuccess(result, ret); - } - - public void setLocationUpdates(boolean enable, Message response) { - unimplemented(response); - } - - private boolean isSimLocked() { - if (mSimLockedState != SimLockState.NONE) { - return true; - } - return false; - } - - public void setRadioPower(boolean on, Message result) - { - if(on) { - if (isSimLocked()) { - Log.i("SIM", "[SimCmd] setRadioPower: SIM locked! state=" + - mSimLockedState); - setRadioState(RadioState.SIM_LOCKED_OR_ABSENT); - } - else { - setRadioState(RadioState.SIM_READY); - } - } else { - setRadioState(RadioState.RADIO_OFF); - } - } - - - public void acknowledgeLastIncomingSMS(boolean success, Message result) { - unimplemented(result); - } - - /** - * parameters equivilient to 27.007 AT+CRSM command - * response.obj will be an AsyncResult - * response.obj.userObj will be a SimIoResult on success - */ - public void simIO (int command, int fileid, String path, int p1, int p2, - int p3, String data, String pin2, Message result) { - unimplemented(result); - } - - /** - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 1 for "CLIP is provisioned", and 0 for "CLIP is not provisioned". - * - * @param response is callback message - */ - public void queryCLIP(Message response) { unimplemented(response); } - - - /** - * response.obj will be a an int[2] - * - * response.obj[0] will be TS 27.007 +CLIR parameter 'n' - * 0 presentation indicator is used according to the subscription of the CLIR service - * 1 CLIR invocation - * 2 CLIR suppression - * - * response.obj[1] will be TS 27.007 +CLIR parameter 'm' - * 0 CLIR not provisioned - * 1 CLIR provisioned in permanent mode - * 2 unknown (e.g. no network, etc.) - * 3 CLIR temporary mode presentation restricted - * 4 CLIR temporary mode presentation allowed - */ - - public void getCLIR(Message result) {unimplemented(result);} - - /** - * clirMode is one of the CLIR_* constants above - * - * response.obj is null - */ - - public void setCLIR(int clirMode, Message result) {unimplemented(result);} - - /** - * (AsyncResult)response.obj).result is an int[] with element [0] set to - * 0 for disabled, 1 for enabled. - * - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - public void queryCallWaiting(int serviceClass, Message response) - { - unimplemented(response); - } - - /** - * @param enable is true to enable, false to disable - * @param serviceClass is a sum of SERVICE_CLASS_* - * @param response is callback message - */ - - public void setCallWaiting(boolean enable, int serviceClass, - Message response) - { - unimplemented(response); - } - - /** - * @param action is one of CF_ACTION_* - * @param cfReason is one of CF_REASON_* - * @param serviceClass is a sum of SERVICE_CLASSS_* - */ - public void setCallForward(int action, int cfReason, int serviceClass, - String number, int timeSeconds, Message result) {unimplemented(result);} - - /** - * cfReason is one of CF_REASON_* - * - * ((AsyncResult)response.obj).result will be an array of - * CallForwardInfo's - * - * An array of length 0 means "disabled for all codes" - */ - public void queryCallForwardStatus(int cfReason, int serviceClass, - String number, Message result) {unimplemented(result);} - - public void setNetworkSelectionModeAutomatic(Message result) {unimplemented(result);} - - public void setNetworkSelectionModeManual(String operatorNumeric, Message result) {unimplemented(result);} - - /** - * Queries whether the current network selection mode is automatic - * or manual - * - * ((AsyncResult)response.obj).result is an int[] with element [0] being - * a 0 for automatic selection and a 1 for manual selection - */ - - public void getNetworkSelectionMode(Message result) - { - int ret[] = new int[1]; - - ret[0] = 0; - resultSuccess(result, ret); - } - - /** - * Queries the currently available networks - * - * ((AsyncResult)response.obj).result is a List of NetworkInfo objects - */ - public void getAvailableNetworks(Message result) {unimplemented(result);} - - public void getBasebandVersion (Message result) - { - resultSuccess(result, "SimulatedCommands"); - } - - /** - * Simulates an incoming USSD message - * @param statusCode Status code string. See <code>setOnUSSD</code> - * in CommandsInterface.java - * @param message Message text to send or null if none - */ - public void triggerIncomingUssd(String statusCode, String message) { - if (mUSSDRegistrant != null) { - String[] result = {statusCode, message}; - mUSSDRegistrant.notifyResult(result); - } - } - - - public void sendUSSD (String ussdString, Message result) { - - // We simulate this particular sequence - if (ussdString.equals("#646#")) { - resultSuccess(result, null); - - // 0 == USSD-Notify - triggerIncomingUssd("0", "You have NNN minutes remaining."); - } else { - resultSuccess(result, null); - - triggerIncomingUssd("0", "All Done"); - } - } - - // inherited javadoc suffices - public void cancelPendingUssd (Message response) { - resultSuccess(response, null); - } - - - public void resetRadio(Message result) - { - unimplemented(result); - } - - public void invokeOemRilRequestRaw(byte[] data, Message response) - { - // Just echo back data - if (response != null) { - AsyncResult.forMessage(response).result = data; - response.sendToTarget(); - } - } - - public void invokeOemRilRequestStrings(String[] strings, Message response) - { - // Just echo back data - if (response != null) { - AsyncResult.forMessage(response).result = strings; - response.sendToTarget(); - } - } - - //***** SimulatedRadioControl - - - /** Start the simulated phone ringing */ - public void - triggerRing(String number) - { - simulatedCallState.triggerRing(number); - mCallStateRegistrants.notifyRegistrants(); - } - - public void - progressConnectingCallState() - { - simulatedCallState.progressConnectingCallState(); - mCallStateRegistrants.notifyRegistrants(); - } - - /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */ - public void - progressConnectingToActive() - { - simulatedCallState.progressConnectingToActive(); - mCallStateRegistrants.notifyRegistrants(); - } - - /** automatically progress mobile originated calls to ACTIVE. - * default to true - */ - public void - setAutoProgressConnectingCall(boolean b) - { - simulatedCallState.setAutoProgressConnectingCall(b); - } - - public void - setNextDialFailImmediately(boolean b) - { - simulatedCallState.setNextDialFailImmediately(b); - } - - public void - setNextCallFailCause(int gsmCause) - { - nextCallFailCause = gsmCause; - } - - public void - triggerHangupForeground() - { - simulatedCallState.triggerHangupForeground(); - mCallStateRegistrants.notifyRegistrants(); - } - - /** hangup holding calls */ - public void - triggerHangupBackground() - { - simulatedCallState.triggerHangupBackground(); - mCallStateRegistrants.notifyRegistrants(); - } - - public void triggerSsn(int type, int code) - { - SuppServiceNotification not = new SuppServiceNotification(); - not.notificationType = type; - not.code = code; - mSsnRegistrant.notifyRegistrant(new AsyncResult(null, not, null)); - } - - public void - shutdown() - { - setRadioState(RadioState.RADIO_UNAVAILABLE); - Looper looper = mHandlerThread.getLooper(); - if (looper != null) { - looper.quit(); - } - } - - /** hangup all */ - - public void - triggerHangupAll() - { - simulatedCallState.triggerHangupAll(); - mCallStateRegistrants.notifyRegistrants(); - } - - public void - triggerIncomingSMS(String message) - { - //TODO - } - - public void - pauseResponses() - { - pausedResponseCount++; - } - - public void - resumeResponses() - { - pausedResponseCount--; - - if (pausedResponseCount == 0) { - for (int i = 0, s = pausedResponses.size(); i < s ; i++) { - pausedResponses.get(i).sendToTarget(); - } - pausedResponses.clear(); - } else { - Log.e("GSM", "SimulatedCommands.resumeResponses < 0"); - } - } - - //***** Private Methods - - private void unimplemented(Message result) - { - if (result != null) { - AsyncResult.forMessage(result).exception - = new RuntimeException("Unimplemented"); - - if (pausedResponseCount > 0) { - pausedResponses.add(result); - } else { - result.sendToTarget(); - } - } - } - - private void resultSuccess(Message result, Object ret) - { - if (result != null) { - AsyncResult.forMessage(result).result = ret; - if (pausedResponseCount > 0) { - pausedResponses.add(result); - } else { - result.sendToTarget(); - } - } - } - - private void resultFail(Message result, Throwable tr) - { - if (result != null) { - AsyncResult.forMessage(result).exception = tr; - if (pausedResponseCount > 0) { - pausedResponses.add(result); - } else { - result.sendToTarget(); - } - } - } - -} diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java b/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java deleted file mode 100644 index 340d788..0000000 --- a/telephony/java/com/android/internal/telephony/test/SimulatedGsmCallState.java +++ /dev/null @@ -1,843 +0,0 @@ -/* - * Copyright (C) 2006 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.test; - -import android.os.Looper; -import android.os.Message; -import android.os.Handler; -import android.telephony.PhoneNumberUtils; -import com.android.internal.telephony.ATParseEx; -import com.android.internal.telephony.gsm.DriverCall; -import java.util.List; -import java.util.ArrayList; - -import android.util.Log; - -class CallInfo -{ - enum State { - ACTIVE(0), - HOLDING(1), - DIALING(2), // MO call only - ALERTING(3), // MO call only - INCOMING(4), // MT call only - WAITING(5); // MT call only - - State (int value) {this.value = value;} - - private final int value; - public int value() {return value;}; - }; - - boolean isMT; - State state; - boolean isMpty; - String number; - int TOA; - - CallInfo (boolean isMT, State state, boolean isMpty, String number) - { - this.isMT = isMT; - this.state = state; - this.isMpty = isMpty; - this.number = number; - - if (number.length() > 0 && number.charAt(0) == '+') { - TOA = PhoneNumberUtils.TOA_International; - } else { - TOA = PhoneNumberUtils.TOA_Unknown; - } - } - - static CallInfo - createOutgoingCall(String number) - { - return new CallInfo (false, State.DIALING, false, number); - } - - static CallInfo - createIncomingCall(String number) - { - return new CallInfo (true, State.INCOMING, false, number); - } - - String - toCLCCLine(int index) - { - return - "+CLCC: " - + index + "," + (isMT ? "1" : "0") +"," - + state.value() + ",0," + (isMpty ? "1" : "0") - + ",\"" + number + "\"," + TOA; - } - - DriverCall - toDriverCall(int index) - { - DriverCall ret; - - ret = new DriverCall(); - - ret.index = index; - ret.isMT = isMT; - - try { - ret.state = DriverCall.stateFromCLCC(state.value()); - } catch (ATParseEx ex) { - throw new RuntimeException("should never happen", ex); - } - - ret.isMpty = isMpty; - ret.number = number; - ret.TOA = TOA; - ret.isVoice = true; - ret.als = 0; - - return ret; - } - - - boolean - isActiveOrHeld() - { - return state == State.ACTIVE || state == State.HOLDING; - } - - boolean - isConnecting() - { - return state == State.DIALING || state == State.ALERTING; - } - - boolean - isRinging() - { - return state == State.INCOMING || state == State.WAITING; - } - -} - -class InvalidStateEx extends Exception -{ - InvalidStateEx() - { - - } -} - - -class SimulatedGsmCallState extends Handler -{ - //***** Instance Variables - - CallInfo calls[] = new CallInfo[MAX_CALLS]; - - private boolean autoProgressConnecting = true; - private boolean nextDialFailImmediately; - - - //***** Event Constants - - static final int EVENT_PROGRESS_CALL_STATE = 1; - - //***** Constants - - static final int MAX_CALLS = 7; - /** number of msec between dialing -> alerting and alerting->active */ - static final int CONNECTING_PAUSE_MSEC = 5 * 100; - - - //***** Overridden from Handler - - public SimulatedGsmCallState(Looper looper) { - super(looper); - } - - public void - handleMessage(Message msg) - { - synchronized(this) { switch (msg.what) { - // PLEASE REMEMBER - // calls may have hung up by the time delayed events happen - - case EVENT_PROGRESS_CALL_STATE: - progressConnectingCallState(); - break; - }} - } - - //***** Public Methods - - - /** - * Start the simulated phone ringing - * true if succeeded, false if failed - */ - public boolean - triggerRing(String number) - { - synchronized (this) { - int empty = -1; - boolean isCallWaiting = false; - - // ensure there aren't already calls INCOMING or WAITING - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call == null && empty < 0) { - empty = i; - } else if (call != null - && (call.state == CallInfo.State.INCOMING - || call.state == CallInfo.State.WAITING) - ) { - Log.w("ModelInterpreter", - "triggerRing failed; phone already ringing"); - return false; - } else if (call != null) { - isCallWaiting = true; - } - } - - if (empty < 0 ) { - Log.w("ModelInterpreter", "triggerRing failed; all full"); - return false; - } - - calls[empty] = CallInfo.createIncomingCall( - PhoneNumberUtils.extractNetworkPortion(number)); - - if (isCallWaiting) { - calls[empty].state = CallInfo.State.WAITING; - } - - } - return true; - } - - /** If a call is DIALING or ALERTING, progress it to the next state */ - public void - progressConnectingCallState() - { - synchronized (this) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && call.state == CallInfo.State.DIALING) { - call.state = CallInfo.State.ALERTING; - - if (autoProgressConnecting) { - sendMessageDelayed( - obtainMessage(EVENT_PROGRESS_CALL_STATE, call), - CONNECTING_PAUSE_MSEC); - } - break; - } else if (call != null - && call.state == CallInfo.State.ALERTING - ) { - call.state = CallInfo.State.ACTIVE; - break; - } - } - } - } - - /** If a call is DIALING or ALERTING, progress it all the way to ACTIVE */ - public void - progressConnectingToActive() - { - synchronized (this) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && (call.state == CallInfo.State.DIALING - || call.state == CallInfo.State.ALERTING) - ) { - call.state = CallInfo.State.ACTIVE; - break; - } - } - } - } - - /** automatically progress mobile originated calls to ACTIVE. - * default to true - */ - public void - setAutoProgressConnectingCall(boolean b) - { - autoProgressConnecting = b; - } - - public void - setNextDialFailImmediately(boolean b) - { - nextDialFailImmediately = b; - } - - /** - * hangup ringing, dialing, or active calls - * returns true if call was hung up, false if not - */ - public boolean - triggerHangupForeground() - { - synchronized (this) { - boolean found; - - found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null - && (call.state == CallInfo.State.INCOMING - || call.state == CallInfo.State.WAITING) - ) { - calls[i] = null; - found = true; - } - } - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null - && (call.state == CallInfo.State.DIALING - || call.state == CallInfo.State.ACTIVE - || call.state == CallInfo.State.ALERTING) - ) { - calls[i] = null; - found = true; - } - } - return found; - } - } - - /** - * hangup holding calls - * returns true if call was hung up, false if not - */ - public boolean - triggerHangupBackground() - { - synchronized (this) { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && call.state == CallInfo.State.HOLDING) { - calls[i] = null; - found = true; - } - } - - return found; - } - } - - /** - * hangup all - * returns true if call was hung up, false if not - */ - public boolean - triggerHangupAll() - { - synchronized(this) { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (calls[i] != null) { - found = true; - } - - calls[i] = null; - } - - return found; - } - } - - public boolean - onAnswer() - { - synchronized (this) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null - && (call.state == CallInfo.State.INCOMING - || call.state == CallInfo.State.WAITING) - ) { - return switchActiveAndHeldOrWaiting(); - } - } - } - - return false; - } - - public boolean - onHangup() - { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null && call.state != CallInfo.State.WAITING) { - calls[i] = null; - found = true; - } - } - - return found; - } - - public boolean - onChld(char c0, char c1) - { - boolean ret; - int callIndex = 0; - - if (c1 != 0) { - callIndex = c1 - '1'; - - if (callIndex < 0 || callIndex >= calls.length) { - return false; - } - } - - switch (c0) { - case '0': - ret = releaseHeldOrUDUB(); - break; - case '1': - if (c1 <= 0) { - ret = releaseActiveAcceptHeldOrWaiting(); - } else { - if (calls[callIndex] == null) { - ret = false; - } else { - calls[callIndex] = null; - ret = true; - } - } - break; - case '2': - if (c1 <= 0) { - ret = switchActiveAndHeldOrWaiting(); - } else { - ret = separateCall(callIndex); - } - break; - case '3': - ret = conference(); - break; - case '4': - ret = explicitCallTransfer(); - break; - case '5': - if (true) { //just so javac doesnt complain about break - //CCBS not impled - ret = false; - } - break; - default: - ret = false; - - } - - return ret; - } - - public boolean - releaseHeldOrUDUB() { - boolean found = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.isRinging()) { - found = true; - calls[i] = null; - break; - } - } - - if (!found) { - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.HOLDING) { - found = true; - calls[i] = null; - // don't stop...there may be more than one - } - } - } - - return true; - } - - - public boolean - releaseActiveAcceptHeldOrWaiting() - { - boolean foundHeld = false; - boolean foundActive = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.ACTIVE) { - calls[i] = null; - foundActive = true; - } - } - - if (!foundActive) { - // FIXME this may not actually be how most basebands react - // CHLD=1 may not hang up dialing/alerting calls - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null - && (c.state == CallInfo.State.DIALING - || c.state == CallInfo.State.ALERTING) - ) { - calls[i] = null; - foundActive = true; - } - } - } - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.HOLDING) { - c.state = CallInfo.State.ACTIVE; - foundHeld = true; - } - } - - if (foundHeld) { - return true; - } - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.isRinging()) { - c.state = CallInfo.State.ACTIVE; - return true; - } - } - - return true; - } - - public boolean - switchActiveAndHeldOrWaiting() - { - boolean hasHeld = false; - - // first, are there held calls? - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null && c.state == CallInfo.State.HOLDING) { - hasHeld = true; - break; - } - } - - // Now, switch - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - if (c.state == CallInfo.State.ACTIVE) { - c.state = CallInfo.State.HOLDING; - } else if (c.state == CallInfo.State.HOLDING) { - c.state = CallInfo.State.ACTIVE; - } else if (!hasHeld && c.isRinging()) { - c.state = CallInfo.State.ACTIVE; - } - } - } - - return true; - } - - - public boolean - separateCall(int index) - { - try { - CallInfo c; - - c = calls[index]; - - if (c == null || c.isConnecting() || countActiveLines() != 1) { - return false; - } - - c.state = CallInfo.State.ACTIVE; - c.isMpty = false; - - for (int i = 0 ; i < calls.length ; i++) { - int countHeld=0, lastHeld=0; - - if (i != index) { - CallInfo cb = calls[i]; - - if (cb != null && cb.state == CallInfo.State.ACTIVE) { - cb.state = CallInfo.State.HOLDING; - countHeld++; - lastHeld = i; - } - } - - if (countHeld == 1) { - // if there's only one left, clear the MPTY flag - calls[lastHeld].isMpty = false; - } - } - - return true; - } catch (InvalidStateEx ex) { - return false; - } - } - - - - public boolean - conference() - { - int countCalls = 0; - - // if there's connecting calls, we can't do this yet - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - countCalls++; - - if (c.isConnecting()) { - return false; - } - } - } - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - c.state = CallInfo.State.ACTIVE; - if (countCalls > 0) { - c.isMpty = true; - } - } - } - - return true; - } - - public boolean - explicitCallTransfer() - { - int countCalls = 0; - - // if there's connecting calls, we can't do this yet - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - countCalls++; - - if (c.isConnecting()) { - return false; - } - } - } - - // disconnect the subscriber from both calls - return triggerHangupAll(); - } - - public boolean - onDial(String address) - { - CallInfo call; - int freeSlot = -1; - - Log.d("GSM", "SC> dial '" + address + "'"); - - if (nextDialFailImmediately) { - nextDialFailImmediately = false; - - Log.d("GSM", "SC< dial fail (per request)"); - return false; - } - - String phNum = PhoneNumberUtils.extractNetworkPortion(address); - - if (phNum.length() == 0) { - Log.d("GSM", "SC< dial fail (invalid ph num)"); - return false; - } - - // Ignore setting up GPRS - if (phNum.startsWith("*99") && phNum.endsWith("#")) { - Log.d("GSM", "SC< dial ignored (gprs)"); - return true; - } - - // There can be at most 1 active "line" when we initiate - // a new call - try { - if (countActiveLines() > 1) { - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } - } catch (InvalidStateEx ex) { - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } - - for (int i = 0 ; i < calls.length ; i++) { - if (freeSlot < 0 && calls[i] == null) { - freeSlot = i; - } - - if (calls[i] != null && !calls[i].isActiveOrHeld()) { - // Can't make outgoing calls when there is a ringing or - // connecting outgoing call - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } else if (calls[i] != null && calls[i].state == CallInfo.State.ACTIVE) { - // All active calls behome held - calls[i].state = CallInfo.State.HOLDING; - } - } - - if (freeSlot < 0) { - Log.d("GSM", "SC< dial fail (invalid call state)"); - return false; - } - - calls[freeSlot] = CallInfo.createOutgoingCall(phNum); - - if (autoProgressConnecting) { - sendMessageDelayed( - obtainMessage(EVENT_PROGRESS_CALL_STATE, calls[freeSlot]), - CONNECTING_PAUSE_MSEC); - } - - Log.d("GSM", "SC< dial (slot = " + freeSlot + ")"); - - return true; - } - - public List<DriverCall> - getDriverCalls() - { - ArrayList<DriverCall> ret = new ArrayList<DriverCall>(calls.length); - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - DriverCall dc; - - dc = c.toDriverCall(i + 1); - ret.add(dc); - } - } - - Log.d("GSM", "SC< getDriverCalls " + ret); - - return ret; - } - - public List<String> - getClccLines() - { - ArrayList<String> ret = new ArrayList<String>(calls.length); - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo c = calls[i]; - - if (c != null) { - ret.add((c.toCLCCLine(i + 1))); - } - } - - return ret; - } - - private int - countActiveLines() throws InvalidStateEx - { - boolean hasMpty = false; - boolean hasHeld = false; - boolean hasActive = false; - boolean hasConnecting = false; - boolean hasRinging = false; - boolean mptyIsHeld = false; - - for (int i = 0 ; i < calls.length ; i++) { - CallInfo call = calls[i]; - - if (call != null) { - if (!hasMpty && call.isMpty) { - mptyIsHeld = call.state == CallInfo.State.HOLDING; - } else if (call.isMpty && mptyIsHeld - && call.state == CallInfo.State.ACTIVE - ) { - Log.e("ModelInterpreter", "Invalid state"); - throw new InvalidStateEx(); - } else if (!call.isMpty && hasMpty && mptyIsHeld - && call.state == CallInfo.State.HOLDING - ) { - Log.e("ModelInterpreter", "Invalid state"); - throw new InvalidStateEx(); - } - - hasMpty |= call.isMpty; - hasHeld |= call.state == CallInfo.State.HOLDING; - hasActive |= call.state == CallInfo.State.ACTIVE; - hasConnecting |= call.isConnecting(); - hasRinging |= call.isRinging(); - } - } - - int ret = 0; - - if (hasHeld) ret++; - if (hasActive) ret++; - if (hasConnecting) ret++; - if (hasRinging) ret++; - - return ret; - } - -} diff --git a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java b/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java deleted file mode 100644 index 9e1a7c5..0000000 --- a/telephony/java/com/android/internal/telephony/test/SimulatedRadioControl.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2006 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.test; - -public interface SimulatedRadioControl -{ - public void triggerRing(String number); - - public void progressConnectingCallState(); - - public void progressConnectingToActive(); - - public void setAutoProgressConnectingCall(boolean b); - - public void setNextDialFailImmediately(boolean b); - - public void setNextCallFailCause(int gsmCause); - - public void triggerHangupForeground(); - - public void triggerHangupBackground(); - - public void triggerHangupAll(); - - public void triggerIncomingSMS(String message); - - public void shutdown(); - - /** Pause responses to async requests until (ref-counted) resumeResponses() */ - public void pauseResponses(); - - /** see pauseResponses */ - public void resumeResponses(); - - public void triggerSsn(int type, int code); - - /** Generates an incoming USSD message. */ - public void triggerIncomingUssd(String statusCode, String message); -} diff --git a/telephony/java/com/android/internal/telephony/test/package.html b/telephony/java/com/android/internal/telephony/test/package.html deleted file mode 100755 index c9f96a6..0000000 --- a/telephony/java/com/android/internal/telephony/test/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> |