summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2019-06-24 17:41:05 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-06-24 17:41:05 +0000
commit2c8f14236db2b2c7989d39dc4e4e51af51bff081 (patch)
tree75d3b358636dc1ef8ac0b123e55510ebe823dbf8 /service
parentc23fd06553163353e75ed9b45d2556b5969ed6f0 (diff)
parent8a5bc9513ceb608391721198df47c1acee0af2cd (diff)
Merge "SupplicantHal/HostapdHal: Wait for death" into qt-r1-dev
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/HostapdHal.java31
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHal.java32
2 files changed, 55 insertions, 8 deletions
diff --git a/service/java/com/android/server/wifi/HostapdHal.java b/service/java/com/android/server/wifi/HostapdHal.java
index 69c787f48..ee96fb269 100644
--- a/service/java/com/android/server/wifi/HostapdHal.java
+++ b/service/java/com/android/server/wifi/HostapdHal.java
@@ -39,6 +39,9 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.ThreadSafe;
@@ -51,6 +54,8 @@ public class HostapdHal {
private static final String TAG = "HostapdHal";
@VisibleForTesting
public static final String HAL_INSTANCE_NAME = "default";
+ @VisibleForTesting
+ public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L;
private final Object mLock = new Object();
private boolean mVerboseLoggingEnabled = false;
@@ -230,11 +235,11 @@ public class HostapdHal {
* Link to death for IHostapd object.
* @return true on success, false otherwise.
*/
- private boolean linkToHostapdDeath() {
+ private boolean linkToHostapdDeath(HwRemoteBinder.DeathRecipient deathRecipient, long cookie) {
synchronized (mLock) {
if (mIHostapd == null) return false;
try {
- if (!mIHostapd.linkToDeath(mHostapdDeathRecipient, ++mDeathRecipientCookie)) {
+ if (!mIHostapd.linkToDeath(deathRecipient, cookie)) {
Log.wtf(TAG, "Error on linkToDeath on IHostapd");
hostapdServiceDiedHandler(mDeathRecipientCookie);
return false;
@@ -282,7 +287,7 @@ public class HostapdHal {
Log.e(TAG, "Got null IHostapd service. Stopping hostapd HIDL startup");
return false;
}
- if (!linkToHostapdDeath()) {
+ if (!linkToHostapdDeath(mHostapdDeathRecipient, ++mDeathRecipientCookie)) {
mIHostapd = null;
return false;
}
@@ -486,10 +491,19 @@ public class HostapdHal {
}
/**
- * Terminate the hostapd daemon.
+ * Terminate the hostapd daemon & wait for it's death.
*/
public void terminate() {
synchronized (mLock) {
+ // Register for a new death listener to block until hostapd is dead.
+ final long waitForDeathCookie = new Random().nextLong();
+ final CountDownLatch waitForDeathLatch = new CountDownLatch(1);
+ linkToHostapdDeath((cookie) -> {
+ Log.d(TAG, "IHostapd died: cookie=" + cookie);
+ if (cookie != waitForDeathCookie) return;
+ waitForDeathLatch.countDown();
+ }, waitForDeathCookie);
+
final String methodStr = "terminate";
if (!checkHostapdAndLogFailure(methodStr)) return;
try {
@@ -497,6 +511,15 @@ public class HostapdHal {
} catch (RemoteException e) {
handleRemoteException(e, methodStr);
}
+
+ // Now wait for death listener callback to confirm that it's dead.
+ try {
+ if (!waitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ Log.w(TAG, "Timed out waiting for confirmation of hostapd death");
+ }
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Failed to wait for hostapd death");
+ }
}
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index bed66d926..86518c761 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -86,6 +86,9 @@ import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -108,6 +111,8 @@ public class SupplicantStaIfaceHal {
public static final String INIT_STOP_PROPERTY = "ctl.stop";
@VisibleForTesting
public static final String INIT_SERVICE_NAME = "wpa_supplicant";
+ @VisibleForTesting
+ public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L;
/**
* Regex pattern for extracting the wps device type bytes.
* Matches a strings like the following: "<categ>-<OUI>-<subcateg>";
@@ -262,11 +267,12 @@ public class SupplicantStaIfaceHal {
}
}
- private boolean linkToSupplicantDeath() {
+ private boolean linkToSupplicantDeath(
+ HwRemoteBinder.DeathRecipient deathRecipient, long cookie) {
synchronized (mLock) {
if (mISupplicant == null) return false;
try {
- if (!mISupplicant.linkToDeath(mSupplicantDeathRecipient, ++mDeathRecipientCookie)) {
+ if (!mISupplicant.linkToDeath(deathRecipient, cookie)) {
Log.wtf(TAG, "Error on linkToDeath on ISupplicant");
supplicantServiceDiedHandler(mDeathRecipientCookie);
return false;
@@ -294,7 +300,7 @@ public class SupplicantStaIfaceHal {
Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup");
return false;
}
- if (!linkToSupplicantDeath()) {
+ if (!linkToSupplicantDeath(mSupplicantDeathRecipient, ++mDeathRecipientCookie)) {
return false;
}
}
@@ -645,10 +651,19 @@ public class SupplicantStaIfaceHal {
}
/**
- * Terminate the supplicant daemon.
+ * Terminate the supplicant daemon & wait for it's death.
*/
public void terminate() {
synchronized (mLock) {
+ // Register for a new death listener to block until supplicant is dead.
+ final long waitForDeathCookie = new Random().nextLong();
+ final CountDownLatch waitForDeathLatch = new CountDownLatch(1);
+ linkToSupplicantDeath((cookie) -> {
+ Log.d(TAG, "ISupplicant died: cookie=" + cookie);
+ if (cookie != waitForDeathCookie) return;
+ waitForDeathLatch.countDown();
+ }, waitForDeathCookie);
+
if (isV1_1()) {
Log.i(TAG, "Terminating supplicant using HIDL");
terminate_V1_1();
@@ -656,6 +671,15 @@ public class SupplicantStaIfaceHal {
Log.i(TAG, "Terminating supplicant using init");
mPropertyService.set(INIT_STOP_PROPERTY, INIT_SERVICE_NAME);
}
+
+ // Now wait for death listener callback to confirm that it's dead.
+ try {
+ if (!waitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ Log.w(TAG, "Timed out waiting for confirmation of supplicant death");
+ }
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Failed to wait for supplicant death");
+ }
}
}