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

Commit b47d6c11 authored by Pengquan Meng's avatar Pengquan Meng Committed by android-build-merger
Browse files

Merge "Support maximum wait time for Cell broadcast" into qt-qpr1-dev

am: c12bf8a9

Change-Id: I2eba4c63b8060f32e7ff4c6d8fdca7e1de757e14
parents 30b667da c12bf8a9
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -3916,6 +3916,12 @@ public final class Telephony {
         */
        public static final Uri CONTENT_URI = Uri.parse("content://cellbroadcasts");

        /**
         * The id of the subscription which received this cell broadcast message.
         * <P>Type: INTEGER</P>
         */
        public static final String SUB_ID = "sub_id";

        /**
         * Message geographical scope.
         * <P>Type: INTEGER</P>
@@ -4095,6 +4101,17 @@ public final class Telephony {
         */
        public static final String GEOMETRIES = "geometries";

        /**
         * Geo-Fencing Maximum Wait Time in second. The range of the time is [0, 255]. A device
         * shall allow to determine its position meeting operator policy. If the device is unable to
         * determine its position meeting operator policy within the GeoFencing Maximum Wait Time,
         * it shall present the alert to the user and discontinue further positioning determination
         * for the alert.
         *
         * <P>Type: INTEGER</P>
         */
        public static final String MAXIMUM_WAIT_TIME = "maximum_wait_time";

        /**
         * Query columns for instantiating {@link android.telephony.CellBroadcastMessage} objects.
         */
@@ -4145,7 +4162,8 @@ public final class Telephony {
                CMAS_CERTAINTY,
                RECEIVED_TIME,
                MESSAGE_BROADCASTED,
                GEOMETRIES
                GEOMETRIES,
                MAXIMUM_WAIT_TIME
        };
    }

