Fix WifiLockManager Death link does not exist

The cause of the issue is that sometimes WifiLocks are added without
linkToDeath working properly.

Catches the NoSuchElementException inside WifiLockManager to prevent
SystemServer from crashing.

Bug: 155240535
Test: atest com.android.server.wifi
Change-Id: Id9d56b9da184febef7915eb5281ea39f97e51b06
diff --git a/service/java/com/android/server/wifi/WifiLockManager.java b/service/java/com/android/server/wifi/WifiLockManager.java
index 7bbd3aa..7cbeea0 100644
--- a/service/java/com/android/server/wifi/WifiLockManager.java
+++ b/service/java/com/android/server/wifi/WifiLockManager.java
@@ -36,6 +36,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.NoSuchElementException;
 
 /**
  * WifiLockManager maintains the list of wake locks held by different applications.
@@ -189,7 +190,6 @@
         // This is to make sure worksource value can not be changed by caller
         // after function returns.
         WorkSource newWorkSource = new WorkSource(ws);
-
         return addLock(new WifiLock(lockMode, tag, binder, newWorkSource));
     }
 
@@ -804,6 +804,7 @@
             try {
                 mBinder.linkToDeath(this, 0);
             } catch (RemoteException e) {
+                Log.e(TAG, "mBinder.linkToDeath failed: " + e.getMessage());
                 binderDied();
             }
         }
@@ -829,7 +830,11 @@
         }
 
         public void unlinkDeathRecipient() {
-            mBinder.unlinkToDeath(this, 0);
+            try {
+                mBinder.unlinkToDeath(this, 0);
+            } catch (NoSuchElementException e) {
+                Log.e(TAG, "mBinder.unlinkToDeath failed: " + e.getMessage());
+            }
         }
 
         public String toString() {
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java b/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
index ed27d50..40c47f4 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
@@ -41,6 +41,7 @@
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
+import java.util.NoSuchElementException;
 
 /** Unit tests for {@link WifiLockManager}. */
 @SmallTest
@@ -1375,4 +1376,19 @@
                 + " uid=" + Binder.getCallingUid() + " workSource=WorkSource{"
                         + DEFAULT_TEST_UID_1 + "}"));
     }
+
+    /**
+     * Verify that an Exception in unlinkDeathRecipient is caught.
+     */
+    @Test
+    public void testUnlinkDeathRecipiientCatchesException() throws Exception {
+        acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "",
+                mBinder, mWorkSource);
+        assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF, mWifiLockManager.getStrongestLockMode());
+
+        doThrow(new NoSuchElementException()).when(mBinder).unlinkToDeath(any(), anyInt());
+        releaseLowLatencyWifiLockSuccessful(mBinder);
+        assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
+                mWifiLockManager.getStrongestLockMode());
+    }
 }