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 /** 63 * 50-byte security information (ETWS primary notification for GSM only). As of Release 10, 64 * 3GPP TS 23.041 states that the UE shall ignore the ETWS primary notification timestamp 65 * and digital signature if received. Therefore it is treated as a raw byte array and 66 * parceled with the broadcast intent if present, but the timestamp is only computed if an 67 * application asks for the individual components. 68 */ 69 private final byte[] mWarningSecurityInformation; 70 71 /** Create a new SmsCbEtwsInfo object with the specified values. */ 72 public SmsCbEtwsInfo(int warningType, boolean emergencyUserAlert, boolean activatePopup, 73 byte[] warningSecurityInformation) { 74 mWarningType = warningType; 75 mEmergencyUserAlert = emergencyUserAlert; 76 mActivatePopup = activatePopup; 77 mWarningSecurityInformation = warningSecurityInformation; 78 } 79 80 /** Create a new SmsCbEtwsInfo object from a Parcel. */ 81 SmsCbEtwsInfo(Parcel in) { 82 mWarningType = in.readInt(); 83 mEmergencyUserAlert = (in.readInt() != 0); 84 mActivatePopup = (in.readInt() != 0); 85 mWarningSecurityInformation = in.createByteArray(); 86 } 87 88 /** 89 * Flatten this object into a Parcel. 90 * 91 * @param dest The Parcel in which the object should be written. 92 * @param flags Additional flags about how the object should be written (ignored). 93 */ 94 @Override 95 public void writeToParcel(Parcel dest, int flags) { 96 dest.writeInt(mWarningType); 97 dest.writeInt(mEmergencyUserAlert ? 1 : 0); 98 dest.writeInt(mActivatePopup ? 1 : 0); 99 dest.writeByteArray(mWarningSecurityInformation); 100 } 101 102 /** 103 * Returns the ETWS warning type. 104 * @return a warning type such as {@link #ETWS_WARNING_TYPE_EARTHQUAKE} 105 */ 106 public int getWarningType() { 107 return mWarningType; 108 } 109 110 /** 111 * Returns the ETWS emergency user alert flag. 112 * @return true to notify terminal to activate emergency user alert; false otherwise 113 */ 114 public boolean isEmergencyUserAlert() { 115 return mEmergencyUserAlert; 116 } 117 118 /** 119 * Returns the ETWS activate popup flag. 120 * @return true to notify terminal to activate display popup; false otherwise 121 */ 122 public boolean isPopupAlert() { 123 return mActivatePopup; 124 } 125 126 /** 127 * Returns the Warning-Security-Information timestamp (GSM primary notifications only). 128 * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received. 129 * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present 130 */ 131 public long getPrimaryNotificationTimestamp() { 132 if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) { 133 return 0; 134 } 135 136 int year = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[0]); 137 int month = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[1]); 138 int day = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[2]); 139 int hour = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[3]); 140 int minute = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[4]); 141 int second = IccUtils.gsmBcdByteToInt(mWarningSecurityInformation[5]); 142 143 // For the timezone, the most significant bit of the 144 // least significant nibble is the sign byte 145 // (meaning the max range of this field is 79 quarter-hours, 146 // which is more than enough) 147 148 byte tzByte = mWarningSecurityInformation[6]; 149 150 // Mask out sign bit. 151 int timezoneOffset = IccUtils.gsmBcdByteToInt((byte) (tzByte & (~0x08))); 152 153 timezoneOffset = ((tzByte & 0x08) == 0) ? timezoneOffset : -timezoneOffset; 154 155 Time time = new Time(Time.TIMEZONE_UTC); 156 157 // We only need to support years above 2000. 158 time.year = year + 2000; 159 time.month = month - 1; 160 time.monthDay = day; 161 time.hour = hour; 162 time.minute = minute; 163 time.second = second; 164 165 // Timezone offset is in quarter hours. 166 return time.toMillis(true) - timezoneOffset * 15 * 60 * 1000; 167 } 168 169 /** 170 * Returns the digital signature (GSM primary notifications only). As of Release 10, 171 * 3GPP TS 23.041 states that the UE shall ignore this value if received. 172 * @return a byte array containing a copy of the primary notification digital signature 173 */ 174 public byte[] getPrimaryNotificationSignature() { 175 if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 50) { 176 return null; 177 } 178 return Arrays.copyOfRange(mWarningSecurityInformation, 7, 50); 179 } 180 181 @Override 182 public String toString() { 183 return "SmsCbEtwsInfo{warningType=" + mWarningType + ", emergencyUserAlert=" 184 + mEmergencyUserAlert + ", activatePopup=" + mActivatePopup + '}'; 185 } 186 187 /** 188 * Describe the kinds of special objects contained in the marshalled representation. 189 * @return a bitmask indicating this Parcelable contains no special objects 190 */ 191 @Override 192 public int describeContents() { 193 return 0; 194 } 195 196 /** Creator for unparcelling objects. */ 197 public static final Creator<SmsCbEtwsInfo> CREATOR = new Creator<SmsCbEtwsInfo>() { 198 @Override 199 public SmsCbEtwsInfo createFromParcel(Parcel in) { 200 return new SmsCbEtwsInfo(in); 201 } 202 203 @Override 204 public SmsCbEtwsInfo[] newArray(int size) { 205 return new SmsCbEtwsInfo[size]; 206 } 207 }; 208 } 209