Remove attemptDeadServiceRecovery() from TagTechnology's.

attemptDeadServiceRecovery() is a hack to recover from NfcService dying. It
should be a rare event, and is only needed in NfcAdapter which is a long-lived
object.

TagTechnology objects are transient, it is acceptable for them to go stale
when NFC service dies. Lets not complicate the code with recovery for a rare
event.

Change-Id: I101350e920b075c680eb4f250683f0a2bb878553
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index dfea4d0..cfbe581 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -195,6 +195,7 @@
     // attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
     // recovery
     private static INfcAdapter sService;
+    private static INfcTag sTagService;
 
     private final Context mContext;
 
@@ -233,6 +234,12 @@
                 Log.e(TAG, "could not retrieve NFC service");
                 return null;
             }
+            try {
+                sTagService = sService.getNfcTagInterface();
+            } catch (RemoteException e) {
+                Log.e(TAG, "could not retrieve NFC Tag service");
+                return null;
+            }
         }
         return sService;
     }
@@ -299,6 +306,14 @@
     }
 
     /**
+     * Returns the binder interface to the tag service.
+     * @hide
+     */
+    public INfcTag getTagService() {
+        return sTagService;
+    }
+
+    /**
      * NFC service dead - attempt best effort recovery
      * @hide
      */
@@ -307,11 +322,21 @@
         INfcAdapter service = getServiceInterface();
         if (service == null) {
             Log.e(TAG, "could not retrieve NFC service during service recovery");
+            // nothing more can be done now, sService is still stale, we'll hit
+            // this recovery path again later
             return;
         }
-        /* assigning to sService is not thread-safe, but this is best-effort code
-         * and on a well-behaved system should never happen */
+        // assigning to sService is not thread-safe, but this is best-effort code
+        // and on a well-behaved system should never happen
         sService = service;
+        try {
+            sTagService = service.getNfcTagInterface();
+        } catch (RemoteException ee) {
+            Log.e(TAG, "could not retrieve NFC tag service during service recovery");
+            // nothing more can be done now, sService is still stale, we'll hit
+            // this recovery path again later
+        }
+
         return;
     }
 
