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

Commit 57eefb69 authored by Taesu Lee's avatar Taesu Lee Committed by android-build-merger
Browse files

Merge "New system API to create SMS PDU and expose copyMessageToIcc()"

am: ca458963

Change-Id: I0a71827058f5ef75e164135516c6228649cfe072
parents 443c2e67 ca458963
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -9182,6 +9182,7 @@ package android.telephony {
  }
  public final class SmsManager {
    method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean copyMessageToIcc(@Nullable byte[], @NonNull byte[], int);
    method @RequiresPermission(android.Manifest.permission.ACCESS_MESSAGES_ON_ICC) public boolean deleteMessageFromIcc(int);
    method public boolean disableCellBroadcastRange(int, int, int);
    method public boolean enableCellBroadcastRange(int, int, int);
@@ -9193,6 +9194,7 @@ package android.telephony {
  public class SmsMessage {
    method @Nullable public static android.telephony.SmsMessage createFromNativeSmsSubmitPdu(@NonNull byte[], boolean);
    method @Nullable public static android.telephony.SmsMessage.SubmitPdu getSmsPdu(int, int, @Nullable String, @NonNull String, @NonNull String, long);
    method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static byte[] getSubmitPduEncodedMessage(boolean, @NonNull String, @NonNull String, int, int, int, int, int, int);
  }
+28 −12
Original line number Diff line number Diff line
@@ -1577,7 +1577,7 @@ public final class SmsManager {
    }

    /**
     * Copy a raw SMS PDU to the ICC.
     * Copies a raw SMS PDU to the ICC.
     * ICC (Integrated Circuit Card) is the card of the device.
     * For example, this can be the SIM or USIM for GSM.
     *
@@ -1591,21 +1591,26 @@ public final class SmsManager {
     * operation is performed on the correct subscription.
     * </p>
     *
     * @param smsc the SMSC for this message, or NULL for the default SMSC
     * @param pdu the raw PDU to store
     * @param status message status (STATUS_ON_ICC_READ, STATUS_ON_ICC_UNREAD,
     *               STATUS_ON_ICC_SENT, STATUS_ON_ICC_UNSENT)
     * @return true for success
     * @param smsc the SMSC for this messag or null for the default SMSC.
     * @param pdu the raw PDU to store.
     * @param status message status. One of these status:
     *               <code>STATUS_ON_ICC_READ</code>
     *               <code>STATUS_ON_ICC_UNREAD</code>
     *               <code>STATUS_ON_ICC_SENT</code>
     *               <code>STATUS_ON_ICC_UNSENT</code>
     * @return true for success. Otherwise false.
     *
     * @throws IllegalArgumentException if pdu is NULL
     * {@hide}
     * @throws IllegalArgumentException if pdu is null.
     * @hide
     */
    @UnsupportedAppUsage
    public boolean copyMessageToIcc(byte[] smsc, byte[] pdu,int status) {
    @SystemApi
    @RequiresPermission(Manifest.permission.ACCESS_MESSAGES_ON_ICC)
    public boolean copyMessageToIcc(
            @Nullable byte[] smsc, @NonNull byte[] pdu, @StatusOnIcc int status) {
        boolean success = false;

        if (null == pdu) {
            throw new IllegalArgumentException("pdu is NULL");
        if (pdu == null) {
            throw new IllegalArgumentException("pdu is null");
        }
        try {
            ISms iSms = getISmsService();
@@ -2035,6 +2040,17 @@ public final class SmsManager {
        return ret;
    }

    /** @hide */
    @IntDef(prefix = { "STATUS_ON_ICC_" }, value = {
            STATUS_ON_ICC_FREE,
            STATUS_ON_ICC_READ,
            STATUS_ON_ICC_UNREAD,
            STATUS_ON_ICC_SENT,
            STATUS_ON_ICC_UNSENT
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface StatusOnIcc {}

    // see SmsMessage.getStatusOnIcc

    /** Free space (TS 51.011 10.5.3 / 3GPP2 C.S0023 3.4.27). */
+71 −22
Original line number Diff line number Diff line
@@ -585,13 +585,15 @@ public class SmsMessage {
     */

    /**
     * Get an SMS-SUBMIT PDU for a destination address and a message.
     * Gets an SMS-SUBMIT PDU for a destination address and a message.
     * This method will not attempt to use any GSM national language 7 bit encodings.
     *
     * @param scAddress Service Centre address. Null means use default.
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param destinationAddress the address of the destination for the message.
     * @param message string representation of the message payload.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
     *         encoded message. Returns null on encode error.
     */
    public static SubmitPdu getSubmitPdu(String scAddress,
            String destinationAddress, String message, boolean statusReportRequested) {
@@ -604,17 +606,16 @@ public class SmsMessage {
    }

    /**
     * Get an SMS-SUBMIT PDU for a destination address and a message.
     * Gets an SMS-SUBMIT PDU for a destination address and a message.
     * This method will not attempt to use any GSM national language 7 bit encodings.
     *
     * @param scAddress Service Centre address. Null means use default.
     * @param destinationAddress the address of the destination for the message.
     * @param message String representation of the message payload.
     * @param statusReportRequested Indicates whether a report is requested for this message.
     * @param subId Subscription of the message
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param message string representation of the message payload.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @param subId subscription of the message.
     * @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
     *         encoded message. Returns null on encode error.
     * @hide
     */
    public static SubmitPdu getSubmitPdu(String scAddress,
@@ -632,17 +633,16 @@ public class SmsMessage {
    }

    /**
     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port.
     * Gets an SMS-SUBMIT PDU for a data message to a destination address &amp; port.
     * This method will not attempt to use any GSM national language 7 bit encodings.
     *
     * @param scAddress Service Centre address. null == use default
     * @param destinationAddress the address of the destination for the message
     * @param destinationPort the port to deliver the message to at the
     *        destination
     * @param data the data for the message
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param scAddress Service Centre address. Null means use default.
     * @param destinationAddress the address of the destination for the message.
     * @param destinationPort the port to deliver the message to at the destination.
     * @param data the data for the message.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
     *         encoded message. Returns null on encode error.
     */
    public static SubmitPdu getSubmitPdu(String scAddress,
            String destinationAddress, short destinationPort, byte[] data,
@@ -660,6 +660,55 @@ public class SmsMessage {
        return new SubmitPdu(spb);
    }

    // TODO: SubmitPdu class is used for SMS-DELIVER also now. Refactor for SubmitPdu and new
    // DeliverPdu accordingly.

    /**
     * Gets an SMS PDU to store in the ICC.
     *
     * @param subId subscription of the message.
     * @param status message status. One of these status:
     *               <code>SmsManager.STATUS_ON_ICC_READ</code>
     *               <code>SmsManager.STATUS_ON_ICC_UNREAD</code>
     *               <code>SmsManager.STATUS_ON_ICC_SENT</code>
     *               <code>SmsManager.STATUS_ON_ICC_UNSENT</code>
     * @param scAddress Service Centre address. Null means use default.
     * @param address destination or originating address.
     * @param message string representation of the message payload.
     * @param date the time stamp the message was received.
     * @return a <code>SubmitPdu</code> containing the encoded SC address if applicable and the
     *         encoded message. Returns null on encode error.
     * @hide
     */
    @SystemApi
    @Nullable
    public static SubmitPdu getSmsPdu(int subId, @SmsManager.StatusOnIcc int status,
            @Nullable String scAddress, @NonNull String address, @NonNull String message,
            long date) {
        SubmitPduBase spb;
        if (isCdmaVoice(subId)) { // 3GPP2 format
            if (status == SmsManager.STATUS_ON_ICC_READ
                    || status == SmsManager.STATUS_ON_ICC_UNREAD) { // Deliver PDU
                spb = com.android.internal.telephony.cdma.SmsMessage.getDeliverPdu(address,
                        message, date);
            } else { // Submit PDU
                spb = com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(scAddress,
                        address, message, false /* statusReportRequested */, null /* smsHeader */);
            }
        } else { // 3GPP format
            if (status == SmsManager.STATUS_ON_ICC_READ
                    || status == SmsManager.STATUS_ON_ICC_UNREAD) { // Deliver PDU
                spb = com.android.internal.telephony.gsm.SmsMessage.getDeliverPdu(scAddress,
                        address, message, date);
            } else { // Submit PDU
                spb = com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress,
                        address, message, false /* statusReportRequested */, null /* header */);
            }
        }

        return spb != null ? new SubmitPdu(spb) : null;
    }

    /**
     * Get an SMS-SUBMIT PDU's encoded message.
     * This is used by Bluetooth MAP profile to handle long non UTF-8 SMS messages.
+106 −54
Original line number Diff line number Diff line
@@ -201,26 +201,16 @@ public class SmsMessage extends SmsMessageBase {
    }

    /**
     * TODO(cleanup): why do getSubmitPdu methods take an scAddr input
     * and do nothing with it?  GSM allows us to specify a SC (eg,
     * when responding to an SMS that explicitly requests the response
     * is sent to a specific SC), or pass null to use the default
     * value.  Is there no similar notion in CDMA? Or do we just not
     * have it hooked up?
     */

    /**
     * Get an SMS-SUBMIT PDU for a destination address and a message
     * Gets an SMS-SUBMIT PDU for a destination address and a message.
     *
     * @param scAddr                Service Centre address.  Null means use default.
     * @param destAddr              Address of the recipient.
     * @param message               String representation of the message payload.
     * @param statusReportRequested Indicates whether a report is requested for this message.
     * @param smsHeader             Array containing the data for the User Data Header, preceded
     *                              by the Element Identifiers.
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param scAddr Service Centre address. No use for this message.
     * @param destAddr the address of the destination for the message.
     * @param message string representation of the message payload.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @param smsHeader array containing the data for the User Data Header, preceded by the Element
     *                  Identifiers.
     * @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
     *         null on encode error.
     * @hide
     */
    @UnsupportedAppUsage
@@ -230,18 +220,17 @@ public class SmsMessage extends SmsMessageBase {
    }

    /**
     * Get an SMS-SUBMIT PDU for a destination address and a message
     * Gets an SMS-SUBMIT PDU for a destination address and a message.
     *
     * @param scAddr                Service Centre address.  Null means use default.
     * @param destAddr              Address of the recipient.
     * @param message               String representation of the message payload.
     * @param statusReportRequested Indicates whether a report is requested for this message.
     * @param smsHeader             Array containing the data for the User Data Header, preceded
     *                              by the Element Identifiers.
     * @param priority              Priority level of the message
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param scAddr Service Centre address. No use for this message.
     * @param destAddr the address of the destination for the message.
     * @param message string representation of the message payload.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @param smsHeader array containing the data for the User Data Header, preceded by the Element
     *                  Identifiers.
     * @param priority priority level of the message.
     * @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
     *         null on encode error.
     * @hide
     */
    @UnsupportedAppUsage
@@ -264,16 +253,15 @@ public class SmsMessage extends SmsMessageBase {
    }

    /**
     * Get an SMS-SUBMIT PDU for a data message to a destination address and port.
     * Gets an SMS-SUBMIT PDU for a data message to a destination address &amp; port.
     *
     * @param scAddr Service Centre address. null == use default
     * @param destAddr the address of the destination for the message
     * @param destPort the port to deliver the message to at the
     *        destination
     * @param data the data for the message
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param scAddr Service Centre address. No use for this message.
     * @param destAddr the address of the destination for the message.
     * @param destPort the port to deliver the message to at the destination.
     * @param data the data for the message.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
     *         null on encode error.
     */
    @UnsupportedAppUsage
    public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort,
@@ -304,14 +292,13 @@ public class SmsMessage extends SmsMessageBase {
    }

    /**
     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
     * Gets an SMS-SUBMIT PDU for a data message to a destination address &amp; port.
     *
     * @param destAddr the address of the destination for the message
     * @param userData the data for the message
     * @param statusReportRequested Indicates whether a report is requested for this message.
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param destAddr the address of the destination for the message.
     * @param userData the data for the message.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
     *         null on encode error.
     */
    @UnsupportedAppUsage
    public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
@@ -320,15 +307,14 @@ public class SmsMessage extends SmsMessageBase {
    }

    /**
     * Get an SMS-SUBMIT PDU for a data message to a destination address &amp; port
     * Gets an SMS-SUBMIT PDU for a data message to a destination address &amp; port.
     *
     * @param destAddr the address of the destination for the message
     * @param userData the data for the message
     * @param statusReportRequested Indicates whether a report is requested for this message.
     * @param priority Priority level of the message
     * @return a <code>SubmitPdu</code> containing the encoded SC
     *         address, if applicable, and the encoded message.
     *         Returns null on encode error.
     * @param destAddr the address of the destination for the message.
     * @param userData the data for the message.
     * @param statusReportRequested indicates whether a report is requested for this message.
     * @param priority Priority level of the message.
     * @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
     *         null on encode error.
     */
    @UnsupportedAppUsage
    public static SubmitPdu getSubmitPdu(String destAddr, UserData userData,
@@ -1057,6 +1043,72 @@ public class SmsMessage extends SmsMessageBase {
        return null;
    }

    /**
     * Gets an SMS-DELIVER PDU for a originating address and a message.
     *
     * @param origAddr the address of the originating for the message.
     * @param message string representation of the message payload.
     * @param date the time stamp the message was received.
     * @return a <code>SubmitPdu</code> containing null SC address and the encoded message. Returns
     *         null on encode error.
     * @hide
     */
    public static SubmitPdu getDeliverPdu(String origAddr, String message, long date) {
        if (origAddr == null || message == null) {
            return null;
        }

        CdmaSmsAddress addr = CdmaSmsAddress.parse(origAddr);
        if (addr == null) return null;

        BearerData bearerData = new BearerData();
        bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;

        bearerData.messageId = 0;

        bearerData.deliveryAckReq = false;
        bearerData.userAckReq = false;
        bearerData.readAckReq = false;
        bearerData.reportReq = false;

        bearerData.userData = new UserData();
        bearerData.userData.payloadStr = message;

        bearerData.msgCenterTimeStamp = BearerData.TimeStamp.fromMillis(date);

        byte[] encodedBearerData = BearerData.encode(bearerData);
        if (encodedBearerData == null) return null;

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(100);
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeInt(SmsEnvelope.TELESERVICE_WMT);
            dos.writeInt(0); // servicePresent
            dos.writeInt(0); // serviceCategory
            dos.write(addr.digitMode);
            dos.write(addr.numberMode);
            dos.write(addr.ton); // number_type
            dos.write(addr.numberPlan);
            dos.write(addr.numberOfDigits);
            dos.write(addr.origBytes, 0, addr.origBytes.length); // digits
            // Subaddress is not supported.
            dos.write(0); // subaddressType
            dos.write(0); // subaddr_odd
            dos.write(0); // subaddr_nbr_of_digits
            dos.write(encodedBearerData.length);
            dos.write(encodedBearerData, 0, encodedBearerData.length);
            dos.close();

            SubmitPdu pdu = new SubmitPdu();
            pdu.encodedMessage = baos.toByteArray();
            pdu.encodedScAddress = null;
            return pdu;
        } catch (IOException ex) {
            Rlog.e(LOG_TAG, "creating Deliver PDU failed: " + ex);
        }
        return null;
    }

    /**
     * Creates byte array (pseudo pdu) from SMS object.
     * Note: Do not call this method more than once per object!
+38 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.util.BitwiseInputStream;
import com.android.internal.util.BitwiseOutputStream;

import java.io.ByteArrayOutputStream;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
@@ -284,6 +285,33 @@ public final class BearerData {
            return ts;
        }

        public static TimeStamp fromMillis(long timeInMillis) {
            TimeStamp ts = new TimeStamp();
            LocalDateTime localDateTime =
                    Instant.ofEpochMilli(timeInMillis).atZone(ts.mZoneId).toLocalDateTime();
            int year = localDateTime.getYear();
            if (year < 1996 || year > 2095) return null;
            ts.year = year;
            ts.month = localDateTime.getMonthValue();
            ts.monthDay = localDateTime.getDayOfMonth();
            ts.hour = localDateTime.getHour();
            ts.minute = localDateTime.getMinute();
            ts.second = localDateTime.getSecond();
            return ts;
        }

        public byte[] toByteArray() {
            int year = this.year % 100; // 00 - 99
            ByteArrayOutputStream outStream = new ByteArrayOutputStream(6);
            outStream.write((((year / 10) & 0x0F) << 4) | ((year % 10) & 0x0F));
            outStream.write((((month / 10) << 4) & 0xF0) | ((month % 10) & 0x0F));
            outStream.write((((monthDay / 10) << 4) & 0xF0) | ((monthDay % 10) & 0x0F));
            outStream.write((((hour / 10) << 4) & 0xF0) | ((hour % 10) & 0x0F));
            outStream.write((((minute / 10) << 4) & 0xF0) | ((minute % 10) & 0x0F));
            outStream.write((((second / 10) << 4) & 0xF0) | ((second % 10) & 0x0F));
            return outStream.toByteArray();
        }

        public long toMillis() {
            LocalDateTime localDateTime =
                    LocalDateTime.of(year, month + 1, monthDay, hour, minute, second);
@@ -957,6 +985,12 @@ public final class BearerData {
        }
    }

    private static void encodeMsgCenterTimeStamp(BearerData bData, BitwiseOutputStream outStream)
            throws BitwiseOutputStream.AccessException {
        outStream.write(8, 6);
        outStream.writeByteArray(8 * 6, bData.msgCenterTimeStamp.toByteArray());
    };

    /**
     * Create serialized representation for BearerData object.
     * (See 3GPP2 C.R1001-F, v1.0, section 4.5 for layout details)
@@ -1021,6 +1055,10 @@ public final class BearerData {
                outStream.write(8, SUBPARAM_SERVICE_CATEGORY_PROGRAM_RESULTS);
                encodeScpResults(bData, outStream);
            }
            if (bData.msgCenterTimeStamp != null) {
                outStream.write(8, SUBPARAM_MESSAGE_CENTER_TIME_STAMP);
                encodeMsgCenterTimeStamp(bData, outStream);
            }
            return outStream.toByteArray();
        } catch (BitwiseOutputStream.AccessException ex) {
            Rlog.e(LOG_TAG, "BearerData encode failed: " + ex);
Loading