FileDocCategorySizeDatePackage
ServiceMonitor.javaAPI DocAndroid 5.1 API10758Thu Mar 12 22:22:42 GMT 2015com.android.systemui.statusbar

ServiceMonitor

public class ServiceMonitor extends Object
Manages a persistent connection to a service component defined in a secure setting.

If a valid service component is specified in the secure setting, starts it up and keeps it running; handling setting changes, package updates, component disabling, and unexpected process termination.

Clients can listen for important events using the supplied {@link Callbacks}.

Fields Summary
private static final int
RECHECK_DELAY
private static final int
WAIT_FOR_STOP
public static final int
MSG_START_SERVICE
public static final int
MSG_CONTINUE_START_SERVICE
public static final int
MSG_STOP_SERVICE
public static final int
MSG_PACKAGE_INTENT
public static final int
MSG_CHECK_BOUND
public static final int
MSG_SERVICE_DISCONNECTED
private final android.os.Handler
mHandler
private final android.database.ContentObserver
mSettingObserver
private final android.content.BroadcastReceiver
mBroadcastReceiver
private final String
mTag
private final boolean
mDebug
private final android.content.Context
mContext
private final String
mSettingKey
private final Callbacks
mCallbacks
private android.content.ComponentName
mServiceName
private SC
mServiceConnection
private boolean
mBound
Constructors Summary
public ServiceMonitor(String ownerTag, boolean debug, android.content.Context context, String settingKey, Callbacks callbacks)


        
                  
        mTag = ownerTag + ".ServiceMonitor";
        mDebug = debug;
        mContext = context;
        mSettingKey = settingKey;
        mCallbacks = callbacks;
    
Methods Summary
private static java.lang.StringbundleToString(android.os.Bundle bundle)

        if (bundle == null) return null;
        StringBuilder sb = new StringBuilder('{");
        for (String key : bundle.keySet()) {
            if (sb.length() > 1) sb.append(',");
            Object v = bundle.get(key);
            v = (v instanceof String[]) ? Arrays.asList((String[]) v) : v;
            sb.append(key).append('=").append(v);
        }
        return sb.append('}").toString();
    
private voidcheckBound()

        if (mDebug) Log.d(mTag, "checkBound mBound=" + mBound);
        if (!mBound) {
            startService();
        }
    
private voidcontinueStartService()

        if (mDebug) Log.d(mTag, "continueStartService");
        Intent intent = new Intent().setComponent(mServiceName);
        try {
            mServiceConnection = new SC();
            mBound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
            if (mDebug) Log.d(mTag, "mBound: " + mBound);
        } catch (Throwable t) {
            Log.w(mTag, "Error binding to service: " + mServiceName, t);
        }
        if (!mBound) {
            mCallbacks.onNoService();
        }
    
private android.content.ComponentNamegetComponentNameFromSetting()

        String cn = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                mSettingKey, UserHandle.USER_CURRENT);
        return cn == null ? null : ComponentName.unflattenFromString(cn);
    
private voidpackageIntent(android.content.Intent intent)

        if (mDebug) Log.d(mTag, "packageIntent intent=" + intent
                + " extras=" + bundleToString(intent.getExtras()));
        if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
            mHandler.sendEmptyMessage(MSG_START_SERVICE);
        } else if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) {
            PackageManager pm = mContext.getPackageManager();
            boolean serviceEnabled =
                    pm.getApplicationEnabledSetting(mServiceName.getPackageName())
                        != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                    && pm.getComponentEnabledSetting(mServiceName)
                        != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
            if (mBound && !serviceEnabled) {
                stopService();
                scheduleCheckBound();
            } else if (!mBound && serviceEnabled) {
                startService();
            }
        }
    
private voidscheduleCheckBound()

        mHandler.removeMessages(MSG_CHECK_BOUND);
        mHandler.sendEmptyMessageDelayed(MSG_CHECK_BOUND, RECHECK_DELAY);
    
private voidserviceDisconnected(android.content.ComponentName serviceName)

        if (mDebug) Log.d(mTag, "serviceDisconnected serviceName=" + serviceName
                + " mServiceName=" + mServiceName);
        if (serviceName.equals(mServiceName)) {
            mBound = false;
            scheduleCheckBound();
        }
    
public voidstart()

        // listen for setting changes
        ContentResolver cr = mContext.getContentResolver();
        cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey),
                false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL);

        // listen for package/component changes
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
        filter.addDataScheme("package");
        mContext.registerReceiver(mBroadcastReceiver, filter);

        mHandler.sendEmptyMessage(MSG_START_SERVICE);
    
private voidstartService()

        mServiceName = getComponentNameFromSetting();
        if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName);
        if (mServiceName == null) {
            mBound = false;
            mCallbacks.onNoService();
        } else {
            long delay = mCallbacks.onServiceStartAttempt();
            mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay);
        }
    
private voidstopService()

        if (mDebug) Log.d(mTag, "stopService");
        boolean stopped = mContext.stopService(new Intent().setComponent(mServiceName));
        if (mDebug) Log.d(mTag, "  stopped=" + stopped);
        mContext.unbindService(mServiceConnection);
        mBound = false;