Merge "TM#setNetworkSelectionModeAutomatic hang muliple minutes"
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index f1be951..5760527 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -51,6 +51,7 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceSpecificException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
@@ -371,6 +372,8 @@
public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
"reset_network_erase_modem_config_enabled";
+ private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
+
/**
* A request object to use for transmitting data to an ICC.
*/
@@ -1890,8 +1893,8 @@
* @see #sendRequestAsync
*/
private Object sendRequest(int command, Object argument) {
- return sendRequest(
- command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
+ return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null,
+ null, -1 /*timeoutInMs*/);
}
/**
@@ -1901,7 +1904,7 @@
*/
private Object sendRequest(int command, Object argument, WorkSource workSource) {
return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
- null, workSource);
+ null, workSource, -1 /*timeoutInMs*/);
}
/**
@@ -1910,7 +1913,18 @@
* @see #sendRequestAsync
*/
private Object sendRequest(int command, Object argument, Integer subId) {
- return sendRequest(command, argument, subId, null, null);
+ return sendRequest(command, argument, subId, null, null, -1 /*timeoutInMs*/);
+ }
+
+ /**
+ * Posts the specified command to be executed on the main thread,
+ * waits for the request to complete for at most {@code timeoutInMs}, and returns the result
+ * if not timeout or null otherwise.
+ * @see #sendRequestAsync
+ */
+ private @Nullable Object sendRequest(int command, Object argument, Integer subId,
+ long timeoutInMs) {
+ return sendRequest(command, argument, subId, null, null, timeoutInMs);
}
/**
@@ -1919,7 +1933,7 @@
* @see #sendRequestAsync
*/
private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
- return sendRequest(command, argument, subId, null, workSource);
+ return sendRequest(command, argument, subId, null, workSource, -1 /*timeoutInMs*/);
}
/**
@@ -1928,17 +1942,18 @@
* @see #sendRequestAsync
*/
private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
- return sendRequest(
- command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
+ return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone,
+ workSource, -1 /*timeoutInMs*/);
}
/**
- * Posts the specified command to be executed on the main thread,
- * waits for the request to complete, and returns the result.
+ * Posts the specified command to be executed on the main thread. If {@code timeoutInMs} is
+ * negative, waits for the request to complete, and returns the result. Otherwise, wait for
+ * maximum of {@code timeoutInMs} milliseconds, interrupt and return null.
* @see #sendRequestAsync
*/
- private Object sendRequest(
- int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
+ private @Nullable Object sendRequest(int command, Object argument, Integer subId, Phone phone,
+ WorkSource workSource, long timeoutInMs) {
if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
throw new RuntimeException("This method will deadlock if called from the main thread.");
}
@@ -1955,16 +1970,36 @@
Message msg = mMainThreadHandler.obtainMessage(command, request);
msg.sendToTarget();
- // Wait for the request to complete
+
synchronized (request) {
- while (request.result == null) {
- try {
- request.wait();
- } catch (InterruptedException e) {
- // Do nothing, go back and wait until the request is complete
+ if (timeoutInMs >= 0) {
+ // Wait for at least timeoutInMs before returning null request result
+ long now = SystemClock.elapsedRealtime();
+ long deadline = now + timeoutInMs;
+ while (request == null && now < deadline) {
+ try {
+ request.wait(deadline - now);
+ } catch (InterruptedException e) {
+ // Do nothing, go back and check if request is completed or timeout
+ } finally {
+ now = SystemClock.elapsedRealtime();
+ }
+ }
+ } else {
+ // Wait for the request to complete
+ while (request.result == null) {
+ try {
+ request.wait();
+ } catch (InterruptedException e) {
+ // Do nothing, go back and wait until the request is complete
+ }
}
}
}
+ if (request.result == null) {
+ Log.wtf(LOG_TAG,
+ "sendRequest: Blocking command timed out. Something has gone terribly wrong.");
+ }
return request.result;
}
@@ -5592,7 +5627,8 @@
return;
}
if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
- sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
+ sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
+ SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS);
} finally {
Binder.restoreCallingIdentity(identity);
}