diff --git a/core/java/android/nfc/technology/BasicTagTechnology.java b/core/java/android/nfc/technology/BasicTagTechnology.java
index bd0bc1e..f529ee5 100644
--- a/core/java/android/nfc/technology/BasicTagTechnology.java
+++ b/core/java/android/nfc/technology/BasicTagTechnology.java
@@ -30,19 +30,14 @@
  * A base class for tag technologies that are built on top of transceive().
  */
 /* package */ abstract class BasicTagTechnology implements TagTechnology {
+    private static final String TAG = "NFC";
 
     /*package*/ final Tag mTag;
     /*package*/ boolean mIsConnected;
     /*package*/ int mSelectedTechnology;
     private final NfcAdapter mAdapter;
-
-    // Following fields are final after construction, except for
-    // during attemptDeadServiceRecovery() when NFC crashes.
-    // Not locked - we accept a best effort attempt when NFC crashes.
-    /*package*/ INfcAdapter mService;
-    /*package*/ INfcTag mTagService;
-
-    private static final String TAG = "NFC";
+    /*package*/ final INfcAdapter mService;
+    /*package*/ final INfcTag mTagService;
 
     /**
      * @hide
@@ -64,11 +59,7 @@
 
         mAdapter = adapter;
         mService = mAdapter.getService();
-        try {
-          mTagService = mService.getNfcTagInterface();
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-        }
+        mTagService = mAdapter.getTagService();
         mTag = tag;
         mSelectedTechnology = tech;
     }
@@ -80,19 +71,6 @@
         this(adapter, tag, tag.getTechnologyList()[0]);
     }
 
-    /** NFC service dead - attempt best effort recovery */
-    /*package*/ void attemptDeadServiceRecovery(Exception e) {
-        mAdapter.attemptDeadServiceRecovery(e);
-        /* assigning to mService is not thread-safe, but this is best-effort code
-         * and on a well-behaved system should never happen */
-        mService = mAdapter.getService();
-        try {
-            mTagService = mService.getNfcTagInterface();
-        } catch (RemoteException e2) {
-            Log.e(TAG, "second RemoteException trying to recover from dead NFC service", e2);
-        }
-    }
-
     /**
      * Get the {@link Tag} this connection is associated with.
      * <p>Requires {@link android.Manifest.permission#NFC} permission.
@@ -135,7 +113,7 @@
         try {
             return mTagService.isPresent(mTag.getServiceHandle());
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
             return false;
         }
     }
@@ -163,7 +141,7 @@
                 throw new IOException();
             }
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
             throw new IOException("NFC service died");
         }
     }
@@ -183,21 +161,21 @@
     public void reconnect() throws IOException {
         if (!mIsConnected) {
             throw new IllegalStateException("Technology not connected yet");
-        } else {
-            try {
-                int errorCode = mTagService.reconnect(mTag.getServiceHandle());
+        }
 
-                if (errorCode != ErrorCodes.SUCCESS) {
-                    mIsConnected = false;
-                    mTag.setTechnologyDisconnected();
-                    throw new IOException();
-                }
-            } catch (RemoteException e) {
+        try {
+            int errorCode = mTagService.reconnect(mTag.getServiceHandle());
+
+            if (errorCode != ErrorCodes.SUCCESS) {
                 mIsConnected = false;
                 mTag.setTechnologyDisconnected();
-                attemptDeadServiceRecovery(e);
-                throw new IOException("NFC service died");
+                throw new IOException();
             }
+        } catch (RemoteException e) {
+            mIsConnected = false;
+            mTag.setTechnologyDisconnected();
+            Log.e(TAG, "NFC service dead", e);
+            throw new IOException("NFC service died");
         }
     }
 
@@ -219,7 +197,7 @@
              */
             mTagService.reconnect(mTag.getServiceHandle());
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
         } finally {
             mIsConnected = false;
             mTag.setTechnologyDisconnected();
@@ -237,7 +215,7 @@
             }
             return response;
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
             throw new IOException("NFC service died");
         }
     }
diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java
index b301de9..03c518e 100644
--- a/core/java/android/nfc/technology/IsoDep.java
+++ b/core/java/android/nfc/technology/IsoDep.java
@@ -58,10 +58,14 @@
     /**
      * 3A only
      */
-    public byte[] getHistoricalBytes() { return mHistBytes; }
+    public byte[] getHistoricalBytes() {
+        return mHistBytes;
+    }
 
     /**
      * 3B only
      */
-    public byte[] getHiLayerResponse() { return mHiLayerResponse; }
+    public byte[] getHiLayerResponse() {
+        return mHiLayerResponse;
+    }
 }
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index ddcec69..457920f 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -23,6 +23,7 @@
 import android.nfc.Tag;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.util.Log;
 
 import java.io.IOException;
 
@@ -38,6 +39,8 @@
  * permission.
  */
 public final class Ndef extends BasicTagTechnology {
+    private static final String TAG = "NFC";
+
     /** @hide */
     public static final int NDEF_MODE_READ_ONLY = 1;
     /** @hide */
@@ -168,7 +171,7 @@
                 return null;
             }
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
             return null;
         }
     }
@@ -200,7 +203,7 @@
                 throw new IOException("Tag is not ndef");
             }
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
         }
     }
 
@@ -241,7 +244,7 @@
                     throw new IOException();
             }
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
             return false;
         }
     }
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
index 11161f1..0901607 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -23,6 +23,7 @@
 import android.nfc.Tag;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.util.Log;
 
 import java.io.IOException;
 
@@ -36,6 +37,8 @@
  * permission.
  */
 public final class NdefFormatable extends BasicTagTechnology {
+    private static final String TAG = "NFC";
+
     /**
      * Internal constructor, to be used by NfcAdapter
      * @hide
@@ -85,7 +88,7 @@
                 throw new IOException();
             }
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "NFC service dead", e);
         }
     }