15c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock/* 25c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Copyright (C) 2013 The Android Open Source Project 35c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * 45c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 55c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * you may not use this file except in compliance with the License. 65c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * You may obtain a copy of the License at 75c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * 85c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * http://www.apache.org/licenses/LICENSE-2.0 95c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * 105c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Unless required by applicable law or agreed to in writing, software 115c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 125c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * See the License for the specific language governing permissions and 145c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * limitations under the License. 155c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock */ 165c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 175c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockpackage com.android.systemui.statusbar; 185c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 195c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.BroadcastReceiver; 205c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.ComponentName; 215c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.ContentResolver; 225c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.Context; 235c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.Intent; 245c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.IntentFilter; 255c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.ServiceConnection; 265c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.content.pm.PackageManager; 275c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.database.ContentObserver; 285c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.net.Uri; 295c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.os.Bundle; 305c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.os.Handler; 315c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.os.IBinder; 325c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.os.Message; 335c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.os.RemoteException; 345c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.os.UserHandle; 355c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.provider.Settings; 365c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport android.util.Log; 375c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 385c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockimport java.util.Arrays; 395c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 405c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock/** 415c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * Manages a persistent connection to a service component defined in a secure setting. 425c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * 435c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * <p>If a valid service component is specified in the secure setting, starts it up and keeps it 445c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * running; handling setting changes, package updates, component disabling, and unexpected 455c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * process termination. 465c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * 475c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * <p>Clients can listen for important events using the supplied {@link Callbacks}. 485c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock */ 495c4541246c6a70f53552423dc35940386788bd5fJohn Spurlockpublic class ServiceMonitor { 505c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private static final int RECHECK_DELAY = 2000; 515c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private static final int WAIT_FOR_STOP = 500; 525c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 535c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public interface Callbacks { 545c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock /** The service does not exist or failed to bind */ 555c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock void onNoService(); 565c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock /** The service is about to start, this is a chance to perform cleanup and 575c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock * delay the start if necessary */ 585c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock long onServiceStartAttempt(); 595c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 605c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 615c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock // internal handler + messages used to serialize access to internal state 625c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public static final int MSG_START_SERVICE = 1; 635c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public static final int MSG_CONTINUE_START_SERVICE = 2; 645c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public static final int MSG_STOP_SERVICE = 3; 655c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public static final int MSG_PACKAGE_INTENT = 4; 665c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public static final int MSG_CHECK_BOUND = 5; 675c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public static final int MSG_SERVICE_DISCONNECTED = 6; 685c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 695c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final Handler mHandler = new Handler() { 705c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void handleMessage(Message msg) { 715c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock switch(msg.what) { 725c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock case MSG_START_SERVICE: 735c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock startService(); 745c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock break; 755c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock case MSG_CONTINUE_START_SERVICE: 765c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock continueStartService(); 775c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock break; 785c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock case MSG_STOP_SERVICE: 795c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock stopService(); 805c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock break; 815c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock case MSG_PACKAGE_INTENT: 825c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock packageIntent((Intent)msg.obj); 835c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock break; 845c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock case MSG_CHECK_BOUND: 855c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock checkBound(); 865c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock break; 875c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock case MSG_SERVICE_DISCONNECTED: 885c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock serviceDisconnected((ComponentName)msg.obj); 895c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock break; 905c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 915c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 925c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock }; 935c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 945c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final ContentObserver mSettingObserver = new ContentObserver(mHandler) { 955c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void onChange(boolean selfChange) { 965c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock onChange(selfChange, null); 975c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 985c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 995c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void onChange(boolean selfChange, Uri uri) { 1005c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "onChange selfChange=" + selfChange + " uri=" + uri); 1014db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock ComponentName cn = getComponentNameFromSetting(); 1024db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock if (cn == null && mServiceName == null || cn != null && cn.equals(mServiceName)) { 1034db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock if (mDebug) Log.d(mTag, "skipping no-op restart"); 1044db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock return; 1054db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock } 1065c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mBound) { 1075c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendEmptyMessage(MSG_STOP_SERVICE); 1085c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1095c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendEmptyMessageDelayed(MSG_START_SERVICE, WAIT_FOR_STOP); 1105c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1115c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock }; 1125c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1135c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final class SC implements ServiceConnection, IBinder.DeathRecipient { 1145c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private ComponentName mName; 1155c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private IBinder mService; 1165c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1175c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void onServiceConnected(ComponentName name, IBinder service) { 1185c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "onServiceConnected name=" + name + " service=" + service); 1195c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mName = name; 1205c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mService = service; 1215c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock try { 1225c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock service.linkToDeath(this, 0); 1235c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } catch (RemoteException e) { 1245c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock Log.w(mTag, "Error linking to death", e); 1255c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1265c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1275c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1285c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void onServiceDisconnected(ComponentName name) { 1295c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "onServiceDisconnected name=" + name); 1305c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock boolean unlinked = mService.unlinkToDeath(this, 0); 1315c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, " unlinked=" + unlinked); 1325c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendMessage(mHandler.obtainMessage(MSG_SERVICE_DISCONNECTED, mName)); 1335c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1345c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1355c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void binderDied() { 1365c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "binderDied"); 1375c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendMessage(mHandler.obtainMessage(MSG_SERVICE_DISCONNECTED, mName)); 1385c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1395c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1405c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1415c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 1425c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void onReceive(Context context, Intent intent) { 1435c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock String pkg = intent.getData().getSchemeSpecificPart(); 1445c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mServiceName != null && mServiceName.getPackageName().equals(pkg)) { 1455c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendMessage(mHandler.obtainMessage(MSG_PACKAGE_INTENT, intent)); 1465c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1475c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1485c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock }; 1495c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1505c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final String mTag; 1515c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final boolean mDebug; 1525c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1535c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final Context mContext; 1545c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final String mSettingKey; 1555c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private final Callbacks mCallbacks; 1565c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1575c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private ComponentName mServiceName; 1585c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private SC mServiceConnection; 1595c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private boolean mBound; 1605c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1615c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public ServiceMonitor(String ownerTag, boolean debug, 1625c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock Context context, String settingKey, Callbacks callbacks) { 1635c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mTag = ownerTag + ".ServiceMonitor"; 1645c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mDebug = debug; 1655c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mContext = context; 1665c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mSettingKey = settingKey; 1675c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mCallbacks = callbacks; 1685c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1695c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1705c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock public void start() { 1715c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock // listen for setting changes 1725c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock ContentResolver cr = mContext.getContentResolver(); 1735c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock cr.registerContentObserver(Settings.Secure.getUriFor(mSettingKey), 1745c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock false /*notifyForDescendents*/, mSettingObserver, UserHandle.USER_ALL); 1755c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1765c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock // listen for package/component changes 1775c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock IntentFilter filter = new IntentFilter(); 1785c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock filter.addAction(Intent.ACTION_PACKAGE_ADDED); 1795c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock filter.addAction(Intent.ACTION_PACKAGE_CHANGED); 1805c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock filter.addDataScheme("package"); 1815c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mContext.registerReceiver(mBroadcastReceiver, filter); 1825c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1835c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendEmptyMessage(MSG_START_SERVICE); 1845c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 1855c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1864db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock private ComponentName getComponentNameFromSetting() { 1874db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock String cn = Settings.Secure.getStringForUser(mContext.getContentResolver(), 1884db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock mSettingKey, UserHandle.USER_CURRENT); 1894db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock return cn == null ? null : ComponentName.unflattenFromString(cn); 1904db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock } 1914db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock 1925c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock // everything below is called on the handler 1935c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 1945c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private void packageIntent(Intent intent) { 1955c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "packageIntent intent=" + intent 1965c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock + " extras=" + bundleToString(intent.getExtras())); 1975c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 1985c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendEmptyMessage(MSG_START_SERVICE); 1995c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } else if (Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())) { 2005c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock PackageManager pm = mContext.getPackageManager(); 2015c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock boolean serviceEnabled = 2025c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock pm.getApplicationEnabledSetting(mServiceName.getPackageName()) 2035c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock != PackageManager.COMPONENT_ENABLED_STATE_DISABLED 2045c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock && pm.getComponentEnabledSetting(mServiceName) 2055c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock != PackageManager.COMPONENT_ENABLED_STATE_DISABLED; 2065c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mBound && !serviceEnabled) { 2075c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock stopService(); 2085c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock scheduleCheckBound(); 2095c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } else if (!mBound && serviceEnabled) { 2105c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock startService(); 2115c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2125c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2135c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2145c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 2155c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private void stopService() { 2165c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "stopService"); 2175c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock boolean stopped = mContext.stopService(new Intent().setComponent(mServiceName)); 2185c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, " stopped=" + stopped); 2195c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mContext.unbindService(mServiceConnection); 2205c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mBound = false; 2215c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2225c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 2235c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private void startService() { 2244db614dbed10e74285eaa6d0e56c3e79a4afecc0John Spurlock mServiceName = getComponentNameFromSetting(); 2255c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "startService mServiceName=" + mServiceName); 2265c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mServiceName == null) { 2275c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mBound = false; 2285c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mCallbacks.onNoService(); 2295c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } else { 2305c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock long delay = mCallbacks.onServiceStartAttempt(); 2315c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_START_SERVICE, delay); 2325c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2335c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2345c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 2355c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private void continueStartService() { 2365c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "continueStartService"); 2375c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock Intent intent = new Intent().setComponent(mServiceName); 2385c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock try { 2395c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mServiceConnection = new SC(); 2405c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mBound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); 2415c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "mBound: " + mBound); 2425c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } catch (Throwable t) { 2435c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock Log.w(mTag, "Error binding to service: " + mServiceName, t); 2445c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2455c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (!mBound) { 2465c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mCallbacks.onNoService(); 2475c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2485c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2495c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 2505c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private void serviceDisconnected(ComponentName serviceName) { 2515c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "serviceDisconnected serviceName=" + serviceName 2525c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock + " mServiceName=" + mServiceName); 2535c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (serviceName.equals(mServiceName)) { 2545c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mBound = false; 2555c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock scheduleCheckBound(); 2565c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2575c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2585c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 2595c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private void checkBound() { 2605c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (mDebug) Log.d(mTag, "checkBound mBound=" + mBound); 2615c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (!mBound) { 2625c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock startService(); 2635c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2645c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2655c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 2665c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private void scheduleCheckBound() { 2675c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.removeMessages(MSG_CHECK_BOUND); 2685c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock mHandler.sendEmptyMessageDelayed(MSG_CHECK_BOUND, RECHECK_DELAY); 2695c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2705c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock 2715c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock private static String bundleToString(Bundle bundle) { 2725c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (bundle == null) return null; 2735c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock StringBuilder sb = new StringBuilder('{'); 2745c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock for (String key : bundle.keySet()) { 2755c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock if (sb.length() > 1) sb.append(','); 2765c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock Object v = bundle.get(key); 2775c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock v = (v instanceof String[]) ? Arrays.asList((String[]) v) : v; 2785c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock sb.append(key).append('=').append(v); 2795c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2805c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock return sb.append('}').toString(); 2815c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock } 2825c4541246c6a70f53552423dc35940386788bd5fJohn Spurlock} 283