1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.telephony; 18 19 import android.os.Parcel; 20 import android.os.Parcelable; 21 import android.text.format.Time; 22 23 import com.android.internal.telephony.uicc.IccUtils; 24 25 import java.util.Arrays; 26 27 /** 28 * Contains information elements for a GSM or UMTS ETWS warning notification. 29 * Supported values for each element are defined in 3GPP TS 23.041. 30 * 31 * {@hide} 32 */ 33 public class SmsCbEtwsInfo implements Parcelable { 34 35 /** ETWS warning type for earthquake. */ 36 public static final int ETWS_WARNING_TYPE_EARTHQUAKE = 0x00; 37 38 /** ETWS warning type for tsunami. */ 39 public static final int ETWS_WARNING_TYPE_TSUNAMI = 0x01; 40 41 /** ETWS warning type for earthquake and tsunami. */ 42 public static final int ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI = 0x02; 43 44 /** ETWS warning type for test messages. */ 45 public static final int ETWS_WARNING_TYPE_TEST_MESSAGE = 0x03; 46 47 /** ETWS warning type for other emergency types. */ 48 public static final int ETWS_WARNING_TYPE_OTHER_EMERGENCY = 0x04; 49 50 /** Unknown ETWS warning type. */ 51 public static final int ETWS_WARNING_TYPE_UNKNOWN = -1; 52 53 /** One of the ETWS warning type constants defined in this class. */ 54 private final int mWarningType; 55 56 /** Whether or not to activate the emergency user alert tone and vibration. */ 57 private final boolean mEmergencyUserAlert; 58 59 /** Whether or not to activate a popup alert. */ 60 private final boolean mActivatePopup; 61 62 /** Whether ETWS primary message or not/ */ 63 private final boolean mPrimary; 64 65 /** 66 * 50-byte security information (ETWS primary notification for GSM only). As of Release 10, 67 * 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp 68 * and digital signature if received. Therefore it is treated as a raw byte array and 69 * parceled with the broadcast intent if present, but the timestamp is only computed if an 70 * application asks for the individual components. 71 */ 72 private final byte[] mWarningSecurityInformation; 73 74 /** Create a new SmsCbEtwsInfo object with the specified values. */ 75 public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup, 76 boolean primary, byte[] warningSecurityInformation) { 77 mWarningType = warningType; 78 mEmergencyUserAlert = emergencyUserAlert; 79 mActivatePopup = activatePopup; 80 mPrimary = primary; 81 mWarningSecurityInformation = warningSecurityInformation; 82 } 83 84 /** Create a new SmsCbEtwsInfo object from a Parcel. */ 85 SmsCbEtwsInfo(Parcel in) { 86 mWarningType = in.readInt(); 87 mEmergencyUserAlert = (in.readInt() != 0); 88 mActivatePopup = (in.readInt() != 0); 89 mPrimary = (in.readInt() != 0); 90 mWarningSecurityInformation = in.createByteArray(); 91 } 92 93 /** 94 * Flatten this object into a Parcel. 95 * 96 * @param dest The Parcel in which the object should be written. 97 * @param flags Additional flags about how the object should be written (ignored). 98 */ 99 @Override 100 public void writeToParcel(Parcel dest, int flags) { 101 dest.writeInt(mWarningType); 102 dest.writeInt(mEmergencyUserAlert ? 1 : 0); 103 dest.writeInt(mActivatePopup ? 1 : 0); 104 dest.writeInt(mPrimary ? 1 : 0); 105 dest.writeByteArray(mWarningSecurityInformation); 106 } 107 108 /** 109 * Returns the ETWS warning type. 110 * @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE} 111 */ 112 public int getWarningType() { 113 return mWarningType; 114 } 115 116 /** 117 * Returns the ETWS emergency user alert flag. 118 * @return true to notify terminal to activate emergency user alert; false otherwise 119 */ 120 public boolean isEmergencyUserAlert() { 121 return mEmergencyUserAlert; 122 } 123 124 /** 125 * Returns the ETWS activate popup flag. 126 * @return true to notify terminal to activate display popup; false otherwise 127 */ 128 public boolean isPopupAlert() { 129 return mActivatePopup; 130 } 131 132 /** 133 * Returns the ETWS format flag. 134 * @return true if the message is primary message, otherwise secondary message 135 */ 136 public boolean isPrimary() { 137 return mPrimary; 138 } 139 140 /** 141 * Returns the Warning-Security-Information timestamp (GSM primary notifications only). 142 * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received. 143 * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present 144 */ 145 public long getPrimaryNotificationTimestamp() { 146 if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) { 147 return 0; 148 } 149 150 int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]); 151 int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]); 152 int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]); 153 int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]); 154 int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]); 155 int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]); 156 157 // For the timezone, the most significant bit of the 158 // least significant nibble is the sign byte 159 // (meaning the max range of this field is 79 quarter-hours, 160 // which is more than enough) 161 162 byte tzByte = mWarningSecurityInformation[6]; 163 164 // Mask out sign bit. 165 int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08))); 166 167 timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset; 168 169 Time time = new Time(Time.TIMEZONE_UTC); 170 171 // We only need to support years above 2000. 172 time.year = year + 2000; 173 time.month = month - 1; 174 time.monthDay = day; 175 time.hour = hour; 176 time.minute = minute; 177 time.second = second; 178 179 // Timezone offset is in quarter hours. 180 return time.toMillis(true) - timezoneOffset * 15 * 60 * 1000; 181 } 182 183 /** 184 * Returns the digital signature (GSM primary notifications only). As of Release 10, 185 * 3GPP TS 23.041 states that the UE shall ignore this value if received. 186 * @return a byte array containing a copy of the primary notification digital signature 187 */ 188 public byte[] getPrimaryNotificationSignature() { 189 if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) { 190 return null; 191 } 192 return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50); 193 } 194 195 @Override 196 public String toString() { 197 return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert=" 198 + mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}'; 199 } 200 201 /** 202 * Describe the kinds of special objects contained in the marshalled representation. 203 * @return a bitmask indicating this Parcelable contains no special objects 204 */ 205 @Override 206 public int describeContents() { 207 return 0; 208 } 209 210 /** Creator for unparcelling objects. */ 211 public static final Creator<SmsCbEtwsInfo> CREATOR = new Creator<SmsCbEtwsInfo>() { 212 @Override 213 public SmsCbEtwsInfo createFromParcel(Parcel in) { 214 return new SmsCbEtwsInfo(in); 215 } 216 217 @Override 218 public SmsCbEtwsInfo[] newArray(int size) { 219 return new SmsCbEtwsInfo[size]; 220 } 221 }; 222 } 223