Commit c38bb60d authored by Wink Saville's avatar Wink Saville Committed by Jean-Baptiste Queru
Browse files

Create telephony-common - DO NOT MERGE

telephony-common was created by moving some of
  frameworks/base/telephony
to:
  frameworks/opt/telephony

Change-Id: I32cbb5eec1fa239c1587e055c8f7ef4fc48fb62c
parent f4ba68aa
# Copyright (C) 2011 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
src/java/com/android/internal/telephony/ISms.aidl \
src/java/com/android/internal/telephony/IIccPhoneBook.aidl \
src/java/com/android/internal/telephony/EventLogTags.logtags \
LOCAL_SRC_FILES += $(call all-java-files-under, src/java)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := telephony-common
include $(BUILD_JAVA_LIBRARY)
# Include subdirectory makefiles
# ============================================================
include $(call all-makefiles-under,$(LOCAL_PATH))
# Copyright (C) 2011 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.
#
# If you don't need to do a full clean build but would like to touch
# a file or delete some intermediate files, add a clean step to the end
# of the list. These steps will only be run once, if they haven't been
# run before.
#
# E.g.:
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
#
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
# files that are missing or have been moved.
#
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
# Use $(OUT_DIR) to refer to the "out" directory.
#
# If you need to re-do something that's already mentioned, just copy
# the command and add it to the bottom of the list. E.g., if a change
# that you made last week required touching a file and a change you
# made today requires touching the same file, just copy the old
# touch step and add it to the end of the list.
#
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
#
# Copyright (C) 2010 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.
#
#
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_LIBRARIES := core framework
LOCAL_STATIC_JAVA_LIBRARIES := librilproto-java
LOCAL_MODULE := mockrilcontroller
include $(BUILD_STATIC_JAVA_LIBRARY)
/*
* Copyright (C) 2010, 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.mockril;
import android.os.Bundle;
import android.util.Log;
import com.android.internal.communication.MsgHeader;
import com.android.internal.communication.Msg;
import com.android.internal.telephony.RilChannel;
import com.android.internal.telephony.ril_proto.RilCtrlCmds;
import com.android.internal.telephony.ril_proto.RilCmds;
import com.google.protobuf.micro.MessageMicro;
import java.io.IOException;
/**
* Contain a list of commands to control Mock RIL. Before using these commands the devices
* needs to be set with Mock RIL. Refer to hardware/ril/mockril/README.txt for details.
*
*/
public class MockRilController {
private static final String TAG = "MockRILController";
private RilChannel mRilChannel = null;
private Msg mMessage = null;
public MockRilController() throws IOException {
mRilChannel = RilChannel.makeRilChannel();
}
/**
* Close the channel after the communication is done.
* This method has to be called after the test is finished.
*/
public void closeChannel() {
mRilChannel.close();
}
/**
* Send commands and return true on success
* @param cmd for MsgHeader
* @param token for MsgHeader
* @param status for MsgHeader
* @param pbData for Msg data
* @return true if command is sent successfully, false if it fails
*/
private boolean sendCtrlCommand(int cmd, long token, int status, MessageMicro pbData) {
try {
Msg.send(mRilChannel, cmd, token, status, pbData);
} catch (IOException e) {
Log.v(TAG, "send command : %d failed: " + e.getStackTrace());
return false;
}
return true;
}
/**
* Get control response
* @return Msg if response is received, else return null.
*/
private Msg getCtrlResponse() {
Msg response = null;
try {
response = Msg.recv(mRilChannel);
} catch (IOException e) {
Log.v(TAG, "receive response for getRadioState() error: " + e.getStackTrace());
return null;
}
return response;
}
/**
* @return the radio state if it is valid, otherwise return -1
*/
public int getRadioState() {
if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_GET_RADIO_STATE, 0, 0, null)) {
return -1;
}
Msg response = getCtrlResponse();
if (response == null) {
Log.v(TAG, "failed to get response");
return -1;
}
response.printHeader(TAG);
RilCtrlCmds.CtrlRspRadioState resp =
response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
int state = resp.getState();
if ((state >= RilCmds.RADIOSTATE_OFF) && (state <= RilCmds.RADIOSTATE_NV_READY))
return state;
else
return -1;
}
/**
* Set the radio state of mock ril to the given state
* @param state for given radio state
* @return true if the state is set successful, false if it fails
*/
public boolean setRadioState(int state) {
RilCtrlCmds.CtrlReqRadioState req = new RilCtrlCmds.CtrlReqRadioState();
if (state < 0 || state > RilCmds.RADIOSTATE_NV_READY) {
Log.v(TAG, "the give radio state is not valid.");
return false;
}
req.setState(state);
if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_RADIO_STATE, 0, 0, req)) {
Log.v(TAG, "send set radio state request failed.");
return false;
}
Msg response = getCtrlResponse();
if (response == null) {
Log.v(TAG, "failed to get response for setRadioState");
return false;
}
response.printHeader(TAG);
RilCtrlCmds.CtrlRspRadioState resp =
response.getDataAs(RilCtrlCmds.CtrlRspRadioState.class);
int curstate = resp.getState();
return curstate == state;
}
/**
* Start an incoming call for the given phone number
*
* @param phoneNumber is the number to show as incoming call
* @return true if the incoming call is started successfully, false if it fails.
*/
public boolean startIncomingCall(String phoneNumber) {
RilCtrlCmds.CtrlReqSetMTCall req = new RilCtrlCmds.CtrlReqSetMTCall();
req.setPhoneNumber(phoneNumber);
if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_MT_CALL, 0, 0, req)) {
Log.v(TAG, "send CMD_SET_MT_CALL request failed");
return false;
}
return true;
}
/**
* Hang up a connection remotelly for the given call fail cause
*
* @param connectionID is the connection to be hung up
* @param failCause is the call fail cause defined in ril.h
* @return true if the hangup is successful, false if it fails
*/
public boolean hangupRemote(int connectionId, int failCause) {
RilCtrlCmds.CtrlHangupConnRemote req = new RilCtrlCmds.CtrlHangupConnRemote();
req.setConnectionId(connectionId);
req.setCallFailCause(failCause);
if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_HANGUP_CONN_REMOTE, 0, 0, req)) {
Log.v(TAG, "send CTRL_CMD_HANGUP_CONN_REMOTE request failed");
return false;
}
return true;
}
/**
* Set call transition flag to the Mock Ril
*
* @param flag is a boolean value for the call transiton flag
* true: call transition: dialing->alert, alert->active is controlled
* false: call transition is automatically handled by Mock Ril
* @return true if the request is successful, false if it failed to set the flag
*/
public boolean setCallTransitionFlag(boolean flag) {
RilCtrlCmds.CtrlSetCallTransitionFlag req = new RilCtrlCmds.CtrlSetCallTransitionFlag();
req.setFlag(flag);
if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_TRANSITION_FLAG, 0, 0, req)) {
Log.v(TAG, "send CTRL_CMD_SET_CALL_TRANSITION_FLAG request failed");
return false;
}
return true;
}
/**
* Set the dialing call to alert if the call transition flag is true
*
* @return true if the call transition is successful, false if it fails
*/
public boolean setDialCallToAlert() {
if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ALERT, 0, 0, null)) {
Log.v(TAG, "send CTRL_CMD_SET_CALL_ALERT request failed");
return false;
}
return true;
}
/**
* Set the alert call to active if the call transition flag is true
*
* @return true if the call transition is successful, false if it fails
*/
public boolean setAlertCallToActive() {
if (!sendCtrlCommand(RilCtrlCmds.CTRL_CMD_SET_CALL_ACTIVE, 0, 0, null)) {
Log.v(TAG, "send CTRL_CMD_SET_CALL_ACTIVE request failed");
return false;
}
return true;
}
}
This diff is collapsed.
/*
* Copyright (C) 2011 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 android.telephony;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Typeface;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.Telephony;
import android.telephony.SmsCbCmasInfo;
import android.telephony.SmsCbEtwsInfo;
import android.telephony.SmsCbLocation;
import android.telephony.SmsCbMessage;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.format.DateUtils;
import android.text.style.StyleSpan;
/**
* Application wrapper for {@link SmsCbMessage}. This is Parcelable so that
* decoded broadcast message objects can be passed between running Services.
* New broadcasts are received by the CellBroadcastReceiver app, which exports
* the database of previously received broadcasts at "content://cellbroadcasts/".
* The "android.permission.READ_CELL_BROADCASTS" permission is required to read
* from the ContentProvider, and writes to the database are not allowed.<p>
*
* Use {@link #createFromCursor} to create CellBroadcastMessage objects from rows
* in the database cursor returned by the ContentProvider.
*
* {@hide}
*/
public class CellBroadcastMessage implements Parcelable {
/** Identifier for getExtra() when adding this object to an Intent. */
public static final String SMS_CB_MESSAGE_EXTRA =
"com.android.cellbroadcastreceiver.SMS_CB_MESSAGE";
/** SmsCbMessage. */
private final SmsCbMessage mSmsCbMessage;
private final long mDeliveryTime;
private boolean mIsRead;
public CellBroadcastMessage(SmsCbMessage message) {
mSmsCbMessage = message;
mDeliveryTime = System.currentTimeMillis();
mIsRead = false;
}
private CellBroadcastMessage(SmsCbMessage message, long deliveryTime, boolean isRead) {
mSmsCbMessage = message;
mDeliveryTime = deliveryTime;
mIsRead = isRead;
}
private CellBroadcastMessage(Parcel in) {
mSmsCbMessage = new SmsCbMessage(in);
mDeliveryTime = in.readLong();
mIsRead = (in.readInt() != 0);
}
/** Parcelable: no special flags. */
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
mSmsCbMessage.writeToParcel(out, flags);
out.writeLong(mDeliveryTime);
out.writeInt(mIsRead ? 1 : 0);
}
public static final Parcelable.Creator<CellBroadcastMessage> CREATOR
= new Parcelable.Creator<CellBroadcastMessage>() {
public CellBroadcastMessage createFromParcel(Parcel in) {
return new CellBroadcastMessage(in);
}
public CellBroadcastMessage[] newArray(int size) {
return new CellBroadcastMessage[size];
}
};
/**
* Create a CellBroadcastMessage from a row in the database.
* @param cursor an open SQLite cursor pointing to the row to read
* @return the new CellBroadcastMessage
* @throws IllegalArgumentException if one of the required columns is missing
*/
public static CellBroadcastMessage createFromCursor(Cursor cursor) {
int geoScope = cursor.getInt(
cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE));
int serialNum = cursor.getInt(
cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERIAL_NUMBER));
int category = cursor.getInt(
cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.SERVICE_CATEGORY));
String language = cursor.getString(
cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.LANGUAGE_CODE));
String body = cursor.getString(
cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_BODY));
int format = cursor.getInt(
cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_FORMAT));
int priority = cursor.getInt(
cursor.getColumnIndexOrThrow(Telephony.CellBroadcasts.MESSAGE_PRIORITY));
String plmn;
int plmnColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.PLMN);
if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) {
plmn = cursor.getString(plmnColumn);
} else {
plmn = null;
}
int lac;
int lacColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.LAC);
if (lacColumn != -1 && !cursor.isNull(lacColumn)) {
lac = cursor.getInt(lacColumn);
} else {
lac = -1;
}
int cid;
int cidColumn = cursor.getColumnIndex(Telephony.CellBroadcasts.CID);
if (cidColumn != -1 && !cursor.isNull(cidColumn)) {
cid = cursor.getInt(cidColumn);
} else {
cid = -1;
}
SmsCbLocation location = new SmsCbLocation(plmn, lac, cid);
SmsCbEtwsInfo etwsInfo;
int etwsWarningTypeColumn = cursor.getColumnIndex(
Telephony.CellBroadcasts.ETWS_WARNING_TYPE);
if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) {
int warningType = cursor.getInt(etwsWarningTypeColumn);
etwsInfo = new SmsCbEtwsInfo(warningType, false, false, null);
} else {
etwsInfo = null;
}
SmsCbCmasInfo cmasInfo;
int cmasMessageClassColumn = cursor.getColumnIndex(
Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS);
if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) {
int messageClass = cursor.getInt(cmasMessageClassColumn);
int cmasCategory;
int cmasCategoryColumn = cursor.getColumnIndex(
Telephony.CellBroadcasts.CMAS_CATEGORY);
if (cmasCategoryColumn != -1 && !cursor.isNull(cmasCategoryColumn)) {
cmasCategory = cursor.getInt(cmasCategoryColumn);
} else {
cmasCategory = SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN;
}
int responseType;
int cmasResponseTypeColumn = cursor.getColumnIndex(
Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE);
if (cmasResponseTypeColumn != -1 && !cursor.isNull(cmasResponseTypeColumn)) {
responseType = cursor.getInt(cmasResponseTypeColumn);
} else {
responseType = SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN;
}
int severity;
int cmasSeverityColumn = cursor.getColumnIndex(
Telephony.CellBroadcasts.CMAS_SEVERITY);
if (cmasSeverityColumn != -1 && !cursor.isNull(cmasSeverityColumn)) {
severity = cursor.getInt(cmasSeverityColumn);
} else {
severity = SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN;
}
int urgency;
int cmasUrgencyColumn = cursor.getColumnIndex(
Telephony.CellBroadcasts.CMAS_URGENCY);
if (cmasUrgencyColumn != -1 && !cursor.isNull(cmasUrgencyColumn)) {
urgency = cursor.getInt(cmasUrgencyColumn);
} else {
urgency = SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN;
}
int certainty;
int cmasCertaintyColumn = cursor.getColumnIndex(
Telephony.CellBroadcasts.CMAS_CERTAINTY);
if (cmasCertaintyColumn != -1 && !cursor.isNull(cmasCertaintyColumn)) {
certainty = cursor.getInt(cmasCertaintyColumn);
} else {
certainty = SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN;
}
cmasInfo = new SmsCbCmasInfo(messageClass, cmasCategory, responseType, severity,
urgency, certainty);
} else {
cmasInfo = null;
}
SmsCbMessage msg = new SmsCbMessage(format, geoScope, serialNum, location, category,
language, body, priority, etwsInfo, cmasInfo);
long deliveryTime = cursor.getLong(cursor.getColumnIndexOrThrow(
Telephony.CellBroadcasts.DELIVERY_TIME));
boolean isRead = (cursor.getInt(cursor.getColumnIndexOrThrow(
Telephony.CellBroadcasts.MESSAGE_READ)) != 0);
return new CellBroadcastMessage(msg, deliveryTime, isRead);
}
/**
* Return a ContentValues object for insertion into the database.
* @return a new ContentValues object containing this object's data
*/
public ContentValues getContentValues() {
ContentValues cv = new ContentValues(16);
SmsCbMessage msg = mSmsCbMessage;
cv.put(Telephony.CellBroadcasts.GEOGRAPHICAL_SCOPE, msg.getGeographicalScope());
SmsCbLocation location = msg.getLocation();
if (location.getPlmn() != null) {
cv.put(Telephony.CellBroadcasts.PLMN, location.getPlmn());
}
if (location.getLac() != -1) {
cv.put(Telephony.CellBroadcasts.LAC, location.getLac());
}
if (location.getCid() != -1) {
cv.put(Telephony.CellBroadcasts.CID, location.getCid());
}
cv.put(Telephony.CellBroadcasts.SERIAL_NUMBER, msg.getSerialNumber());
cv.put(Telephony.CellBroadcasts.SERVICE_CATEGORY, msg.getServiceCategory());
cv.put(Telephony.CellBroadcasts.LANGUAGE_CODE, msg.getLanguageCode());
cv.put(Telephony.CellBroadcasts.MESSAGE_BODY, msg.getMessageBody());
cv.put(Telephony.CellBroadcasts.DELIVERY_TIME, mDeliveryTime);
cv.put(Telephony.CellBroadcasts.MESSAGE_READ, mIsRead);
cv.put(Telephony.CellBroadcasts.MESSAGE_FORMAT, msg.getMessageFormat());
cv.put(Telephony.CellBroadcasts.MESSAGE_PRIORITY, msg.getMessagePriority());
SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
if (etwsInfo != null) {
cv.put(Telephony.CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType());
}
SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
if (cmasInfo != null) {
cv.put(Telephony.CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass());
cv.put(Telephony.CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory());
cv.put(Telephony.CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType());
cv.put(Telephony.CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity());
cv.put(Telephony.CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency());
cv.put(Telephony.CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty());
}
return cv;
}
/**
* Set or clear the "read message" flag.
* @param isRead true if the message has been read; false if not
*/
public void setIsRead(boolean isRead) {
mIsRead = isRead;
}
public String getLanguageCode() {
return mSmsCbMessage.getLanguageCode();
}
public int getServiceCategory() {
return mSmsCbMessage.getServiceCategory();
}
public long getDeliveryTime() {
return mDeliveryTime;
}
public String getMessageBody() {
return mSmsCbMessage.getMessageBody();
}
public boolean isRead() {
return mIsRead;
}
public int getSerialNumber() {
return mSmsCbMessage.getSerialNumber();
}
public SmsCbCmasInfo getCmasWarningInfo() {
return mSmsCbMessage.getCmasWarningInfo();
}
public SmsCbEtwsInfo getEtwsWarningInfo() {
return mSmsCbMessage.getEtwsWarningInfo();
}
/**
* Return whether the broadcast is an emergency (PWS) message type.
* This includes lower priority test messages and Amber alerts.
*
* All public alerts show the flashing warning icon in the dialog,
* but only emergency alerts play the alert sound and speak the message.
*
* @return true if the message is PWS type; false otherwise
*/
public boolean isPublicAlertMessage() {
return mSmsCbMessage.isEmergencyMessage();
}
/**
* Returns whether the broadcast is an emergency (PWS) message type,
* including test messages, but excluding lower priority Amber alert broadcasts.
*
* @return true if the message is PWS type, excluding Amber alerts
*/
public boolean isEmergencyAlertMessage() {
if (!mSmsCbMessage.isEmergencyMessage()) {
return false;
}
SmsCbCmasInfo cmasInfo = mSmsCbMessage.getCmasWarningInfo();
if (cmasInfo != null &&
cmasInfo.getMessageClass() == SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY) {
return false;
}
return true;
}
/**
* Return whether the broadcast is an ETWS emergency message type.
* @return true if the message is ETWS emergency type; false otherwise
*/
public boolean isEtwsMessage() {
return mSmsCbMessage.isEtwsMessage();
}
/**
* Return whether the broadcast is a CMAS emergency message type.
* @return true if the message is CMAS emergency type; false otherwise
*/
public boolean isCmasMessage() {
return mSmsCbMessage.isCmasMessage();
}
/**
* Return the CMAS message class.
* @return the CMAS message class, e.g. {@link SmsCbCmasInfo#CMAS_CLASS_SEVERE_THREAT}, or
* {@link SmsCbCmasInfo#CMAS_CLASS_UNKNOWN} if this is not a CMAS alert
*/
public int getCmasMessageClass() {
if (mSmsCbMessage.isCmasMessage()) {
return mSmsCbMessage.getCmasWarningInfo().getMessageClass();
} else {
return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN;
}
}
/**
* Return whether the broadcast is an ETWS popup alert.
* This method checks the message ID and the message code.
* @return true if the message indicates an ETWS popup alert
*/
public boolean isEtwsPopupAlert() {
SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
return etwsInfo != null && etwsInfo.isPopupAlert();
}
/**
* Return whether the broadcast is an ETWS emergency user alert.
* This method checks the message ID and the message code.
* @return true if the message indicates an ETWS emergency user alert
*/
public boolean isEtwsEmergencyUserAlert() {
SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
return etwsInfo != null && etwsInfo.isEmergencyUserAlert();
}
/**
* Return whether the broadcast is an ETWS test message.
* @return true if the message is an ETWS test message; false otherwise
*/
public boolean isEtwsTestMessage() {
SmsCbEtwsInfo etwsInfo = mSmsCbMessage.getEtwsWarningInfo();
return etwsInfo != null &&
etwsInfo.getWarningType() == SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE;
}
/**
* Return the abbreviated date string for the message delivery time.
* @param context the context object
* @return a String to use in the broadcast list UI
*/
public String getDateString(Context context) {
int flags = DateUtils.FORMAT_NO_NOON_MIDNIGHT | DateUtils.FORMAT_SHOW_TIME |
DateUtils.FORMAT_ABBREV_ALL | DateUtils.FORMAT_SHOW_DATE |
DateUtils.FORMAT_CAP_AMPM;
return DateUtils.formatDateTime(context, mDeliveryTime, flags);
}
/**
* Return the date string for the message delivery time, suitable for text-to-speech.
* @param context the context object
* @return a String for populating the list item AccessibilityEvent for TTS
*/
public String getSpokenDateString(Context context) {
int flags = DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE;
return DateUtils.formatDateTime(context, mDeliveryTime, flags);
}
}
/*
* Copyright (C) 2012 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 android.telephony;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Contains CMAS warning notification Type 1 elements for a {@link SmsCbMessage}.
* Supported values for each element are defined in TIA-1149-0-1 (CMAS over CDMA) and
* 3GPP TS 23.041 (for GSM/UMTS).
*
* {@hide}
*/
public class SmsCbCmasInfo implements Parcelable {
// CMAS message class (in GSM/UMTS message identifier or CDMA service category).
/** Presidential-level alert (Korean Public Alert System Class 0 message). */
public static final int CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT = 0x00;
/** Extreme threat to life and property (Korean Public Alert System Class 1 message). */
public static final int CMAS_CLASS_EXTREME_THREAT = 0x01;
/** Severe threat to life and property (Korean Public Alert System Class 1 message). */
public static final int CMAS_CLASS_SEVERE_THREAT = 0x02;
/** Child abduction emergency (AMBER Alert). */
public static final int CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY = 0x03;
/** CMAS test message. */
public static final int CMAS_CLASS_REQUIRED_MONTHLY_TEST = 0x04;
/** CMAS exercise. */
public static final int CMAS_CLASS_CMAS_EXERCISE = 0x05;
/** CMAS category for operator defined use. */
public static final int CMAS_CLASS_OPERATOR_DEFINED_USE = 0x06;
/** CMAS category for warning types that are reserved for future extension. */
public static final int CMAS_CLASS_UNKNOWN = -1;
// CMAS alert category (in CDMA type 1 elements record).
/** CMAS alert category: Geophysical including landslide. */
public static final int CMAS_CATEGORY_GEO = 0x00;
/** CMAS alert category: Meteorological including flood. */
public static final int CMAS_CATEGORY_MET = 0x01;
/** CMAS alert category: General emergency and public safety. */
public static final int CMAS_CATEGORY_SAFETY = 0x02;
/** CMAS alert category: Law enforcement, military, homeland/local/private security. */
public static final int CMAS_CATEGORY_SECURITY = 0x03;
/** CMAS alert category: Rescue and recovery. */
public static final int CMAS_CATEGORY_RESCUE = 0x04;
/** CMAS alert category: Fire suppression and rescue. */
public static final int CMAS_CATEGORY_FIRE = 0x05;
/** CMAS alert category: Medical and public health. */
public static final int CMAS_CATEGORY_HEALTH = 0x06;
/** CMAS alert category: Pollution and other environmental. */
public static final int CMAS_CATEGORY_ENV = 0x07;
/** CMAS alert category: Public and private transportation. */
public static final int CMAS_CATEGORY_TRANSPORT = 0x08;
/** CMAS alert category: Utility, telecom, other non-transport infrastructure. */
public static final int CMAS_CATEGORY_INFRA = 0x09;
/** CMAS alert category: Chem, bio, radiological, nuclear, high explosive threat or attack. */
public static final int CMAS_CATEGORY_CBRNE = 0x0a;
/** CMAS alert category: Other events. */
public static final int CMAS_CATEGORY_OTHER = 0x0b;
/**
* CMAS alert category is unknown. The category is only available for CDMA broadcasts
* containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
*/
public static final int CMAS_CATEGORY_UNKNOWN = -1;
// CMAS response type (in CDMA type 1 elements record).
/** CMAS response type: Take shelter in place. */
public static final int CMAS_RESPONSE_TYPE_SHELTER = 0x00;
/** CMAS response type: Evacuate (Relocate). */
public static final int CMAS_RESPONSE_TYPE_EVACUATE = 0x01;
/** CMAS response type: Make preparations. */
public static final int CMAS_RESPONSE_TYPE_PREPARE = 0x02;
/** CMAS response type: Execute a pre-planned activity. */
public static final int CMAS_RESPONSE_TYPE_EXECUTE = 0x03;
/** CMAS response type: Attend to information sources. */
public static final int CMAS_RESPONSE_TYPE_MONITOR = 0x04;
/** CMAS response type: Avoid hazard. */
public static final int CMAS_RESPONSE_TYPE_AVOID = 0x05;
/** CMAS response type: Evaluate the information in this message (not for public warnings). */
public static final int CMAS_RESPONSE_TYPE_ASSESS = 0x06;
/** CMAS response type: No action recommended. */
public static final int CMAS_RESPONSE_TYPE_NONE = 0x07;
/**
* CMAS response type is unknown. The response type is only available for CDMA broadcasts
* containing a type 1 elements record, so GSM and UMTS broadcasts always return unknown.
*/
public static final int CMAS_RESPONSE_TYPE_UNKNOWN = -1;
// 4-bit CMAS severity (in GSM/UMTS message identifier or CDMA type 1 elements record).
/** CMAS severity type: Extraordinary threat to life or property. */
public static final int CMAS_SEVERITY_EXTREME = 0x0;
/** CMAS severity type: Significant threat to life or property. */
public static final int CMAS_SEVERITY_SEVERE = 0x1;
/**
* CMAS alert severity is unknown. The severity is available for CDMA warning alerts
* containing a type 1 elements record and for all GSM and UMTS alerts except for the
* Presidential-level alert class (Korean Public Alert System Class 0).
*/
public static final int CMAS_SEVERITY_UNKNOWN = -1;
// CMAS urgency (in GSM/UMTS message identifier or CDMA type 1 elements record).
/** CMAS urgency type: Responsive action should be taken immediately. */
public static final int CMAS_URGENCY_IMMEDIATE = 0x0;
/** CMAS urgency type: Responsive action should be taken within the next hour. */
public static final int CMAS_URGENCY_EXPECTED = 0x1;
/**
* CMAS alert urgency is unknown. The urgency is available for CDMA warning alerts
* containing a type 1 elements record and for all GSM and UMTS alerts except for the
* Presidential-level alert class (Korean Public Alert System Class 0).
*/
public static final int CMAS_URGENCY_UNKNOWN = -1;
// CMAS certainty (in GSM/UMTS message identifier or CDMA type 1 elements record).
/** CMAS certainty type: Determined to have occurred or to be ongoing. */
public static final int CMAS_CERTAINTY_OBSERVED = 0x0;
/** CMAS certainty type: Likely (probability > ~50%). */
public static final int CMAS_CERTAINTY_LIKELY = 0x1;
/**
* CMAS alert certainty is unknown. The certainty is available for CDMA warning alerts
* containing a type 1 elements record and for all GSM and UMTS alerts except for the
* Presidential-level alert class (Korean Public Alert System Class 0).
*/
public static final int CMAS_CERTAINTY_UNKNOWN = -1;
/** CMAS message class. */
private final int mMessageClass;
/** CMAS category. */
private final int mCategory;
/** CMAS response type. */
private final int mResponseType;
/** CMAS severity. */
private final int mSeverity;
/** CMAS urgency. */
private final int mUrgency;
/** CMAS certainty. */
private final int mCertainty;
/** Create a new SmsCbCmasInfo object with the specified values. */
public SmsCbCmasInfo(int messageClass, int category, int responseType, int severity,
int urgency, int certainty) {
mMessageClass = messageClass;
mCategory = category;
mResponseType = responseType;
mSeverity = severity;
mUrgency = urgency;
mCertainty = certainty;
}
/** Create a new SmsCbCmasInfo object from a Parcel. */
SmsCbCmasInfo(Parcel in) {
mMessageClass = in.readInt();
mCategory = in.readInt();
mResponseType = in.readInt();
mSeverity = in.readInt();
mUrgency = in.readInt();
mCertainty = in.readInt();
}
/**
* Flatten this object into a Parcel.
*
* @param dest The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written (ignored).
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mMessageClass);
dest.writeInt(mCategory);
dest.writeInt(mResponseType);
dest.writeInt(mSeverity);
dest.writeInt(mUrgency);
dest.writeInt(mCertainty);
}
/**
* Returns the CMAS message class, e.g. {@link #CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT}.
* @return one of the {@code CMAS_CLASS} values
*/
public int getMessageClass() {
return mMessageClass;
}
/**
* Returns the CMAS category, e.g. {@link #CMAS_CATEGORY_GEO}.
* @return one of the {@code CMAS_CATEGORY} values
*/
public int getCategory() {
return mCategory;
}
/**
* Returns the CMAS response type, e.g. {@link #CMAS_RESPONSE_TYPE_SHELTER}.
* @return one of the {@code CMAS_RESPONSE_TYPE} values
*/
public int getResponseType() {
return mResponseType;
}
/**
* Returns the CMAS severity, e.g. {@link #CMAS_SEVERITY_EXTREME}.
* @return one of the {@code CMAS_SEVERITY} values
*/
public int getSeverity() {
return mSeverity;
}
/**
* Returns the CMAS urgency, e.g. {@link #CMAS_URGENCY_IMMEDIATE}.
* @return one of the {@code CMAS_URGENCY} values
*/
public int getUrgency() {
return mUrgency;
}
/**
* Returns the CMAS certainty, e.g. {@link #CMAS_CERTAINTY_OBSERVED}.
* @return one of the {@code CMAS_CERTAINTY} values
*/
public int getCertainty() {
return mCertainty;
}
@Override
public String toString() {
return "SmsCbCmasInfo{messageClass=" + mMessageClass + ", category=" + mCategory
+ ", responseType=" + mResponseType + ", severity=" + mSeverity
+ ", urgency=" + mUrgency + ", certainty=" + mCertainty + '}';
}
/**
* Describe the kinds of special objects contained in the marshalled representation.
* @return a bitmask indicating this Parcelable contains no special objects
*/
@Override
public int describeContents() {
return 0;
}
/** Creator for unparcelling objects. */
public static final Parcelable.Creator<SmsCbCmasInfo>
CREATOR = new Parcelable.Creator<SmsCbCmasInfo>() {
public SmsCbCmasInfo createFromParcel(Parcel in) {
return new SmsCbCmasInfo(in);
}
public SmsCbCmasInfo[] newArray(int size) {
return new SmsCbCmasInfo[size];
}
};
}
/*
* Copyright (C) 2012 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 android.telephony;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.format.Time;
import com.android.internal.telephony.IccUtils;
import java.util.Arrays;
/**
* Contains information elements for a GSM or UMTS ETWS warning notification.
* Supported values for each element are defined in 3GPP TS 23.041.
*
* {@hide}
*/
public class SmsCbEtwsInfo implements Parcelable {
/** ETWS warning type for earthquake. */
public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00;
/** ETWS warning type for tsunami. */
public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01;
/** ETWS warning type for earthquake and tsunami. */
public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02;
/** ETWS warning type for test messages. */
public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 0x03;
/** ETWS warning type for other emergency types. */
public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 0x04;
/** Unknown ETWS warning type. */
public static final int ETWS_WARNING_TYPE_UNKNOWN = -1;
/** One of the ETWS warning type constants defined in this class. */
private final int mWarningType;
/** Whether or not to activate the emergency user alert tone and vibration. */
private final boolean mEmergencyUserAlert;
/** Whether or not to activate a popup alert. */
private final boolean mActivatePopup;
/**
* 50-byte security information (ETWS primary notification for GSM only). As of Release 10,
* 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp
* and digital signature if received. Therefore it is treated as a raw byte array and
* parceled with the broadcast intent if present, but the timestamp is only computed if an
* application asks for the individual components.
*/
private final byte[] mWarningSecurityInformation;
/** Create a new SmsCbEtwsInfo object with the specified values. */
public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup,
byte[] warningSecurityInformation) {
mWarningType = warningType;
mEmergencyUserAlert = emergencyUserAlert;
mActivatePopup = activatePopup;
mWarningSecurityInformation = warningSecurityInformation;
}
/** Create a new SmsCbEtwsInfo object from a Parcel. */
SmsCbEtwsInfo(Parcel in) {
mWarningType = in.readInt();
mEmergencyUserAlert = (in.readInt() != 0);
mActivatePopup = (in.readInt() != 0);
mWarningSecurityInformation = in.createByteArray();
}
/**
* Flatten this object into a Parcel.
*
* @param dest The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written (ignored).
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mWarningType);
dest.writeInt(mEmergencyUserAlert ? 1 : 0);
dest.writeInt(mActivatePopup ? 1 : 0);
dest.writeByteArray(mWarningSecurityInformation);
}
/**
* Returns the ETWS warning type.
* @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE}
*/
public int getWarningType() {
return mWarningType;
}
/**
* Returns the ETWS emergency user alert flag.
* @return true to notify terminal to activate emergency user alert; false otherwise
*/
public boolean isEmergencyUserAlert() {
return mEmergencyUserAlert;
}
/**
* Returns the ETWS activate popup flag.
* @return true to notify terminal to activate display popup; false otherwise
*/
public boolean isPopupAlert() {
return mActivatePopup;
}
/**
* Returns the Warning-Security-Information timestamp (GSM primary notifications only).
* As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received.
* @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present
*/
public long getPrimaryNotificationTimestamp() {
if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) {
return 0;
}
int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]);
int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]);
int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]);
int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]);
int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]);
int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]);
// For the timezone, the most significant bit of the
// least significant nibble is the sign byte
// (meaning the max range of this field is 79 quarter-hours,
// which is more than enough)
byte tzByte = mWarningSecurityInformation[6];
// Mask out sign bit.
int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08)));
timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset;
Time time = new Time(Time.TIMEZONE_UTC);
// We only need to support years above 2000.
time.year = year + 2000;
time.month = month - 1;
time.monthDay = day;
time.hour = hour;
time.minute = minute;
time.second = second;
// Timezone offset is in quarter hours.
return time.toMillis(true) - (long) (timezoneOffset * 15 * 60 * 1000);
}
/**
* Returns the digital signature (GSM primary notifications only). As of Release 10,
* 3GPP TS 23.041 states that the UE shall ignore this value if received.
* @return a byte array containing a copy of the primary notification digital signature
*/
public byte[] getPrimaryNotificationSignature() {
if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) {
return null;
}
return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50);
}
@Override
public String toString() {
return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert="
+ mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}';
}
/**
* Describe the kinds of special objects contained in the marshalled representation.
* @return a bitmask indicating this Parcelable contains no special objects
*/
@Override
public int describeContents() {
return 0;
}
/** Creator for unparcelling objects. */
public static final Creator<SmsCbEtwsInfo> CREATOR = new Creator<SmsCbEtwsInfo>() {
public SmsCbEtwsInfo createFromParcel(Parcel in) {
return new SmsCbEtwsInfo(in);
}
public SmsCbEtwsInfo[] newArray(int size) {
return new SmsCbEtwsInfo[size];
}
};
}
/*
* Copyright (C) 2012 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 android.telephony;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.gsm.GsmCellLocation;
/**
* Represents the location and geographical scope of a cell broadcast message.
* For GSM/UMTS, the Location Area and Cell ID are set when the broadcast
* geographical scope is cell wide or Location Area wide. For CDMA, the
* broadcast geographical scope is always PLMN wide.
*
* @hide
*/
public class SmsCbLocation implements Parcelable {
/** The PLMN. Note that this field may be an empty string, but isn't allowed to be null. */
private final String mPlmn;
private final int mLac;
private final int mCid;
/**
* Construct an empty location object. This is used for some test cases, and for
* cell broadcasts saved in older versions of the database without location info.
*/
public SmsCbLocation() {
mPlmn = "";
mLac = -1;
mCid = -1;
}
/**
* Construct a location object for the PLMN. This class is immutable, so
* the same object can be reused for multiple broadcasts.
*/
public SmsCbLocation(String plmn) {
mPlmn = plmn;
mLac = -1;
mCid = -1;
}
/**
* Construct a location object for the PLMN, LAC, and Cell ID. This class is immutable, so
* the same object can be reused for multiple broadcasts.
*/
public SmsCbLocation(String plmn, int lac, int cid) {
mPlmn = plmn;
mLac = lac;
mCid = cid;
}
/**
* Initialize the object from a Parcel.
*/
public SmsCbLocation(Parcel in) {
mPlmn = in.readString();
mLac = in.readInt();
mCid = in.readInt();
}
/**
* Returns the MCC/MNC of the network as a String.
* @return the PLMN identifier (MCC+MNC) as a String
*/
public String getPlmn() {
return mPlmn;
}
/**
* Returns the GSM location area code, or UMTS service area code.
* @return location area code, -1 if unknown, 0xffff max legal value
*/
public int getLac() {
return mLac;
}
/**
* Returns the GSM or UMTS cell ID.
* @return gsm cell id, -1 if unknown, 0xffff max legal value
*/
public int getCid() {
return mCid;
}
@Override
public int hashCode() {
int hash = mPlmn.hashCode();
hash = hash * 31 + mLac;
hash = hash * 31 + mCid;
return hash;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o == null || !(o instanceof SmsCbLocation)) {
return false;
}
SmsCbLocation other = (SmsCbLocation) o;
return mPlmn.equals(other.mPlmn) && mLac == other.mLac && mCid == other.mCid;
}
@Override
public String toString() {
return '[' + mPlmn + ',' + mLac + ',' + mCid + ']';
}
/**
* Test whether this location is within the location area of the specified object.
*
* @param area the location area to compare with this location
* @return true if this location is contained within the specified location area
*/
public boolean isInLocationArea(SmsCbLocation area) {
if (mCid != -1 && mCid != area.mCid) {
return false;
}
if (mLac != -1 && mLac != area.mLac) {
return false;
}
return mPlmn.equals(area.mPlmn);
}
/**
* Test whether this location is within the location area of the CellLocation.
*
* @param plmn the PLMN to use for comparison
* @param lac the Location Area (GSM) or Service Area (UMTS) to compare with
* @param cid the Cell ID to compare with
* @return true if this location is contained within the specified PLMN, LAC, and Cell ID
*/
public boolean isInLocationArea(String plmn, int lac, int cid) {
if (!mPlmn.equals(plmn)) {
return false;
}
if (mLac != -1 && mLac != lac) {
return false;
}
if (mCid != -1 && mCid != cid) {
return false;
}
return true;
}
/**
* Flatten this object into a Parcel.
*
* @param dest The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written (ignored).
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mPlmn);
dest.writeInt(mLac);
dest.writeInt(mCid);
}
public static final Parcelable.Creator<SmsCbLocation> CREATOR
= new Parcelable.Creator<SmsCbLocation>() {
@Override
public SmsCbLocation createFromParcel(Parcel in) {
return new SmsCbLocation(in);
}
@Override
public SmsCbLocation[] newArray(int size) {
return new SmsCbLocation[size];
}
};
/**
* Describe the kinds of special objects contained in the marshalled representation.
* @return a bitmask indicating this Parcelable contains no special objects
*/
@Override
public int describeContents() {
return 0;
}
}
/*
* Copyright (C) 2010 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 android.telephony;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Parcelable object containing a received cell broadcast message. There are four different types
* of Cell Broadcast messages:
*
* <ul>
* <li>opt-in informational broadcasts, e.g. news, weather, stock quotes, sports scores</li>
* <li>cell information messages, broadcast on channel 50, indicating the current cell name for
* roaming purposes (required to display on the idle screen in Brazil)</li>
* <li>emergency broadcasts for the Japanese Earthquake and Tsunami Warning System (ETWS)</li>
* <li>emergency broadcasts for the American Commercial Mobile Alert Service (CMAS)</li>
* </ul>
*
* <p>There are also four different CB message formats: GSM, ETWS Primary Notification (GSM only),
* UMTS, and CDMA. Some fields are only applicable for some message formats. Other fields were
* unified under a common name, avoiding some names, such as "Message Identifier", that refer to
* two completely different concepts in 3GPP and CDMA.
*
* <p>The GSM/UMTS Message Identifier field is available via {@link #getServiceCategory}, the name
* of the equivalent field in CDMA. In both cases the service category is a 16-bit value, but 3GPP
* and 3GPP2 have completely different meanings for the respective values. For ETWS and CMAS, the
* application should
*
* <p>The CDMA Message Identifier field is available via {@link #getSerialNumber}, which is used
* to detect the receipt of a duplicate message to be discarded. In CDMA, the message ID is
* unique to the current PLMN. In GSM/UMTS, there is a 16-bit serial number containing a 2-bit
* Geographical Scope field which indicates whether the 10-bit message code and 4-bit update number
* are considered unique to the PLMN, to the current cell, or to the current Location Area (or
* Service Area in UMTS). The relevant values are concatenated into a single String which will be
* unique if the messages are not duplicates.
*
* <p>The SMS dispatcher does not detect duplicate messages. However, it does concatenate the
* pages of a GSM multi-page cell broadcast into a single SmsCbMessage object.
*
* <p>Interested applications with {@code RECEIVE_SMS_PERMISSION} can register to receive
* {@code SMS_CB_RECEIVED_ACTION} broadcast intents for incoming non-emergency broadcasts.
* Only system applications such as the CellBroadcastReceiver may receive notifications for
* emergency broadcasts (ETWS and CMAS). This is intended to prevent any potential for delays or
* interference with the immediate display of the alert message and playing of the alert sound and
* vibration pattern, which could be caused by poorly written or malicious non-system code.
*
* @hide
*/
public class SmsCbMessage implements Parcelable {
protected static final String LOG_TAG = "SMSCB";
/** Cell wide geographical scope with immediate display (GSM/UMTS only). */
public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0;
/** PLMN wide geographical scope (GSM/UMTS and all CDMA broadcasts). */
public static final int GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1;
/** Location / service area wide geographical scope (GSM/UMTS only). */
public static final int GEOGRAPHICAL_SCOPE_LA_WIDE = 2;
/** Cell wide geographical scope (GSM/UMTS only). */
public static final int GEOGRAPHICAL_SCOPE_CELL_WIDE = 3;
/** GSM or UMTS format cell broadcast. */
public static final int MESSAGE_FORMAT_3GPP = 1;
/** CDMA format cell broadcast. */
public static final int MESSAGE_FORMAT_3GPP2 = 2;
/** Normal message priority. */
public static final int MESSAGE_PRIORITY_NORMAL = 0;
/** Interactive message priority. */
public static final int MESSAGE_PRIORITY_INTERACTIVE = 1;
/** Urgent message priority. */
public static final int MESSAGE_PRIORITY_URGENT = 2;
/** Emergency message priority. */
public static final int MESSAGE_PRIORITY_EMERGENCY = 3;
/** Format of this message (for interpretation of service category values). */
private final int mMessageFormat;
/** Geographical scope of broadcast. */
private final int mGeographicalScope;
/**
* Serial number of broadcast (message identifier for CDMA, geographical scope + message code +
* update number for GSM/UMTS). The serial number plus the location code uniquely identify
* a cell broadcast for duplicate detection.
*/
private final int mSerialNumber;
/**
* Location identifier for this message. It consists of the current operator MCC/MNC as a
* 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
* message is not binary 01, the Location Area is included for comparison. If the GS is
* 00 or 11, the Cell ID is also included. LAC and Cell ID are -1 if not specified.
*/
private final SmsCbLocation mLocation;
/**
* 16-bit CDMA service category or GSM/UMTS message identifier. For ETWS and CMAS warnings,
* the information provided by the category is also available via {@link #getEtwsWarningInfo()}
* or {@link #getCmasWarningInfo()}.
*/
private final int mServiceCategory;
/** Message language, as a two-character string, e.g. "en". */
private final String mLanguage;
/** Message body, as a String. */
private final String mBody;
/** Message priority (including emergency priority). */
private final int mPriority;
/** ETWS warning notification information (ETWS warnings only). */
private final SmsCbEtwsInfo mEtwsWarningInfo;
/** CMAS warning notification information (CMAS warnings only). */
private final SmsCbCmasInfo mCmasWarningInfo;
/**
* Create a new SmsCbMessage with the specified data.
*/
public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
SmsCbLocation location, int serviceCategory, String language, String body,
int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) {
mMessageFormat = messageFormat;
mGeographicalScope = geographicalScope;
mSerialNumber = serialNumber;
mLocation = location;
mServiceCategory = serviceCategory;
mLanguage = language;
mBody = body;
mPriority = priority;
mEtwsWarningInfo = etwsWarningInfo;
mCmasWarningInfo = cmasWarningInfo;
}
/** Create a new SmsCbMessage object from a Parcel. */
public SmsCbMessage(Parcel in) {
mMessageFormat = in.readInt();
mGeographicalScope = in.readInt();
mSerialNumber = in.readInt();
mLocation = new SmsCbLocation(in);
mServiceCategory = in.readInt();
mLanguage = in.readString();
mBody = in.readString();
mPriority = in.readInt();
int type = in.readInt();
switch (type) {
case 'E':
// unparcel ETWS warning information
mEtwsWarningInfo = new SmsCbEtwsInfo(in);
mCmasWarningInfo = null;
break;
case 'C':
// unparcel CMAS warning information
mEtwsWarningInfo = null;
mCmasWarningInfo = new SmsCbCmasInfo(in);
break;
default:
mEtwsWarningInfo = null;
mCmasWarningInfo = null;
}
}
/**
* Flatten this object into a Parcel.
*
* @param dest The Parcel in which the object should be written.
* @param flags Additional flags about how the object should be written (ignored).
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mMessageFormat);
dest.writeInt(mGeographicalScope);
dest.writeInt(mSerialNumber);
mLocation.writeToParcel(dest, flags);
dest.writeInt(mServiceCategory);
dest.writeString(mLanguage);
dest.writeString(mBody);
dest.writeInt(mPriority);
if (mEtwsWarningInfo != null) {
// parcel ETWS warning information
dest.writeInt('E');
mEtwsWarningInfo.writeToParcel(dest, flags);
} else if (mCmasWarningInfo != null) {
// parcel CMAS warning information
dest.writeInt('C');
mCmasWarningInfo.writeToParcel(dest, flags);
} else {
// no ETWS or CMAS warning information
dest.writeInt('0');
}
}
public static final Parcelable.Creator<SmsCbMessage> CREATOR
= new Parcelable.Creator<SmsCbMessage>() {
@Override
public SmsCbMessage createFromParcel(Parcel in) {
return new SmsCbMessage(in);
}
@Override
public SmsCbMessage[] newArray(int size) {
return new SmsCbMessage[size];
}
};
/**
* Return the geographical scope of this message (GSM/UMTS only).
*
* @return Geographical scope
*/
public int getGeographicalScope() {
return mGeographicalScope;
}
/**
* Return the broadcast serial number of broadcast (message identifier for CDMA, or
* geographical scope + message code + update number for GSM/UMTS). The serial number plus
* the location code uniquely identify a cell broadcast for duplicate detection.
*
* @return the 16-bit CDMA message identifier or GSM/UMTS serial number
*/
public int getSerialNumber() {
return mSerialNumber;
}
/**
* Return the location identifier for this message, consisting of the MCC/MNC as a
* 5 or 6-digit decimal string. In addition, for GSM/UMTS, if the Geographical Scope of the
* message is not binary 01, the Location Area is included. If the GS is 00 or 11, the
* cell ID is also included. The {@link SmsCbLocation} object includes a method to test
* if the location is included within another location area or within a PLMN and CellLocation.
*
* @return the geographical location code for duplicate message detection
*/
public SmsCbLocation getLocation() {
return mLocation;
}
/**
* Return the 16-bit CDMA service category or GSM/UMTS message identifier. The interpretation
* of the category is radio technology specific. For ETWS and CMAS warnings, the information
* provided by the category is available via {@link #getEtwsWarningInfo()} or
* {@link #getCmasWarningInfo()} in a radio technology independent format.
*
* @return the radio technology specific service category
*/
public int getServiceCategory() {
return mServiceCategory;
}
/**
* Get the ISO-639-1 language code for this message, or null if unspecified
*
* @return Language code
*/
public String getLanguageCode() {
return mLanguage;
}
/**
* Get the body of this message, or null if no body available
*
* @return Body, or null
*/
public String getMessageBody() {
return mBody;
}
/**
* Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
* @return an integer representing 3GPP or 3GPP2 message format
*/
public int getMessageFormat() {
return mMessageFormat;
}
/**
* Get the message priority. Normal broadcasts return {@link #MESSAGE_PRIORITY_NORMAL}
* and emergency broadcasts return {@link #MESSAGE_PRIORITY_EMERGENCY}. CDMA also may return
* {@link #MESSAGE_PRIORITY_INTERACTIVE} or {@link #MESSAGE_PRIORITY_URGENT}.
* @return an integer representing the message priority
*/
public int getMessagePriority() {
return mPriority;
}
/**
* If this is an ETWS warning notification then this method will return an object containing
* the ETWS warning type, the emergency user alert flag, and the popup flag. If this is an
* ETWS primary notification (GSM only), there will also be a 7-byte timestamp and 43-byte
* digital signature. As of Release 10, 3GPP TS 23.041 states that the UE shall ignore the
* ETWS primary notification timestamp and digital signature if received.
*
* @return an SmsCbEtwsInfo object, or null if this is not an ETWS warning notification
*/
public SmsCbEtwsInfo getEtwsWarningInfo() {
return mEtwsWarningInfo;
}
/**
* If this is a CMAS warning notification then this method will return an object containing
* the CMAS message class, category, response type, severity, urgency and certainty.
* The message class is always present. Severity, urgency and certainty are present for CDMA
* warning notifications containing a type 1 elements record and for GSM and UMTS warnings
* except for the Presidential-level alert category. Category and response type are only
* available for CDMA notifications containing a type 1 elements record.
*
* @return an SmsCbCmasInfo object, or null if this is not a CMAS warning notification
*/
public SmsCbCmasInfo getCmasWarningInfo() {
return mCmasWarningInfo;
}
/**
* Return whether this message is an emergency (PWS) message type.
* @return true if the message is a public warning notification; false otherwise
*/
public boolean isEmergencyMessage() {
return mPriority == MESSAGE_PRIORITY_EMERGENCY;
}
/**
* Return whether this message is an ETWS warning alert.
* @return true if the message is an ETWS warning notification; false otherwise
*/
public boolean isEtwsMessage() {
return mEtwsWarningInfo != null;
}
/**
* Return whether this message is a CMAS warning alert.
* @return true if the message is a CMAS warning notification; false otherwise
*/
public boolean isCmasMessage() {
return mCmasWarningInfo != null;
}
@Override
public String toString() {
return "SmsCbMessage{geographicalScope=" + mGeographicalScope + ", serialNumber="
+ mSerialNumber + ", location=" + mLocation + ", serviceCategory="
+ mServiceCategory + ", language=" + mLanguage + ", body=" + mBody
+ ", priority=" + mPriority
+ (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
+ (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}';
}
/**
* Describe the kinds of special objects contained in the marshalled representation.
* @return a bitmask indicating this Parcelable contains no special objects
*/
@Override
public int describeContents() {
return 0;
}
}
This diff is collapsed.
This diff is collapsed.
/*
* 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 android.telephony.gsm;
import android.app.PendingIntent;
import java.util.ArrayList;
/**
* Manages SMS operations such as sending data, text, and pdu SMS messages.
* Get this object by calling the static method SmsManager.getDefault().
* @deprecated Replaced by android.telephony.SmsManager that supports both GSM and CDMA.
*/
@Deprecated public final class SmsManager {
private static SmsManager sInstance;
private android.telephony.SmsManager mSmsMgrProxy;
/** Get the default instance of the SmsManager
*
* @return the default instance of the SmsManager
* @deprecated Use android.telephony.SmsManager.
*/
@Deprecated
public static final SmsManager getDefault() {
if (sInstance == null) {
sInstance = new SmsManager();
}
return sInstance;
}
@Deprecated
private SmsManager() {
mSmsMgrProxy = android.telephony.SmsManager.getDefault();
}
/**
* Send a 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 text the body of the message to send
* @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is successfully 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 applications,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or text are empty
* @deprecated Use android.telephony.SmsManager.
*/
@Deprecated
public final void sendTextMessage(
String destinationAddress, String scAddress, String text,
PendingIntent sentIntent, PendingIntent deliveryIntent) {
mSmsMgrProxy.sendTextMessage(destinationAddress, scAddress, text,
sentIntent, deliveryIntent);
}
/**
* Divide a text message into several messages, none bigger than
* the maximum SMS message size.
*
* @param text the original message. Must not be null.
* @return an <code>ArrayList</code> of strings that, in order,
* comprise the original message
* @deprecated Use android.telephony.SmsManager.
*/
@Deprecated
public final ArrayList<String> divideMessage(String text) {
return mSmsMgrProxy.divideMessage(text);
}
/**
* Send a multi-part text based SMS. The callee should have already
* divided the message into correctly sized parts by calling
* <code>divideMessage</code>.
*
* @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").
*
* @throws IllegalArgumentException if destinationAddress or data are empty
* @deprecated Use android.telephony.SmsManager.
*/
@Deprecated
public final void sendMultipartTextMessage(
String destinationAddress, String scAddress, ArrayList<String> parts,
ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) {
mSmsMgrProxy.sendMultipartTextMessage(destinationAddress, scAddress, parts,
sentIntents, deliveryIntents);
}
/**
* Send a data based SMS to a specific application port.
*
* @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 destinationPort the port to deliver the message to
* @param data the body of the message to send
* @param sentIntent if not NULL this <code>PendingIntent</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>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*
* @throws IllegalArgumentException if destinationAddress or data are empty
* @deprecated Use android.telephony.SmsManager.
*/
@Deprecated
public final void sendDataMessage(
String destinationAddress, String scAddress, short destinationPort,
byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
mSmsMgrProxy.sendDataMessage(destinationAddress, scAddress, destinationPort,
data, sentIntent, deliveryIntent);
}
/**
* Copy a raw SMS PDU to the SIM.
*
* @param smsc the SMSC for this message, or NULL for the default SMSC
* @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 true for success
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
@Deprecated
public final boolean copyMessageToSim(byte[] smsc, byte[] pdu, int status) {
return mSmsMgrProxy.copyMessageToIcc(smsc, pdu, status);
}
/**
* Delete the specified message from the SIM.
*
* @param messageIndex is the record index of the message on SIM
* @return true for success
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
@Deprecated
public final boolean deleteMessageFromSim(int messageIndex) {
return mSmsMgrProxy.deleteMessageFromIcc(messageIndex);
}
/**
* 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 true for success
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
@Deprecated
public final boolean updateMessageOnSim(int messageIndex, int newStatus, byte[] pdu) {
return mSmsMgrProxy.updateMessageOnIcc(messageIndex, newStatus, pdu);
}
/**
* Retrieves all messages currently stored on SIM.
* @return <code>ArrayList</code> of <code>SmsMessage</code> objects
* @deprecated Use android.telephony.SmsManager.
* {@hide}
*/
@Deprecated
public final ArrayList<android.telephony.SmsMessage> getAllMessagesFromSim() {
return mSmsMgrProxy.getAllMessagesFromIcc();
}
/** Free space (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_FREE = 0;
/** Received and read (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_READ = 1;
/** Received and unread (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_UNREAD = 3;
/** Stored and sent (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_SENT = 5;
/** Stored and unsent (TS 51.011 10.5.3).
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int STATUS_ON_SIM_UNSENT = 7;
/** Generic failure cause
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_GENERIC_FAILURE = 1;
/** Failed because radio was explicitly turned off
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_RADIO_OFF = 2;
/** Failed because no pdu provided
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_NULL_PDU = 3;
/** Failed because service is currently unavailable
* @deprecated Use android.telephony.SmsManager. */
@Deprecated static public final int RESULT_ERROR_NO_SERVICE = 4;
}
This diff is collapsed.
/*
* 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);
}
}
/*
* 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");
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment