FileDocCategorySizeDatePackage
MmsServiceBroker.javaAPI DocAndroid 5.1 API18519Thu Mar 12 22:22:42 GMT 2015com.android.server

MmsServiceBroker

public class MmsServiceBroker extends SystemService
This class is a proxy for MmsService APIs. We need this because MmsService runs in phone process and may crash anytime. This manages a connection to the actual MmsService and bridges the public SMS/MMS APIs with MmsService implementation.

Fields Summary
private static final String
TAG
private static final android.content.ComponentName
MMS_SERVICE_COMPONENT
private static final int
MSG_TRY_CONNECTING
private static final android.net.Uri
FAKE_SMS_SENT_URI
private static final android.net.Uri
FAKE_MMS_SENT_URI
private static final android.net.Uri
FAKE_SMS_DRAFT_URI
private static final android.net.Uri
FAKE_MMS_DRAFT_URI
private static final long
SERVICE_CONNECTION_WAIT_TIME_MS
private static final long
RETRY_DELAY_ON_DISCONNECTION_MS
private android.content.Context
mContext
private volatile com.android.internal.telephony.IMms
mService
private volatile android.app.AppOpsManager
mAppOpsManager
private volatile android.content.pm.PackageManager
mPackageManager
private volatile android.telephony.TelephonyManager
mTelephonyManager
private final android.os.Handler
mConnectionHandler
private android.content.ServiceConnection
mConnection
Constructors Summary
public MmsServiceBroker(android.content.Context context)


       
        super(context);
        mContext = context;
        mService = null;
    
Methods Summary
private voidensureService()

        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");
            }
        }
    
private android.app.AppOpsManagergetAppOpsManager()

        if (mAppOpsManager == null) {
            mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
        }
        return mAppOpsManager;
    
private java.lang.StringgetCallingPackageName()

        final String[] packages = getPackageManager().getPackagesForUid(Binder.getCallingUid());
        if (packages != null && packages.length > 0) {
            return packages[0];
        }
        return "unknown";
    
private android.content.pm.PackageManagergetPackageManager()

        if (mPackageManager == null) {
            mPackageManager = mContext.getPackageManager();
        }
        return mPackageManager;
    
private com.android.internal.telephony.IMmsgetServiceGuarded()
Making sure when we obtain the mService instance it is always valid. Throws {@link RuntimeException} when it is empty.

        ensureService();
        return mService;
    
private android.telephony.TelephonyManagergetTelephonyManager()

        if (mTelephonyManager == null) {
            mTelephonyManager = (TelephonyManager) mContext.getSystemService(
                    Context.TELEPHONY_SERVICE);
        }
        return mTelephonyManager;
    
public voidonStart()

        publishBinderService("imms", new BinderService());
    
public voidsystemRunning()

        Slog.i(TAG, "Delay connecting to MmsService until an API is called");
    
private voidtryConnecting()

        Slog.i(TAG, "Connecting to MmsService");
        synchronized (this) {
            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)) {
                    Slog.e(TAG, "Failed to bind to MmsService");
                }
            } catch (SecurityException e) {
                Slog.e(TAG, "Forbidden to bind to MmsService", e);
            }
        }