Stop presence checking for tags when reader mode is disabled

Presence checking prevents the tag from getting disconnected for a
dedicated time even if the tag is out of range. While enabling reader mode,
users are allowed to set a custom value for the presence checking delay.
This effect should also be disabled, when the mode is disabled.

Test: Sample application; enable/disable Reader Mode
Bug: 70697778
Change-Id: I247f17644b002c60d5ca3624b12021f64a042e97
diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java b/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java
index 720df29..671ea2b 100755
--- a/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java
+++ b/nci/src/com/android/nfc/dhimpl/NativeNfcTag.java
@@ -73,7 +73,7 @@
     class PresenceCheckWatchdog extends Thread {
 
         private final int watchdogTimeout;
-        private final DeviceHost.TagDisconnectedCallback tagDisconnectedCallback;
+        private DeviceHost.TagDisconnectedCallback tagDisconnectedCallback;
 
         private boolean isPresent = true;
         private boolean isStopped = false;
@@ -100,9 +100,12 @@
             this.notifyAll();
         }
 
-        public synchronized void end() {
+        public synchronized void end(boolean disableCallback) {
             isStopped = true;
             doCheck = false;
+            if (disableCallback) {
+                tagDisconnectedCallback = null;
+            }
             this.notifyAll();
         }
 
@@ -229,6 +232,14 @@
     }
 
     @Override
+    public synchronized void stopPresenceChecking() {
+        mIsPresent = false;
+        if (mWatchdog != null) {
+            mWatchdog.end(true);
+        }
+    }
+
+    @Override
     public synchronized void startPresenceChecking(int presenceCheckDelay,
                                                    DeviceHost.TagDisconnectedCallback callback) {
         // Once we start presence checking, we allow the upper layers
@@ -257,7 +268,7 @@
         }
         if (watchdog != null) {
             // Watchdog has already disconnected or will do it
-            watchdog.end();
+            watchdog.end(false);
             try {
                 watchdog.join();
             } catch (InterruptedException e) {
diff --git a/src/com/android/nfc/DeviceHost.java b/src/com/android/nfc/DeviceHost.java
index 7fb0833..b7441ba 100644
--- a/src/com/android/nfc/DeviceHost.java
+++ b/src/com/android/nfc/DeviceHost.java
@@ -58,6 +58,7 @@
         boolean isPresent();
         void startPresenceChecking(int presenceCheckDelay,
                                    @Nullable TagDisconnectedCallback callback);
+        void stopPresenceChecking();
 
         int[] getTechList();
         void removeTechnology(int tech); // TODO remove this one
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index 112db71..abf4d3b 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -1114,6 +1114,7 @@
                 } else {
                     try {
                         mReaderModeParams = null;
+                        StopPresenceChecking();
                         binder.unlinkToDeath(mReaderModeDeathRecipient, 0);
                     } catch (NoSuchElementException e) {
                         Log.e(TAG, "Reader mode Binder was never registered.");
@@ -1758,6 +1759,17 @@
         }
         return false;
     }
+
+    private void StopPresenceChecking() {
+        Object[] objectValues = mObjectMap.values().toArray();
+        for (Object object : objectValues) {
+            if (object instanceof TagEndpoint) {
+                TagEndpoint tag = (TagEndpoint)object;
+                ((TagEndpoint) object).stopPresenceChecking();
+            }
+        }
+    }
+
     /**
      * Disconnect any target if present
      */