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

Commit 3748600b authored by Martijn Coenen's avatar Martijn Coenen
Browse files

NFC: Allow apps to specify they're done with tag.

When an application is no longer interested in
communicating with a tag, but the tag is kept in
range of the device for a long amount of time, we
will burn a lot of power keeping the connection
to it alive.

Instead, allow the app to signal it's "done" with
the tag, which allows us to put the controller
in a low-power mode. This will save power in scenarios
such as an NFC tag embedded in a car dock or
wireless charging dock.

Bug: 26426491
Change-Id: I7a0149ede46e0c7610b06ed1776344b772677350
parent 8414c671
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -24246,6 +24246,7 @@ package android.nfc {
  public final class Tag implements android.os.Parcelable {
    method public int describeContents();
    method public boolean done(int);
    method public byte[] getId();
    method public java.lang.String[] getTechList();
    method public void writeToParcel(android.os.Parcel, int);
+1 −0
Original line number Diff line number Diff line
@@ -26246,6 +26246,7 @@ package android.nfc {
  public final class Tag implements android.os.Parcelable {
    method public int describeContents();
    method public boolean done(int);
    method public byte[] getId();
    method public java.lang.String[] getTechList();
    method public void writeToParcel(android.os.Parcel, int);
+1 −0
Original line number Diff line number Diff line
@@ -24254,6 +24254,7 @@ package android.nfc {
  public final class Tag implements android.os.Parcelable {
    method public int describeContents();
    method public boolean done(int);
    method public byte[] getId();
    method public java.lang.String[] getTechList();
    method public void writeToParcel(android.os.Parcel, int);
+1 −1
Original line number Diff line number Diff line
@@ -25,13 +25,13 @@ import android.nfc.TransceiveResult;
 */
interface INfcTag
{
    int close(int nativeHandle);
    int connect(int nativeHandle, int technology);
    int reconnect(int nativeHandle);
    int[] getTechList(int nativeHandle);
    boolean isNdef(int nativeHandle);
    boolean isPresent(int nativeHandle);
    TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
    boolean done(int nativeHandle, int debounceMs);

    NdefMessage ndefRead(int nativeHandle);
    int ndefWrite(int nativeHandle, in NdefMessage msg);
+36 −0
Original line number Diff line number Diff line
@@ -214,6 +214,42 @@ public final class Tag implements Parcelable {
        return techIntList;
    }

    /**
     * Signals that you are no longer interested in communicating with this tag
     * for as long as it remains in range.
     *
     * All future attempted communication to this tag will fail with {@link IOException}.
     * The NFC controller will be put in a low-power polling mode, allowing the device
     * to save power in cases where it's "attached" to a tag all the time (eg a tag in
     * car dock).
     *
     * Additionally the debounceMs parameter allows you to specify for how long the tag needs
     * to have gone out of range, before it will be dispatched again.
     *
     * Note: the NFC controller typically polls at a pretty slow interval (100 - 500 ms).
     * This means that if the tag repeatedly goes in and out of range (for example, in
     * case of a flaky connection), and the controller happens to poll every time the
     * tag is out of range, it *will* re-dispatch the tag after debounceMs, despite the tag
     * having been "in range" during the interval.
     *
     * Note 2: if a tag with another UID is detected after this API is called, its effect
     * will be cancelled; if this tag shows up before the amount of time specified in
     * debounceMs, it will be dispatched again.
     *
     * Note 3: some tags have a random UID, in which case this API won't work.
     *
     * @param debounceMs minimum amount of time the tag needs to be out of range before being
     *                   dispatched again.
     * @return false if the Tag couldn't be found (or has gone out of range), true otherwise
     */
    public boolean done(int debounceMs) {
        try {
            return mTagService.done(getServiceHandle(), debounceMs);
        } catch (RemoteException e) {
            return false;
        }
    }

    private static HashMap<String, Integer> getTechStringToCodeMap() {
        HashMap<String, Integer> techStringToCodeMap = new HashMap<String, Integer>();