Merge "Return pending intent to service caller if MmsService can't be connected"
This commit is contained in:
@@ -36,6 +36,7 @@ import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.service.carrier.CarrierMessagingService;
|
||||
import android.telephony.SmsManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -111,6 +112,106 @@ public class MmsServiceBroker extends SystemService {
|
||||
}
|
||||
};
|
||||
|
||||
// Instance of IMms for returning failure to service API caller,
|
||||
// used when MmsService cannot be connected.
|
||||
private final IMms mServiceStubForFailure = new IMms() {
|
||||
|
||||
@Override
|
||||
public IBinder asBinder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl,
|
||||
Bundle configOverrides, PendingIntent sentIntent) throws RemoteException {
|
||||
returnPendingIntentWithError(sentIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadMessage(int subId, String callingPkg, String locationUrl,
|
||||
Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent)
|
||||
throws RemoteException {
|
||||
returnPendingIntentWithError(downloadedIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getCarrierConfigValues(int subId) throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri importTextMessage(String callingPkg, String address, int type, String text,
|
||||
long timestampMillis, boolean seen, boolean read) throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri importMultimediaMessage(String callingPkg, Uri contentUri, String messageId,
|
||||
long timestampSecs, boolean seen, boolean read) throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteStoredMessage(String callingPkg, Uri messageUri)
|
||||
throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteStoredConversation(String callingPkg, long conversationId)
|
||||
throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateStoredMessageStatus(String callingPkg, Uri messageUri,
|
||||
ContentValues statusValues) throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean archiveStoredConversation(String callingPkg, long conversationId,
|
||||
boolean archived) throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri addTextMessageDraft(String callingPkg, String address, String text)
|
||||
throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri addMultimediaMessageDraft(String callingPkg, Uri contentUri)
|
||||
throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendStoredMessage(int subId, String callingPkg, Uri messageUri,
|
||||
Bundle configOverrides, PendingIntent sentIntent) throws RemoteException {
|
||||
returnPendingIntentWithError(sentIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoPersisting(String callingPkg, boolean enabled) throws RemoteException {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAutoPersisting() throws RemoteException {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void returnPendingIntentWithError(PendingIntent pendingIntent) {
|
||||
try {
|
||||
pendingIntent.send(mContext, SmsManager.MMS_ERROR_UNSPECIFIED, null);
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Slog.e(TAG, "Failed to return pending intent result", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public MmsServiceBroker(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
@@ -145,44 +246,51 @@ public class MmsServiceBroker extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureService() {
|
||||
private IMms getOrConnectService() {
|
||||
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");
|
||||
if (mService != null) {
|
||||
return mService;
|
||||
}
|
||||
// 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 mService;
|
||||
}
|
||||
// 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)");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Making sure when we obtain the mService instance it is always valid.
|
||||
* Throws {@link RuntimeException} when it is empty.
|
||||
* Make sure to return a non-empty service instance. Return the connected MmsService
|
||||
* instance, if not connected, try connecting. If fail to connect, return a fake service
|
||||
* instance which returns failure to service caller.
|
||||
*
|
||||
* @return a non-empty service instance, real or fake
|
||||
*/
|
||||
private IMms getServiceGuarded() {
|
||||
ensureService();
|
||||
return mService;
|
||||
final IMms service = getOrConnectService();
|
||||
if (service != null) {
|
||||
return service;
|
||||
}
|
||||
return mServiceStubForFailure;
|
||||
}
|
||||
|
||||
private AppOpsManager getAppOpsManager() {
|
||||
|
||||
Reference in New Issue
Block a user