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

Commit 8bede170 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Fix NdefRecord flags handling.

NdefMessages created from byte arrays set the wrong flags on
NdefRecord: every record had at least FLAG_MB|FLAG_ME set, instead of actually
setting the flags from the byte-stream itself. Fixed by creating an internal
constructor which can take the flags.

Public constructor remains the same, as we don't want to bother application
writers with these flags - they can be inferred from the context in which the
record is used. Getting the flags is not a public operation on an NdefRecord
either. However, applications can get the byte[] representation and it
is reasonable for them to expect the flags byte to be set correctly.

Change-Id: Ic32411688dd092c55b1aeccbba9635792e15a671
parent aa4fa2c5
Loading
Loading
Loading
Loading
+16 −5
Original line number Original line Diff line number Diff line
@@ -163,6 +163,18 @@ public final class NdefRecord implements Parcelable {
     *                must not be null
     *                must not be null
     */
     */
    public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
    public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
        /* New NDEF records created by applications will have FLAG_MB|FLAG_ME
         * set by default; when multiple records are stored in a
         * {@link NdefMessage}, these flags will be corrected when the {@link NdefMessage}
         * is serialized to bytes.
         */
        this(tnf, type, id, payload, (byte)(FLAG_MB|FLAG_ME));
    }

    /**
     * @hide
     */
    /*package*/ NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload, byte flags) {
        /* check arguments */
        /* check arguments */
        if ((type == null) || (id == null) || (payload == null)) {
        if ((type == null) || (id == null) || (payload == null)) {
            throw new IllegalArgumentException("Illegal null argument");
            throw new IllegalArgumentException("Illegal null argument");
@@ -172,9 +184,6 @@ public final class NdefRecord implements Parcelable {
            throw new IllegalArgumentException("TNF out of range " + tnf);
            throw new IllegalArgumentException("TNF out of range " + tnf);
        }
        }


        /* generate flag */
        byte flags = FLAG_MB | FLAG_ME;

        /* Determine if it is a short record */
        /* Determine if it is a short record */
        if(payload.length < 0xFF) {
        if(payload.length < 0xFF) {
            flags |= FLAG_SR;
            flags |= FLAG_SR;
@@ -258,6 +267,7 @@ public final class NdefRecord implements Parcelable {
    }
    }


    public void writeToParcel(Parcel dest, int flags) {
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mFlags);
        dest.writeInt(mTnf);
        dest.writeInt(mTnf);
        dest.writeInt(mType.length);
        dest.writeInt(mType.length);
        dest.writeByteArray(mType);
        dest.writeByteArray(mType);
@@ -270,6 +280,7 @@ public final class NdefRecord implements Parcelable {
    public static final Parcelable.Creator<NdefRecord> CREATOR =
    public static final Parcelable.Creator<NdefRecord> CREATOR =
            new Parcelable.Creator<NdefRecord>() {
            new Parcelable.Creator<NdefRecord>() {
        public NdefRecord createFromParcel(Parcel in) {
        public NdefRecord createFromParcel(Parcel in) {
            byte flags = (byte)in.readInt();
            short tnf = (short)in.readInt();
            short tnf = (short)in.readInt();
            int typeLength = in.readInt();
            int typeLength = in.readInt();
            byte[] type = new byte[typeLength];
            byte[] type = new byte[typeLength];
@@ -281,7 +292,7 @@ public final class NdefRecord implements Parcelable {
            byte[] payload = new byte[payloadLength];
            byte[] payload = new byte[payloadLength];
            in.readByteArray(payload);
            in.readByteArray(payload);


            return new NdefRecord(tnf, type, id, payload);
            return new NdefRecord(tnf, type, id, payload, flags);
        }
        }
        public NdefRecord[] newArray(int size) {
        public NdefRecord[] newArray(int size) {
            return new NdefRecord[size];
            return new NdefRecord[size];
+2 −2
Original line number Original line Diff line number Diff line
@@ -86,7 +86,7 @@ static jint android_nfc_NdefMessage_parseNdefMessage(JNIEnv *e, jobject o,
    if (records_array == NULL)
    if (records_array == NULL)
        goto end;
        goto end;


    ctor = e->GetMethodID(record_cls, "<init>", "(S[B[B[B)V");
    ctor = e->GetMethodID(record_cls, "<init>", "(S[B[B[BB)V");


    for (i = 0; i < num_of_records; i++) {
    for (i = 0; i < num_of_records; i++) {
        jbyteArray type, id, payload;
        jbyteArray type, id, payload;
@@ -128,7 +128,7 @@ static jint android_nfc_NdefMessage_parseNdefMessage(JNIEnv *e, jobject o,
                (jbyte *)record.PayloadData);
                (jbyte *)record.PayloadData);


        new_record = e->NewObject(record_cls, ctor,
        new_record = e->NewObject(record_cls, ctor,
                (jshort)record.Tnf, type, id, payload);
                (jshort)record.Tnf, type, id, payload, (jbyte)record.Flags);


        e->SetObjectArrayElement(records_array, i, new_record);
        e->SetObjectArrayElement(records_array, i, new_record);


+6 −1
Original line number Original line Diff line number Diff line
@@ -91,7 +91,7 @@ static jint android_nfc_NdefRecord_parseNdefRecord(JNIEnv *e, jobject o,
    jint ret = -1;
    jint ret = -1;
    phFriNfc_NdefRecord_t record;
    phFriNfc_NdefRecord_t record;


    jfieldID mType, mId, mPayload, mTnf;
    jfieldID mType, mId, mPayload, mTnf, mFlags;
    jbyteArray type = NULL;
    jbyteArray type = NULL;
    jbyteArray id = NULL;
    jbyteArray id = NULL;
    jbyteArray payload = NULL;
    jbyteArray payload = NULL;
@@ -142,10 +142,15 @@ static jint android_nfc_NdefRecord_parseNdefRecord(JNIEnv *e, jobject o,
    if (payload == NULL) {
    if (payload == NULL) {
        goto clean_and_return;
        goto clean_and_return;
    }
    }

    e->SetByteArrayRegion(payload, 0, record.PayloadLength,
    e->SetByteArrayRegion(payload, 0, record.PayloadLength,
            (jbyte *)record.PayloadData);
            (jbyte *)record.PayloadData);
    e->SetObjectField(o, mPayload, payload);
    e->SetObjectField(o, mPayload, payload);


    /* Set flags field */
    mFlags = e->GetFieldID(record_cls, "mFlags", "B");
    e->SetIntField(o, mFlags, record.Flags);

    ret = 0;
    ret = 0;


clean_and_return:
clean_and_return: