/* * 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: * *
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. * *
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 * *
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. * *
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. * *
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