Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9bc9b809 authored by Pengquan Meng's avatar Pengquan Meng Committed by Gerrit Code Review
Browse files

Merge "Support WAC decoding in UMTS format"

parents 78658058 c3427c01
Loading
Loading
Loading
Loading
+29 −2
Original line number Diff line number Diff line
@@ -4021,8 +4021,8 @@ public final class Telephony {
        public static final String DEFAULT_SORT_ORDER = DELIVERY_TIME + " DESC";

        /**
         * The Epoch Unix timestamp when the device received the message.
         * <P>Type: INTEGER</P>
         * The timestamp in millisecond of when the device received the message.
         * <P>Type: BIGINT</P>
         */
        public static final String RECEIVED_TIME = "received_time";

@@ -4092,6 +4092,33 @@ public final class Telephony {
                CMAS_URGENCY,
                CMAS_CERTAINTY
        };

        /**
         * Query columns for instantiating {@link android.telephony.SmsCbMessage} objects.
         */
        public static final String[] QUERY_COLUMNS_FWK = {
                _ID,
                GEOGRAPHICAL_SCOPE,
                PLMN,
                LAC,
                CID,
                SERIAL_NUMBER,
                SERVICE_CATEGORY,
                LANGUAGE_CODE,
                MESSAGE_BODY,
                MESSAGE_FORMAT,
                MESSAGE_PRIORITY,
                ETWS_WARNING_TYPE,
                CMAS_MESSAGE_CLASS,
                CMAS_CATEGORY,
                CMAS_RESPONSE_TYPE,
                CMAS_SEVERITY,
                CMAS_URGENCY,
                CMAS_CERTAINTY,
                RECEIVED_TIME,
                MESSAGE_BROADCASTED,
                GEOMETRIES
        };
    }

    /**
+10 −0
Original line number Diff line number Diff line
@@ -53,6 +53,11 @@ public class CbGeoUtils {

    private static final String TAG = "CbGeoUtils";

    /** The TLV tags of WAC, defined in ATIS-0700041 5.2.3 WAC tag coding. */
    public static final int GEO_FENCING_MAXIMUM_WAIT_TIME = 0x01;
    public static final int GEOMETRY_TYPE_POLYGON = 0x02;
    public static final int GEOMETRY_TYPE_CIRCLE = 0x03;

    /** The identifier of geometry in the encoded string. */
    private static final String CIRCLE_SYMBOL = "circle";
    private static final String POLYGON_SYMBOL = "polygon";
