【内核研究】ServiceManager管理的服务

来源:互联网 发布:国内量化交易软件 编辑:程序博客网 时间:2024/06/03 21:32

系统服务中的Binder对象

在应用程序编程时,经常使用getSystemService(String serviceName)方法获取一个系统服务,那么,这些系统服务的Binder引用是如何传递给客户端的呢?须知系统服务并不是通过startService()启动的。

getSystemService()函数的实现是在ContextImpl类中,该函数所返回的Service比较多,具体可参照源码。这些Service一般都由ServiceManager管理。

@Override    public Object getSystemService(String name) {        if (WINDOW_SERVICE.equals(name)) {            return WindowManagerImpl.getDefault();        } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {            synchronized (mSync) {                LayoutInflater inflater = mLayoutInflater;                if (inflater != null) {                    return inflater;                }                mLayoutInflater = inflater =                    PolicyManager.makeNewLayoutInflater(getOuterContext());                return inflater;            }        } else if (ACTIVITY_SERVICE.equals(name)) {            return getActivityManager();        } else if (INPUT_METHOD_SERVICE.equals(name)) {            return InputMethodManager.getInstance(this);        } else if (ALARM_SERVICE.equals(name)) {            return getAlarmManager();        } else if (ACCOUNT_SERVICE.equals(name)) {            return getAccountManager();        } else if (POWER_SERVICE.equals(name)) {            return getPowerManager();        } else if (CONNECTIVITY_SERVICE.equals(name)) {            return getConnectivityManager();        } else if (THROTTLE_SERVICE.equals(name)) {            return getThrottleManager();        } else if (WIFI_SERVICE.equals(name)) {            return getWifiManager();        } else if (NOTIFICATION_SERVICE.equals(name)) {            return getNotificationManager();        } else if (KEYGUARD_SERVICE.equals(name)) {            return new KeyguardManager();        } else if (ACCESSIBILITY_SERVICE.equals(name)) {            return AccessibilityManager.getInstance(this);        } else if (LOCATION_SERVICE.equals(name)) {            return getLocationManager();        } else if (SEARCH_SERVICE.equals(name)) {            return getSearchManager();        } else if (SENSOR_SERVICE.equals(name)) {            return getSensorManager();        } else if (STORAGE_SERVICE.equals(name)) {            return getStorageManager();        } else if (VIBRATOR_SERVICE.equals(name)) {            return getVibrator();        } else if (STATUS_BAR_SERVICE.equals(name)) {            synchronized (mSync) {                if (mStatusBarManager == null) {                    mStatusBarManager = new StatusBarManager(getOuterContext());                }                return mStatusBarManager;            }        } else if (AUDIO_SERVICE.equals(name)) {            return getAudioManager();        } else if (TELEPHONY_SERVICE.equals(name)) {            return getTelephonyManager();        } else if (CLIPBOARD_SERVICE.equals(name)) {            return getClipboardManager();        } else if (WALLPAPER_SERVICE.equals(name)) {            return getWallpaperManager();        } else if (DROPBOX_SERVICE.equals(name)) {            return getDropBoxManager();        } else if (DEVICE_POLICY_SERVICE.equals(name)) {            return getDevicePolicyManager();        } else if (UI_MODE_SERVICE.equals(name)) {            return getUiModeManager();        } else if (DOWNLOAD_SERVICE.equals(name)) {            return getDownloadManager();        } else if (NFC_SERVICE.equals(name)) {            return getNfcManager();        }        return null;    }
    // activity manager    private ActivityManager getActivityManager() {        synchronized (mSync) {            if (mActivityManager == null) {                mActivityManager = new ActivityManager(getOuterContext(),                        mMainThread.getHandler());            }        }        return mActivityManager;    }    // alarm manager    private AlarmManager getAlarmManager() {        synchronized (sSync) {            if (sAlarmManager == null) {                IBinder b = ServiceManager.getService(ALARM_SERVICE);                IAlarmManager service = IAlarmManager.Stub.asInterface(b);                sAlarmManager = new AlarmManager(service);            }        }        return sAlarmManager;    }

ServiceManager管理的服务

ServiceManager是一个独立进程,其作用如名称所示,管理各种系统服务,管理的逻辑如下所示。

ServiceManager
AlarmServiceInputMethodManagerServiceVibrationServiceAccountManagerServiceWIFIServiceLOcationService...

