Improve error handling with separate ICanErrorListener

Error handling highlights:
- moved onError from ICanMessageListener to ICanErrorListener
- added isFatal callback argument to request client disconnect
- don't down interface that's already down

Also:
- don't crash if it's not possible to unregister ICanBus
- don't crash while trying to down interface that failed
- make hidl-utils available to vendor libraries

Bug: 143779011
Test: implemented a VHAL service prototype that communicates with this HAL
Change-Id: I98d054da9da0ead5ef952aebc086e052ac996212
diff --git a/automotive/can/1.0/default/CanSocket.cpp b/automotive/can/1.0/default/CanSocket.cpp
index 4d86de6..ecf4044 100644
--- a/automotive/can/1.0/default/CanSocket.cpp
+++ b/automotive/can/1.0/default/CanSocket.cpp
@@ -61,7 +61,14 @@
 
 CanSocket::~CanSocket() {
     mStopReaderThread = true;
-    mReaderThread.join();
+
+    /* CanSocket can be brought down as a result of read failure, from the same thread,
+     * so let's just detach and let it finish on its own. */
+    if (mReaderThreadFinished) {
+        mReaderThread.detach();
+    } else {
+        mReaderThread.join();
+    }
 }
 
 bool CanSocket::send(const struct canfd_frame& frame) {
@@ -94,6 +101,7 @@
 
 void CanSocket::readerThread() {
     LOG(VERBOSE) << "Reader thread started";
+    int errnoCopy = 0;
 
     while (!mStopReaderThread) {
         /* The ideal would be to have a blocking read(3) call and interrupt it with shutdown(3).
@@ -130,14 +138,20 @@
             }
             if (errno == EAGAIN) continue;
 
-            LOG(ERROR) << "Failed to read CAN packet: " << errno;
+            errnoCopy = errno;
+            LOG(ERROR) << "Failed to read CAN packet: " << strerror(errno) << " (" << errno << ")";
             break;
         }
 
         mReadCallback(frame, ts);
     }
 
-    if (!mStopReaderThread) mErrorCallback();
+    bool failed = !mStopReaderThread;
+    auto errCb = mErrorCallback;
+    mReaderThreadFinished = true;
+
+    // Don't access any fields from here, see CanSocket::~CanSocket comment about detached thread
+    if (failed) errCb(errnoCopy);
 
     LOG(VERBOSE) << "Reader thread stopped";
 }