Loading nfc/api/current.txt +12 −5 Original line number Diff line number Diff line Loading @@ -228,14 +228,10 @@ package android.nfc.cardemulation { method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onDeactivated(int); method public abstract byte[] processCommandApdu(byte[], android.os.Bundle); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.os.Bundle>); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>); method public final void sendResponseApdu(byte[]); field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_DATA = "android.nfc.cardemulation.DATA"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_GAIN = "android.nfc.cardemulation.GAIN"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_TIMESTAMP = "android.nfc.cardemulation.TIMESTAMP"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_TYPE = "android.nfc.cardemulation.TYPE"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_A = 65; // 0x0041 'A' field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_B = 66; // 0x0042 'B' field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_F = 70; // 0x0046 'F' Loading Loading @@ -274,6 +270,17 @@ package android.nfc.cardemulation { field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service"; } @FlaggedApi("android.nfc.nfc_read_polling_loop") public final class PollingFrame implements android.os.Parcelable { ctor public PollingFrame(char, @Nullable byte[], int, int); method public int describeContents(); method @NonNull public byte[] getData(); method public int getGain(); method public int getTimestamp(); method public char getType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.PollingFrame> CREATOR; } } package android.nfc.tech { Loading nfc/java/android/nfc/NfcAdapter.java +8 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.nfc.cardemulation.HostApduService; import android.nfc.cardemulation.PollingFrame; import android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; import android.nfc.tech.NfcA; Loading Loading @@ -2799,7 +2801,12 @@ public final class NfcAdapter { */ @TestApi @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) public void notifyPollingLoop(@NonNull Bundle frame) { public void notifyPollingLoop(@NonNull PollingFrame pollingFrame) { Bundle frame = new Bundle(); frame.putChar(HostApduService.KEY_POLLING_LOOP_TYPE, pollingFrame.getType()); frame.putByte(HostApduService.KEY_POLLING_LOOP_GAIN, (byte) pollingFrame.getGain()); frame.putByteArray(HostApduService.KEY_POLLING_LOOP_DATA, pollingFrame.getData()); frame.putInt(HostApduService.KEY_POLLING_LOOP_TIMESTAMP, pollingFrame.getTimestamp()); try { if (sService == null) { attemptDeadServiceRecovery(null); Loading nfc/java/android/nfc/cardemulation/HostApduService.java +19 −9 Original line number Diff line number Diff line Loading @@ -245,7 +245,9 @@ public abstract class HostApduService extends Service { /** * KEY_POLLING_LOOP_TYPE is the Bundle key for the type of * polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_TYPE = "android.nfc.cardemulation.TYPE"; Loading Loading @@ -300,24 +302,27 @@ public abstract class HostApduService extends Service { /** * KEY_POLLING_LOOP_DATA is the Bundle key for the raw data of captured from * the polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * when the frame type isn't recognized. * the polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_DATA = "android.nfc.cardemulation.DATA"; /** * KEY_POLLING_LOOP_GAIN is the Bundle key for the field strength of * the polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * when the frame type isn't recognized. * the polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_GAIN = "android.nfc.cardemulation.GAIN"; /** * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for the timestamp of * the polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * when the frame type isn't recognized. * the polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_TIMESTAMP = "android.nfc.cardemulation.TIMESTAMP"; Loading Loading @@ -407,7 +412,12 @@ public abstract class HostApduService extends Service { ArrayList<Bundle> frames = msg.getData().getParcelableArrayList(KEY_POLLING_LOOP_FRAMES_BUNDLE, Bundle.class); processPollingFrames(frames); ArrayList<PollingFrame> pollingFrames = new ArrayList<PollingFrame>(frames.size()); for (Bundle frame : frames) { pollingFrames.add(new PollingFrame(frame)); } processPollingFrames(pollingFrames); break; default: super.handleMessage(msg); Loading Loading @@ -482,7 +492,7 @@ public abstract class HostApduService extends Service { * @param frame A description of the polling frame. */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public void processPollingFrames(@NonNull List<Bundle> frame) { public void processPollingFrames(@NonNull List<PollingFrame> frame) { } /** Loading nfc/java/android/nfc/cardemulation/PollingFrame.java 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.nfc.cardemulation; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; /** * Polling Frames represent data about individual frames of an NFC polling loop. These frames will * be deliverd to subclasses of {@link HostApduService} that have registered filters with * {@link CardEmulation#registerPollingLoopFilterForService(ComponentName, String)} that match a * given frame in a loop and will be delivered through calls to * {@link HostApduService#processPollingFrames(List)}. */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public final class PollingFrame implements Parcelable{ private char mType; private byte[] mData; private int mGain; private int mTimestamp; public static final @NonNull Parcelable.Creator<PollingFrame> CREATOR = new Parcelable.Creator<PollingFrame>() { @Override public PollingFrame createFromParcel(Parcel source) { return new PollingFrame(source.readBundle()); } @Override public PollingFrame[] newArray(int size) { return new PollingFrame[0]; } }; PollingFrame(Bundle frame) { mType = frame.getChar(HostApduService.KEY_POLLING_LOOP_TYPE); mData = frame.getByteArray(HostApduService.KEY_POLLING_LOOP_DATA); if (mData == null) { mData = new byte[0]; } mGain = frame.getByte(HostApduService.KEY_POLLING_LOOP_GAIN); mTimestamp = frame.getInt(HostApduService.KEY_POLLING_LOOP_TIMESTAMP); } public PollingFrame(char type, @Nullable byte[] data, int gain, int timestamp) { mType = type; mData = data == null ? new byte[0] : data; mGain = gain; mTimestamp = timestamp; } private PollingFrame(Parcel source) { mType = (char) source.readInt(); source.readByteArray(mData); mGain = source.readInt(); mTimestamp = source.readInt(); } /** * Returns the type of frame for this polling loop frame. * * The possible return values are: * <ul> * <li>{@link HostApduService#POLLING_LOOP_TYPE_ON}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_OFF}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_A}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_B}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_F}</li> * </ul> */ public char getType() { return mType; } /** * Returns the raw data from the polling type frame. */ public @NonNull byte[] getData() { return mData; } /** * Returns the gain representing the field strength of the NFC field when this polling loop * frame was observed. */ public int getGain() { return mGain; } /** * Returns the timestamp of when the polling loop frame was observed in milliseconds. These * timestamps are relative and not absolute and should only be used fro comparing the timing of * frames relative to each other. * @return the timestamp in milliseconds */ public int getTimestamp() { return mTimestamp; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeBundle(toBundle()); } /** * * @hide * @return a Bundle representing this frame */ public Bundle toBundle() { Bundle frame = new Bundle(); frame.putInt(HostApduService.KEY_POLLING_LOOP_TYPE, getType()); frame.putByte(HostApduService.KEY_POLLING_LOOP_GAIN, (byte) getGain()); frame.putByteArray(HostApduService.KEY_POLLING_LOOP_DATA, getData()); frame.putInt(HostApduService.KEY_POLLING_LOOP_TIMESTAMP, getTimestamp()); return frame; } } Loading
nfc/api/current.txt +12 −5 Original line number Diff line number Diff line Loading @@ -228,14 +228,10 @@ package android.nfc.cardemulation { method public final android.os.IBinder onBind(android.content.Intent); method public abstract void onDeactivated(int); method public abstract byte[] processCommandApdu(byte[], android.os.Bundle); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.os.Bundle>); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>); method public final void sendResponseApdu(byte[]); field public static final int DEACTIVATION_DESELECTED = 1; // 0x1 field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0 field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_DATA = "android.nfc.cardemulation.DATA"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_GAIN = "android.nfc.cardemulation.GAIN"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_TIMESTAMP = "android.nfc.cardemulation.TIMESTAMP"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final String KEY_POLLING_LOOP_TYPE = "android.nfc.cardemulation.TYPE"; field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_A = 65; // 0x0041 'A' field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_B = 66; // 0x0042 'B' field @FlaggedApi("android.nfc.nfc_read_polling_loop") public static final char POLLING_LOOP_TYPE_F = 70; // 0x0046 'F' Loading Loading @@ -274,6 +270,17 @@ package android.nfc.cardemulation { field public static final String SERVICE_META_DATA = "android.nfc.cardemulation.off_host_apdu_service"; } @FlaggedApi("android.nfc.nfc_read_polling_loop") public final class PollingFrame implements android.os.Parcelable { ctor public PollingFrame(char, @Nullable byte[], int, int); method public int describeContents(); method @NonNull public byte[] getData(); method public int getGain(); method public int getTimestamp(); method public char getType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.nfc.cardemulation.PollingFrame> CREATOR; } } package android.nfc.tech { Loading
nfc/java/android/nfc/NfcAdapter.java +8 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,8 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.nfc.cardemulation.HostApduService; import android.nfc.cardemulation.PollingFrame; import android.nfc.tech.MifareClassic; import android.nfc.tech.Ndef; import android.nfc.tech.NfcA; Loading Loading @@ -2799,7 +2801,12 @@ public final class NfcAdapter { */ @TestApi @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) public void notifyPollingLoop(@NonNull Bundle frame) { public void notifyPollingLoop(@NonNull PollingFrame pollingFrame) { Bundle frame = new Bundle(); frame.putChar(HostApduService.KEY_POLLING_LOOP_TYPE, pollingFrame.getType()); frame.putByte(HostApduService.KEY_POLLING_LOOP_GAIN, (byte) pollingFrame.getGain()); frame.putByteArray(HostApduService.KEY_POLLING_LOOP_DATA, pollingFrame.getData()); frame.putInt(HostApduService.KEY_POLLING_LOOP_TIMESTAMP, pollingFrame.getTimestamp()); try { if (sService == null) { attemptDeadServiceRecovery(null); Loading
nfc/java/android/nfc/cardemulation/HostApduService.java +19 −9 Original line number Diff line number Diff line Loading @@ -245,7 +245,9 @@ public abstract class HostApduService extends Service { /** * KEY_POLLING_LOOP_TYPE is the Bundle key for the type of * polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_TYPE = "android.nfc.cardemulation.TYPE"; Loading Loading @@ -300,24 +302,27 @@ public abstract class HostApduService extends Service { /** * KEY_POLLING_LOOP_DATA is the Bundle key for the raw data of captured from * the polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * when the frame type isn't recognized. * the polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_DATA = "android.nfc.cardemulation.DATA"; /** * KEY_POLLING_LOOP_GAIN is the Bundle key for the field strength of * the polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * when the frame type isn't recognized. * the polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_GAIN = "android.nfc.cardemulation.GAIN"; /** * KEY_POLLING_LOOP_TIMESTAMP is the Bundle key for the timestamp of * the polling loop frame in the Bundle passed to {@link #processPollingFrames(List)} * when the frame type isn't recognized. * the polling loop frame in the Bundle included in MSG_POLLING_LOOP. * * @hide */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public static final String KEY_POLLING_LOOP_TIMESTAMP = "android.nfc.cardemulation.TIMESTAMP"; Loading Loading @@ -407,7 +412,12 @@ public abstract class HostApduService extends Service { ArrayList<Bundle> frames = msg.getData().getParcelableArrayList(KEY_POLLING_LOOP_FRAMES_BUNDLE, Bundle.class); processPollingFrames(frames); ArrayList<PollingFrame> pollingFrames = new ArrayList<PollingFrame>(frames.size()); for (Bundle frame : frames) { pollingFrames.add(new PollingFrame(frame)); } processPollingFrames(pollingFrames); break; default: super.handleMessage(msg); Loading Loading @@ -482,7 +492,7 @@ public abstract class HostApduService extends Service { * @param frame A description of the polling frame. */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public void processPollingFrames(@NonNull List<Bundle> frame) { public void processPollingFrames(@NonNull List<PollingFrame> frame) { } /** Loading
nfc/java/android/nfc/cardemulation/PollingFrame.java 0 → 100644 +143 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.nfc.cardemulation; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; /** * Polling Frames represent data about individual frames of an NFC polling loop. These frames will * be deliverd to subclasses of {@link HostApduService} that have registered filters with * {@link CardEmulation#registerPollingLoopFilterForService(ComponentName, String)} that match a * given frame in a loop and will be delivered through calls to * {@link HostApduService#processPollingFrames(List)}. */ @FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP) public final class PollingFrame implements Parcelable{ private char mType; private byte[] mData; private int mGain; private int mTimestamp; public static final @NonNull Parcelable.Creator<PollingFrame> CREATOR = new Parcelable.Creator<PollingFrame>() { @Override public PollingFrame createFromParcel(Parcel source) { return new PollingFrame(source.readBundle()); } @Override public PollingFrame[] newArray(int size) { return new PollingFrame[0]; } }; PollingFrame(Bundle frame) { mType = frame.getChar(HostApduService.KEY_POLLING_LOOP_TYPE); mData = frame.getByteArray(HostApduService.KEY_POLLING_LOOP_DATA); if (mData == null) { mData = new byte[0]; } mGain = frame.getByte(HostApduService.KEY_POLLING_LOOP_GAIN); mTimestamp = frame.getInt(HostApduService.KEY_POLLING_LOOP_TIMESTAMP); } public PollingFrame(char type, @Nullable byte[] data, int gain, int timestamp) { mType = type; mData = data == null ? new byte[0] : data; mGain = gain; mTimestamp = timestamp; } private PollingFrame(Parcel source) { mType = (char) source.readInt(); source.readByteArray(mData); mGain = source.readInt(); mTimestamp = source.readInt(); } /** * Returns the type of frame for this polling loop frame. * * The possible return values are: * <ul> * <li>{@link HostApduService#POLLING_LOOP_TYPE_ON}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_OFF}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_A}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_B}</li> * <li>{@link HostApduService#POLLING_LOOP_TYPE_F}</li> * </ul> */ public char getType() { return mType; } /** * Returns the raw data from the polling type frame. */ public @NonNull byte[] getData() { return mData; } /** * Returns the gain representing the field strength of the NFC field when this polling loop * frame was observed. */ public int getGain() { return mGain; } /** * Returns the timestamp of when the polling loop frame was observed in milliseconds. These * timestamps are relative and not absolute and should only be used fro comparing the timing of * frames relative to each other. * @return the timestamp in milliseconds */ public int getTimestamp() { return mTimestamp; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeBundle(toBundle()); } /** * * @hide * @return a Bundle representing this frame */ public Bundle toBundle() { Bundle frame = new Bundle(); frame.putInt(HostApduService.KEY_POLLING_LOOP_TYPE, getType()); frame.putByte(HostApduService.KEY_POLLING_LOOP_GAIN, (byte) getGain()); frame.putByteArray(HostApduService.KEY_POLLING_LOOP_DATA, getData()); frame.putInt(HostApduService.KEY_POLLING_LOOP_TIMESTAMP, getTimestamp()); return frame; } }