ServiceManager本身也是一个Service,Framework提供了一个系统函数,可以获取该Service对应的Binder引用,那就是BinderInternal.getContextObject()。该静态函数返回ServiceManager后,就可以通过ServiceManager提供的方法获取其他系统Service的Binder引用。这种设计模式在日常生活中到处可见,ServiceManager就像是一个公司的总机,这个总机号码是公开的,系统中任何进程都可以使用BinderInternal.getContextObject()获取该总机的Binder对象,而当用户想联系公司中的其他人(服务)时,则要经过总机再获得分机号码。这种设计的好处是系统中仅暴露一个全局Binder引用,那就是ServiceManager,而其他系统服务则可以隐藏起来,从而有助于系统服务的扩展,以及调用系统服务的安全检查。其他系统服务在启动时,首先把自己的Binder对象传递给ServiceManager,即所谓的注册(addService)。

下面从代码实现来看以上逻辑。可以查看ContextImpl.getSystemService()中各种Service的具体获取方式,比如INPUT_METHOD_SERVICE,代码如下:

 } else if (INPUT_METHOD_SERVICE.equals(name)) {            return InputMethodManager.getInstance(this);        }

而InputMethodManager.getInstance(this)的关键代码如下:

    /**     * Retrieve the global InputMethodManager instance, creating it if it     * doesn't already exist.     * @hide     */    static public InputMethodManager getInstance(Context context) {        return getInstance(context.getMainLooper());    }
    /**     * Internally, the input method manager can't be context-dependent, so     * we have this here for the places that need it.     * @hide     */    static public InputMethodManager getInstance(Looper mainLooper) {        synchronized (mInstanceSync) {            if (mInstance != null) {                return mInstance;            }            IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);            IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);            mInstance = new InputMethodManager(service, mainLooper);        }        return mInstance;    }

即通过ServiceManager获取InputMethod Service对应的Binder对象b,然后再将该Binder对象作为IInputMethodManager.Stub.asInterface()的参数,返回一个IInputMethodManager的统一接口。

ServiceManager.getService()的代码如下:

/**     * Returns a reference to a service with the given name.     *      * @param name the name of the service to get     * @return a reference to the service, or <code>null</code> if the service doesn't exist     */    public static IBinder getService(String name) {        try {            IBinder service = sCache.get(name);            if (service != null) {                return service;            } else {                return getIServiceManager().getService(name);            }        } catch (RemoteException e) {            Log.e(TAG, "error in getService", e);        }        return null;    }

即首先从sCache缓存中查看是否有对应的Binder对象,有则返回,没有则调用getIServiceManager().getService(name),第一个函数getIServiceManager()即用于返回系统中唯一的ServiceManager对应的Binder,其代码如下:

    private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // Find the service manager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());        return sServiceManager;    }

以上代码中,BinderInternal.getContextObject()静态函数即用于返回ServiceManager对应的全局Binder对象,该函数不需要任何参数,因为它的作用是固定的。从这个角度来看,这个函数的命名似乎更应该明确一些,比如,可以命名为getServiceManager()。

其他所有通过ServiceManager获取的系统服务的过程与以上基本类似,所不同的就是传递给ServiceManager的服务名称不同,因为ServiceManager正是按照服务的名称(String类型)来保存不同的Binder对象的。

关于使用addService()向ServiceManager中添加一个服务一般是在SystemService进程启动时完成的,具体见关于Framework启动过程的描述。