@@ -92,6 +97,11 @@ public class CbGeoUtils {
                    + dlng * dlng * Math.cos(Math.toRadians(lat)) * Math.cos(Math.toRadians(p.lat));
            return 2 * Math.atan2(Math.sqrt(x), Math.sqrt(1 - x)) * EARTH_RADIUS_METER;
        }

        @Override
        public String toString() {
            return "(" + lat + "," + lng + ")";
        }
    }

    /**
+225 −1
Original line number Diff line number Diff line
@@ -16,8 +16,17 @@

package android.telephony;

import android.annotation.Nullable;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.Telephony.CellBroadcasts;

import com.android.internal.telephony.CbGeoUtils;
import com.android.internal.telephony.CbGeoUtils.Geometry;

import java.util.List;

/**
 * Parcelable object containing a received cell broadcast message. There are four different types
@@ -138,12 +147,31 @@ public class SmsCbMessage implements Parcelable {
    /** CMAS warning notification information (CMAS warnings only). */
    private final SmsCbCmasInfo mCmasWarningInfo;

    /** UNIX timestamp of when the message was received. */
    private final long mReceivedTimeMillis;

    /** CMAS warning area coordinates. */
    private final List<Geometry> mGeometries;

    /**
     * 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) {

        this(messageFormat, geographicalScope, serialNumber, location, serviceCategory, language,
                body, priority, etwsWarningInfo, cmasWarningInfo, null /* geometries */,
                System.currentTimeMillis());
    }

    /**
     * Create a new {@link SmsCbMessage} with the warning area coordinates information.
     */
    public SmsCbMessage(int messageFormat, int geographicalScope, int serialNumber,
            SmsCbLocation location, int serviceCategory, String language, String body,
            int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo,
            List<Geometry> geometries, long receivedTimeMillis) {
        mMessageFormat = messageFormat;
        mGeographicalScope = geographicalScope;
        mSerialNumber = serialNumber;
@@ -154,6 +182,8 @@ public class SmsCbMessage implements Parcelable {
        mPriority = priority;
        mEtwsWarningInfo = etwsWarningInfo;
        mCmasWarningInfo = cmasWarningInfo;
        mReceivedTimeMillis = receivedTimeMillis;
        mGeometries = geometries;
    }

    /** Create a new SmsCbMessage object from a Parcel. */
@@ -184,6 +214,9 @@ public class SmsCbMessage implements Parcelable {
                mEtwsWarningInfo = null;
                mCmasWarningInfo = null;
        }
        mReceivedTimeMillis = in.readLong();
        String geoStr = in.readString();
        mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
    }

    /**
@@ -214,6 +247,9 @@ public class SmsCbMessage implements Parcelable {
            // no ETWS or CMAS warning information
            dest.writeInt('0');
        }
        dest.writeLong(mReceivedTimeMillis);
        dest.writeString(
                mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null);
    }

    public static final Parcelable.Creator<SmsCbMessage> CREATOR
@@ -292,6 +328,24 @@ public class SmsCbMessage implements Parcelable {
        return mBody;
    }

    /**
     * Get the warning area coordinates information represent by polygons and circles.
     * @return a list of geometries, {@link Nullable} means there is no coordinate information
     * associated to this message.
     */
    @Nullable
    public List<Geometry> getGeometries() {
        return mGeometries;
    }

    /**
     * Get the time when this message was received.
     * @return the time in millisecond
     */
    public long getReceivedTime() {
        return mReceivedTimeMillis;
    }

    /**
     * Get the message format ({@link #MESSAGE_FORMAT_3GPP} or {@link #MESSAGE_FORMAT_3GPP2}).
     * @return an integer representing 3GPP or 3GPP2 message format
@@ -368,7 +422,10 @@ public class SmsCbMessage implements Parcelable {
                + mServiceCategory + ", language=" + mLanguage + ", body=" + mBody
                + ", priority=" + mPriority
                + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
                + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "") + '}';
                + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "")
                + ", geo=" + (mGeometries != null
                ? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null")
                + '}';
    }

    /**
@@ -379,4 +436,171 @@ public class SmsCbMessage implements Parcelable {
    public int describeContents() {
        return 0;
    }

    /**
     * @return the {@link ContentValues} instance that includes the cell broadcast data.
     */
    public ContentValues getContentValues() {
        ContentValues cv = new ContentValues(16);
        cv.put(CellBroadcasts.GEOGRAPHICAL_SCOPE, mGeographicalScope);
        if (mLocation.getPlmn() != null) {
            cv.put(CellBroadcasts.PLMN, mLocation.getPlmn());
        }
        if (mLocation.getLac() != -1) {
            cv.put(CellBroadcasts.LAC, mLocation.getLac());
        }
        if (mLocation.getCid() != -1) {
            cv.put(CellBroadcasts.CID, mLocation.getCid());
        }
        cv.put(CellBroadcasts.SERIAL_NUMBER, getSerialNumber());
        cv.put(CellBroadcasts.SERVICE_CATEGORY, getServiceCategory());
        cv.put(CellBroadcasts.LANGUAGE_CODE, getLanguageCode());
        cv.put(CellBroadcasts.MESSAGE_BODY, getMessageBody());
        cv.put(CellBroadcasts.MESSAGE_FORMAT, getMessageFormat());
        cv.put(CellBroadcasts.MESSAGE_PRIORITY, getMessagePriority());

        SmsCbEtwsInfo etwsInfo = getEtwsWarningInfo();
        if (etwsInfo != null) {
            cv.put(CellBroadcasts.ETWS_WARNING_TYPE, etwsInfo.getWarningType());
        }

        SmsCbCmasInfo cmasInfo = getCmasWarningInfo();
        if (cmasInfo != null) {
            cv.put(CellBroadcasts.CMAS_MESSAGE_CLASS, cmasInfo.getMessageClass());
            cv.put(CellBroadcasts.CMAS_CATEGORY, cmasInfo.getCategory());
            cv.put(CellBroadcasts.CMAS_RESPONSE_TYPE, cmasInfo.getResponseType());
            cv.put(CellBroadcasts.CMAS_SEVERITY, cmasInfo.getSeverity());
            cv.put(CellBroadcasts.CMAS_URGENCY, cmasInfo.getUrgency());
            cv.put(CellBroadcasts.CMAS_CERTAINTY, cmasInfo.getCertainty());
        }

        cv.put(CellBroadcasts.RECEIVED_TIME, mReceivedTimeMillis);

        if (mGeometries != null) {
            cv.put(CellBroadcasts.GEOMETRIES, CbGeoUtils.encodeGeometriesToString(mGeometries));
        } else {
            cv.put(CellBroadcasts.GEOMETRIES, (String) null);
        }

        return cv;
    }

    /**
     * Create a {@link SmsCbMessage} instance from a row in the cell broadcast database.
     * @param cursor an open SQLite cursor pointing to the row to read
     * @return a {@link SmsCbMessage} instance.
     * @throws IllegalArgumentException if one of the required columns is missing
     */
    public static SmsCbMessage createFromCursor(Cursor cursor) {
        int geoScope = cursor.getInt(
                cursor.getColumnIndexOrThrow(CellBroadcasts.GEOGRAPHICAL_SCOPE));
        int serialNum = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERIAL_NUMBER));
        int category = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.SERVICE_CATEGORY));
        String language = cursor.getString(
                cursor.getColumnIndexOrThrow(CellBroadcasts.LANGUAGE_CODE));
        String body = cursor.getString(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_BODY));
        int format = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_FORMAT));
        int priority = cursor.getInt(cursor.getColumnIndexOrThrow(CellBroadcasts.MESSAGE_PRIORITY));

        String plmn;
        int plmnColumn = cursor.getColumnIndex(CellBroadcasts.PLMN);
        if (plmnColumn != -1 && !cursor.isNull(plmnColumn)) {
            plmn = cursor.getString(plmnColumn);
        } else {
            plmn = null;
        }

        int lac;
        int lacColumn = cursor.getColumnIndex(CellBroadcasts.LAC);
        if (lacColumn != -1 && !cursor.isNull(lacColumn)) {
            lac = cursor.getInt(lacColumn);
        } else {
            lac = -1;
        }

        int cid;
        int cidColumn = cursor.getColumnIndex(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(CellBroadcasts.ETWS_WARNING_TYPE);
        if (etwsWarningTypeColumn != -1 && !cursor.isNull(etwsWarningTypeColumn)) {
            int warningType = cursor.getInt(etwsWarningTypeColumn);
            etwsInfo = new SmsCbEtwsInfo(warningType, false, false, false, null);
        } else {
            etwsInfo = null;
        }

        SmsCbCmasInfo cmasInfo = null;
        int cmasMessageClassColumn = cursor.getColumnIndex(CellBroadcasts.CMAS_MESSAGE_CLASS);
        if (cmasMessageClassColumn != -1 && !cursor.isNull(cmasMessageClassColumn)) {
            int messageClass = cursor.getInt(cmasMessageClassColumn);

            int cmasCategory;
            int cmasCategoryColumn = cursor.getColumnIndex(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(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(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(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(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);
        }

        String geoStr = cursor.getString(cursor.getColumnIndex(CellBroadcasts.GEOMETRIES));
        List<Geometry> geometries =
                geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;

        long receivedTimeSec = cursor.getLong(
                cursor.getColumnIndexOrThrow(CellBroadcasts.RECEIVED_TIME));

        return new SmsCbMessage(format, geoScope, serialNum, location, category,
                language, body, priority, etwsInfo, cmasInfo, geometries, receivedTimeSec);
    }

    /**
     * @return {@code True} if this message needs geo-fencing check.
     */
    public boolean needGeoFencingCheck() {
        return mGeometries != null;
    }
}
+307 −155

File changed.

Preview size limit exceeded, changes collapsed.

+5 −3
Original line number Diff line number Diff line
@@ -215,9 +215,11 @@ public class SmsCbConstants {
    public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST_LANGUAGE
            = 0x112F; // 4399

    /** End of CMAS Message Identifier range (including future extensions). */
    public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER
            = 0x112F; // 4399
    /** CMAS Message Identifier for CMAS geo fencing trigger message. */
    public static final int MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER = 0x1130; // 4440

    /** End of CMAS Message Identifier range. */
    public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER = MESSAGE_ID_CMAS_GEO_FENCING_TRIGGER;

    /** End of PWS Message Identifier range (includes ETWS, CMAS, and future extensions). */
    public static final int MESSAGE_ID_PWS_LAST_IDENTIFIER
Loading