am 108ba84a: am de73afe2: Merge "Make MmsServiceBroker more robust to MmsService crashes" into lmp-dev
* commit '108ba84ac546bb72deae76699cd26b1004985c05':
Make MmsServiceBroker more robust to MmsService crashes
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 0fb80c9..926235f 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -34,7 +34,7 @@
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
-import android.os.ServiceManager;
+import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.util.Slog;
@@ -56,10 +56,12 @@
private static final Uri FAKE_SMS_DRAFT_URI = Uri.parse("content://sms/draft/0");
private static final Uri FAKE_MMS_DRAFT_URI = Uri.parse("content://mms/draft/0");
+ private static final long SERVICE_CONNECTION_WAIT_TIME_MS = 4 * 1000L; // 4 seconds
+ private static final long RETRY_DELAY_ON_DISCONNECTION_MS = 3 * 1000L; // 3 seconds
+
private Context mContext;
// The actual MMS service instance to invoke
private volatile IMms mService;
- private boolean mIsConnecting;
// Cached system service instances
private volatile AppOpsManager mAppOpsManager = null;
@@ -85,7 +87,7 @@
Slog.i(TAG, "MmsService connected");
synchronized (MmsServiceBroker.this) {
mService = IMms.Stub.asInterface(service);
- mIsConnecting = false;
+ MmsServiceBroker.this.notifyAll();
}
}
@@ -94,8 +96,13 @@
Slog.i(TAG, "MmsService unexpectedly disconnected");
synchronized (MmsServiceBroker.this) {
mService = null;
- mIsConnecting = false;
+ MmsServiceBroker.this.notifyAll();
}
+ // Retry connecting, but not too eager (with a delay)
+ // since it may come back by itself.
+ mConnectionHandler.sendMessageDelayed(
+ mConnectionHandler.obtainMessage(MSG_TRY_CONNECTING),
+ RETRY_DELAY_ON_DISCONNECTION_MS);
}
};
@@ -103,7 +110,6 @@
super(context);
mContext = context;
mService = null;
- mIsConnecting = false;
}
@Override
@@ -118,29 +124,50 @@
private void tryConnecting() {
Slog.i(TAG, "Connecting to MmsService");
synchronized (this) {
- if (mIsConnecting) {
- Slog.d(TAG, "Already connecting");
+ if (mService != null) {
+ Slog.d(TAG, "Already connected");
return;
}
final Intent intent = new Intent();
intent.setComponent(MMS_SERVICE_COMPONENT);
try {
- if (mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
- mIsConnecting = true;
- } else {
- Slog.e(TAG, "Failed to connect to MmsService");
+ if (!mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)) {
+ Slog.e(TAG, "Failed to bind to MmsService");
}
} catch (SecurityException e) {
- Slog.e(TAG, "Forbidden to connect to MmsService", e);
+ Slog.e(TAG, "Forbidden to bind to MmsService", e);
}
}
}
private void ensureService() {
- if (mService == null) {
- // Service instance lost, kicking off the connection again
- mConnectionHandler.sendMessage(mConnectionHandler.obtainMessage(MSG_TRY_CONNECTING));
- throw new RuntimeException("MMS service is not connected");
+ synchronized (this) {
+ if (mService == null) {
+ // Service is not connected. Try blocking connecting.
+ Slog.w(TAG, "MmsService not connected. Try connecting...");
+ mConnectionHandler.sendMessage(
+ mConnectionHandler.obtainMessage(MSG_TRY_CONNECTING));
+ final long shouldEnd =
+ SystemClock.elapsedRealtime() + SERVICE_CONNECTION_WAIT_TIME_MS;
+ long waitTime = SERVICE_CONNECTION_WAIT_TIME_MS;
+ while (waitTime > 0) {
+ try {
+ // TODO: consider using Java concurrent construct instead of raw object wait
+ this.wait(waitTime);
+ } catch (InterruptedException e) {
+ Slog.w(TAG, "Connection wait interrupted", e);
+ }
+ if (mService != null) {
+ // Success
+ return;
+ }
+ // Calculate remaining waiting time to make sure we wait the full timeout period
+ waitTime = shouldEnd - SystemClock.elapsedRealtime();
+ }
+ // Timed out. Something's really wrong.
+ Slog.e(TAG, "Can not connect to MmsService (timed out)");
+ throw new RuntimeException("Timed out in connecting to MmsService");
+ }
}
}