系统服务列表

    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.os.PowerManager} for controlling power management,     * including "wake locks," which let you keep the device on while     * you're running long tasks.     */    public static final String POWER_SERVICE = "power";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.view.WindowManager} for accessing the system's window     * manager.     *     * @see #getSystemService     * @see android.view.WindowManager     */    public static final String WINDOW_SERVICE = "window";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.view.LayoutInflater} for inflating layout resources in this     * context.     *     * @see #getSystemService     * @see android.view.LayoutInflater     */    public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.accounts.AccountManager} for receiving intents at a     * time of your choosing.     *     * @see #getSystemService     * @see android.accounts.AccountManager     */    public static final String ACCOUNT_SERVICE = "account";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.app.ActivityManager} for interacting with the global     * system state.     *     * @see #getSystemService     * @see android.app.ActivityManager     */    public static final String ACTIVITY_SERVICE = "activity";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.app.AlarmManager} for receiving intents at a     * time of your choosing.     *     * @see #getSystemService     * @see android.app.AlarmManager     */    public static final String ALARM_SERVICE = "alarm";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.app.NotificationManager} for informing the user of     * background events.     *     * @see #getSystemService     * @see android.app.NotificationManager     */    public static final String NOTIFICATION_SERVICE = "notification";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.view.accessibility.AccessibilityManager} for giving the user     * feedback for UI events through the registered event listeners.     *     * @see #getSystemService     * @see android.view.accessibility.AccessibilityManager     */    public static final String ACCESSIBILITY_SERVICE = "accessibility";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.app.NotificationManager} for controlling keyguard.     *     * @see #getSystemService     * @see android.app.KeyguardManager     */    public static final String KEYGUARD_SERVICE = "keyguard";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.location.LocationManager} for controlling location     * updates.     *     * @see #getSystemService     * @see android.location.LocationManager     */    public static final String LOCATION_SERVICE = "location";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.app.SearchManager} for handling searches.     *     * @see #getSystemService     * @see android.app.SearchManager     */    public static final String SEARCH_SERVICE = "search";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.hardware.SensorManager} for accessing sensors.     *     * @see #getSystemService     * @see android.hardware.SensorManager     */    public static final String SENSOR_SERVICE = "sensor";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.os.storage.StorageManager} for accessing system storage     * functions.     *     * @see #getSystemService     * @see android.os.storage.StorageManager     */    public static final String STORAGE_SERVICE = "storage";    /**     * Use with {@link #getSystemService} to retrieve a     * com.android.server.WallpaperService for accessing wallpapers.     *     * @see #getSystemService     */    public static final String WALLPAPER_SERVICE = "wallpaper";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.os.Vibrator} for interacting with the vibration hardware.     *     * @see #getSystemService     * @see android.os.Vibrator     */    public static final String VIBRATOR_SERVICE = "vibrator";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.app.StatusBarManager} for interacting with the status bar.     *     * @see #getSystemService     * @see android.app.StatusBarManager     * @hide     */    public static final String STATUS_BAR_SERVICE = "statusbar";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.net.ConnectivityManager} for handling management of     * network connections.     *     * @see #getSystemService     * @see android.net.ConnectivityManager     */    public static final String CONNECTIVITY_SERVICE = "connectivity";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.net.ThrottleManager} for handling management of     * throttling.     *     * @hide     * @see #getSystemService     * @see android.net.ThrottleManager     */    public static final String THROTTLE_SERVICE = "throttle";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.net.NetworkManagementService} for handling management of     * system network services     *     * @hide     * @see #getSystemService     * @see android.net.NetworkManagementService     */    public static final String NETWORKMANAGEMENT_SERVICE = "network_management";    /**     * Use with {@link #getSystemService} to retrieve a {@link     * android.net.wifi.WifiManager} for handling management of     * Wi-Fi access.     *     * @see #getSystemService     * @see android.net.wifi.WifiManager     */    public static final String WIFI_SERVICE = "wifi";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.media.AudioManager} for handling management of volume,     * ringer modes and audio routing.     *     * @see #getSystemService     * @see android.media.AudioManager     */    public static final String AUDIO_SERVICE = "audio";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.telephony.TelephonyManager} for handling management the     * telephony features of the device.     *     * @see #getSystemService     * @see android.telephony.TelephonyManager     */    public static final String TELEPHONY_SERVICE = "phone";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.text.ClipboardManager} for accessing and modifying     * the contents of the global clipboard.     *     * @see #getSystemService     * @see android.text.ClipboardManager     */    public static final String CLIPBOARD_SERVICE = "clipboard";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.view.inputmethod.InputMethodManager} for accessing input     * methods.     *     * @see #getSystemService     */    public static final String INPUT_METHOD_SERVICE = "input_method";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.appwidget.AppWidgetManager} for accessing AppWidgets.     *     * @hide     * @see #getSystemService     */    public static final String APPWIDGET_SERVICE = "appwidget";    /**     * Use with {@link #getSystemService} to retrieve an     * {@link android.app.backup.IBackupManager IBackupManager} for communicating     * with the backup mechanism.     * @hide     *     * @see #getSystemService     */    public static final String BACKUP_SERVICE = "backup";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.os.DropBoxManager} instance for recording     * diagnostic logs.     * @see #getSystemService     */    public static final String DROPBOX_SERVICE = "dropbox";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.app.admin.DevicePolicyManager} for working with global     * device policy management.     *     * @see #getSystemService     */    public static final String DEVICE_POLICY_SERVICE = "device_policy";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.app.UiModeManager} for controlling UI modes.     *     * @see #getSystemService     */    public static final String UI_MODE_SERVICE = "uimode";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.app.DownloadManager} for requesting HTTP downloads.     *     * @see #getSystemService     */    public static final String DOWNLOAD_SERVICE = "download";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.nfc.NfcManager} for using NFC.     *     * @see #getSystemService     */    public static final String NFC_SERVICE = "nfc";    /**     * Use with {@link #getSystemService} to retrieve a     * {@link android.net.sip.SipManager} for accessing the SIP related service.     *     * @see #getSystemService     */    /** @hide */    public static final String SIP_SERVICE = "sip";


0 0
原创粉丝点击