|  | /* | 
|  | * 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.uicc.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; | 
|  |  | 
|  | /** Whether ETWS primary message or not/ */ | 
|  | private final boolean mPrimary; | 
|  |  | 
|  | /** | 
|  | * 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, | 
|  | boolean primary, byte[] warningSecurityInformation) { | 
|  | mWarningType = warningType; | 
|  | mEmergencyUserAlert = emergencyUserAlert; | 
|  | mActivatePopup = activatePopup; | 
|  | mPrimary = primary; | 
|  | mWarningSecurityInformation = warningSecurityInformation; | 
|  | } | 
|  |  | 
|  | /** Create a new SmsCbEtwsInfo object from a Parcel. */ | 
|  | SmsCbEtwsInfo(Parcel in) { | 
|  | mWarningType = in.readInt(); | 
|  | mEmergencyUserAlert = (in.readInt() != 0); | 
|  | mActivatePopup = (in.readInt() != 0); | 
|  | mPrimary = (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.writeInt(mPrimary ? 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 ETWS format flag. | 
|  | * @return true if the message is primary message, otherwise secondary message | 
|  | */ | 
|  | public boolean isPrimary() { | 
|  | return mPrimary; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * 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) - 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>() { | 
|  | @Override | 
|  | public SmsCbEtwsInfo createFromParcel(Parcel in) { | 
|  | return new SmsCbEtwsInfo(in); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public SmsCbEtwsInfo[] newArray(int size) { | 
|  | return new SmsCbEtwsInfo[size]; | 
|  | } | 
|  | }; | 
|  | } |