+2 −1
Original line number Diff line number Diff line
@@ -299,7 +299,8 @@ public class CbGeoUtils {
     * @return the encoded string.
     */
    @NonNull
    public static String encodeGeometriesToString(@NonNull List<Geometry> geometries) {
    public static String encodeGeometriesToString(List<Geometry> geometries) {
        if (geometries == null || geometries.isEmpty()) return "";
        return geometries.stream()
                .map(geometry -> encodeGeometryToString(geometry))
                .filter(encodedStr -> !TextUtils.isEmpty(encodedStr))
+35 −6
Original line number Diff line number Diff line
@@ -104,6 +104,9 @@ public class SmsCbMessage implements Parcelable {
    /** Emergency message priority. */
    public static final int MESSAGE_PRIORITY_EMERGENCY = 3;

    /** ATIS-0700041 Section 5.2.8 WAC Geo-Fencing Maximum Wait Time Table 12. */
    public static final int MAXIMUM_WAIT_TIME_NOT_SET = 255;

    /** Format of this message (for interpretation of service category values). */
    private final int mMessageFormat;

@@ -147,6 +150,14 @@ public class SmsCbMessage implements Parcelable {
    /** CMAS warning notification information (CMAS warnings only). */
    private final SmsCbCmasInfo mCmasWarningInfo;

    /**
     * Geo-Fencing Maximum Wait Time in second, a device shall allow to determine its position
     * meeting operator policy. If the device is unable to determine its position meeting operator
     * policy within the GeoFencing Maximum Wait Time, it shall present the alert to the user and
     * discontinue further positioning determination for the alert.
     */
    private final int mMaximumWaitTimeSec;

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

@@ -161,8 +172,8 @@ public class SmsCbMessage implements Parcelable {
            int priority, SmsCbEtwsInfo etwsWarningInfo, SmsCbCmasInfo cmasWarningInfo) {

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

    /**
@@ -171,7 +182,7 @@ public class SmsCbMessage implements Parcelable {
    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) {
            int maximumWaitTimeSec, List<Geometry> geometries, long receivedTimeMillis) {
        mMessageFormat = messageFormat;
        mGeographicalScope = geographicalScope;
        mSerialNumber = serialNumber;
@@ -184,6 +195,7 @@ public class SmsCbMessage implements Parcelable {
        mCmasWarningInfo = cmasWarningInfo;
        mReceivedTimeMillis = receivedTimeMillis;
        mGeometries = geometries;
        mMaximumWaitTimeSec = maximumWaitTimeSec;
    }

    /** Create a new SmsCbMessage object from a Parcel. */
@@ -217,6 +229,7 @@ public class SmsCbMessage implements Parcelable {
        mReceivedTimeMillis = in.readLong();
        String geoStr = in.readString();
        mGeometries = geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;
        mMaximumWaitTimeSec = in.readInt();
    }

    /**
@@ -250,6 +263,7 @@ public class SmsCbMessage implements Parcelable {
        dest.writeLong(mReceivedTimeMillis);
        dest.writeString(
                mGeometries != null ? CbGeoUtils.encodeGeometriesToString(mGeometries) : null);
        dest.writeInt(mMaximumWaitTimeSec);
    }

    public static final Parcelable.Creator<SmsCbMessage> CREATOR
@@ -338,6 +352,14 @@ public class SmsCbMessage implements Parcelable {
        return mGeometries;
    }

    /**
     * Get the Geo-Fencing Maximum Wait Time.
     * @return the time in second.
     */
    public int getMaximumWaitingTime() {
        return mMaximumWaitTimeSec;
    }

    /**
     * Get the time when this message was received.
     * @return the time in millisecond
@@ -423,6 +445,7 @@ public class SmsCbMessage implements Parcelable {
                + ", priority=" + mPriority
                + (mEtwsWarningInfo != null ? (", " + mEtwsWarningInfo.toString()) : "")
                + (mCmasWarningInfo != null ? (", " + mCmasWarningInfo.toString()) : "")
                + ", maximumWaitingTime = " + mMaximumWaitTimeSec
                + ", geo=" + (mGeometries != null
                ? CbGeoUtils.encodeGeometriesToString(mGeometries) : "null")
                + '}';
@@ -482,6 +505,8 @@ public class SmsCbMessage implements Parcelable {
            cv.put(CellBroadcasts.GEOMETRIES, (String) null);
        }

        cv.put(CellBroadcasts.MAXIMUM_WAIT_TIME, mMaximumWaitTimeSec);

        return cv;
    }

@@ -590,17 +615,21 @@ public class SmsCbMessage implements Parcelable {
        List<Geometry> geometries =
                geoStr != null ? CbGeoUtils.parseGeometriesFromString(geoStr) : null;

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

        int maximumWaitTimeSec = cursor.getInt(
                cursor.getColumnIndexOrThrow(CellBroadcasts.MAXIMUM_WAIT_TIME));

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

    /**
     * @return {@code True} if this message needs geo-fencing check.
     */
    public boolean needGeoFencingCheck() {
        return mGeometries != null;
        return mMaximumWaitTimeSec > 0 && mGeometries != null;
    }
}
+24 −8
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ public class GsmSmsCbMessage {
                    header.getSerialNumber(), location, header.getServiceCategory(), null,
                    getEtwsPrimaryMessage(context, header.getEtwsInfo().getWarningType()),
                    SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY, header.getEtwsInfo(),
                    header.getCmasInfo(), null /* geometries */, receivedTimeMillis);
                    header.getCmasInfo(), 0, null /* geometries */, receivedTimeMillis);
        } else if (header.isUmtsFormat()) {
            // UMTS format has only 1 PDU
            byte[] pdu = pdus[0];
@@ -120,9 +120,13 @@ public class GsmSmsCbMessage {

            // Has Warning Area Coordinates information
            List<Geometry> geometries = null;
            int maximumWaitingTimeSec = 255;
            if (pdu.length > wacDataOffset) {
                try {
                    geometries = parseWarningAreaCoordinates(pdu, wacDataOffset);
                    Pair<Integer, List<Geometry>> wac = parseWarningAreaCoordinates(pdu,
                            wacDataOffset);
                    maximumWaitingTimeSec = wac.first;
                    geometries = wac.second;
                } catch (Exception ex) {
                    // Catch the exception here, the message will be considered as having no WAC
                    // information which means the message will be broadcasted directly.
@@ -133,7 +137,8 @@ public class GsmSmsCbMessage {
            return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
                    header.getGeographicalScope(), header.getSerialNumber(), location,
                    header.getServiceCategory(), language, body, priority,
                    header.getEtwsInfo(), header.getCmasInfo(), geometries, receivedTimeMillis);
                    header.getEtwsInfo(), header.getCmasInfo(), maximumWaitingTimeSec, geometries,
                    receivedTimeMillis);
        } else {
            String language = null;
            StringBuilder sb = new StringBuilder();
@@ -148,7 +153,7 @@ public class GsmSmsCbMessage {
            return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP,
                    header.getGeographicalScope(), header.getSerialNumber(), location,
                    header.getServiceCategory(), language, sb.toString(), priority,
                    header.getEtwsInfo(), header.getCmasInfo(), null /* geometries */,
                    header.getEtwsInfo(), header.getCmasInfo(), 0, null /* geometries */,
                    receivedTimeMillis);
        }
    }
@@ -197,7 +202,17 @@ public class GsmSmsCbMessage {
        }
    }

    private static List<Geometry> parseWarningAreaCoordinates(byte[] pdu, int wacOffset) {
    /**
     * Parse the broadcast area and maximum wait time from the Warning Area Coordinates TLV.
     *
     * @param pdu Warning Area Coordinates TLV.
     * @param wacOffset the offset of Warning Area Coordinates TLV.
     * @return a pair with the first element is maximum wait time and the second is the broadcast
     * area. The default value of the maximum wait time is 255 which means use the device default
     * value.
     */
    private static Pair<Integer, List<Geometry>> parseWarningAreaCoordinates(
            byte[] pdu, int wacOffset) {
        // little-endian
        int wacDataLength = (pdu[wacOffset + 1] << 8) | pdu[wacOffset];
        int offset = wacOffset + 2;
@@ -209,6 +224,8 @@ public class GsmSmsCbMessage {

        BitStreamReader bitReader = new BitStreamReader(pdu, offset);

        int maximumWaitTimeSec = SmsCbMessage.MAXIMUM_WAIT_TIME_NOT_SET;

        List<Geometry> geo = new ArrayList<>();
        int remainedBytes = wacDataLength;
        while (remainedBytes > 0) {
@@ -220,8 +237,7 @@ public class GsmSmsCbMessage {

            switch (type) {
                case CbGeoUtils.GEO_FENCING_MAXIMUM_WAIT_TIME:
                    // TODO: handle the maximum wait time in cell broadcast provider.
                    int maximumWaitTimeSec = bitReader.read(8);
                    maximumWaitTimeSec = bitReader.read(8);
                    break;
                case CbGeoUtils.GEOMETRY_TYPE_POLYGON:
                    List<LatLng> latLngs = new ArrayList<>();
@@ -247,7 +263,7 @@ public class GsmSmsCbMessage {
                    throw new IllegalArgumentException("Unsupported geoType = " + type);
            }
        }
        return geo;
        return new Pair(maximumWaitTimeSec, geo);
    }

    /**