Permit assignment from a null hidl_memory

Bug: 34102220
Test: libhidl_test, hidl_test

Change-Id: Ic0da09f0f6a79643ee44c6b13ef606b2217956e0
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 1b0184a..78bc2c8 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -226,8 +226,15 @@
     // copy assignment
     hidl_memory &operator=(const hidl_memory &other) {
         if (this != &other) {
-            mOwnsHandle = true;
-            mHandle = native_handle_clone(other.mHandle);
+            cleanup();
+
+            if (other.mHandle == nullptr) {
+                mHandle = nullptr;
+                mOwnsHandle = false;
+            } else {
+                mOwnsHandle = true;
+                mHandle = native_handle_clone(other.mHandle);
+            }
             mSize = other.mSize;
             mName = other.mName;
         }
@@ -238,10 +245,7 @@
     // TODO move constructor/move assignment
 
     ~hidl_memory() {
-        // TODO if we had previously mapped from this object, unmap
-        if (mOwnsHandle) {
-            native_handle_close(mHandle);
-        }
+        cleanup();
     }
 
     const native_handle_t* handle() const {
@@ -260,11 +264,19 @@
     static const size_t kOffsetOfHandle;
     // offsetof(hidl_memory, mName) exposed since mHandle is private.
     static const size_t kOffsetOfName;
+
 private:
     bool mOwnsHandle;
     hidl_handle mHandle;
     size_t mSize;
     hidl_string mName;
+
+    void cleanup() {
+        // TODO(b/33812533): native_handle_delete
+        if (mOwnsHandle && mHandle != nullptr) {
+            native_handle_close(mHandle);
+        }
+    }
 };
 
 ////////////////////////////////////////////////////////////////////////////////