返回

发布服务与获取服务——publishBinderService 和 getService

Android

在 Framework 中使用 AIDL 服务,其发布和获取是两个重要方法,本文尝试探究其源码的实现。

我们知道手机在开机过程中,会启动一个 ServiceManger 的服务,它就是服务的大管家。AIDL 服务的发布和获取过程,其实就是与 ServiceManger 进行交互的过程。

1. AIDL 服务的发布

AIDL 服务的发布,需要用到 publishBinderService 方法,该方法的实现位于 frameworks/base/services/core/java/com/android/server/SystemServer.java 文件中。

public void publishBinderService(String serviceName, Service service) {
    publishBinderService(serviceName, service, false);
}

public void publishBinderService(String serviceName, Service service, boolean allowisolated) {
    if (service == null) {
        Slog.w(TAG, "trying to publish null service for " + serviceName);
        return;
    }

    synchronized (this) {
        if (mServices != null) {
            Log.wtf(TAG, "Attempt to publish already published service: " + serviceName);
            return;
        }

        mServices = new ServiceManager();
    }

    String name = check farbServiceName(serviceName);
    if (name == null) {
        return;
    }

    if (allowisolated) {
        service.setIsolated(true);
    }
    try {
        getServiceManagerLocked().addService(name, service);
    } catch (SecurityException ex) {
        Log.e(TAG, "Could not add service " + serviceName + " due to security exception", ex);
        return;
    }
    if (service.isDeclaredIsolated()) {
        // Hack to make sure isolated services always start up,
        // regardless of if anyone is currently bound to them.

        if (DBG) Log.d(TAG, "Scheduling isolated service " + serviceName + " to start");
        scheduleForSafeShutdown(serviceName, service);
    } else if (DBG) {
        Log.d(TAG, "Published service: " + serviceName);
    }
}

这个方法主要做了以下几件事:

  1. 创建一个 ServiceManager 对象,如果已经存在则直接使用。
  2. 对服务名称进行检查,如果服务名称为空或者已经存在则直接返回。
  3. 设置服务的属性,比如是否允许被其他进程访问。
  4. 把服务添加到 ServiceManger 中。
  5. 调用 scheduleForSafeShutdown 方法,如果服务被声明为独立服务,则将其调度到安全关闭。

2. AIDL 服务的获取

AIDL 服务的获取,需要用到 getService 方法,该方法的实现位于 frameworks/base/services/core/java/com/android/server/ServiceManager.java 文件中。

public IBinder getService(String name) {
    synchronized (this) {
        ServiceBinder s = mServices.get(name);
        if (s != null) {
            return s.getBinder();
        }
        if ("activity".equals(name)) {
            return IActivityManager.Stub.asInterface(
                    this.mLocalActivityManager);
        } else if ("power".equals(name)) {
            return IPowerManager.Stub.asInterface(this.mPowerManager);
        } else if ("window".equals(name)) {
            return IWindowManager.Stub.asInterface(this.mWindowManager);
        } else if ("search".equals(name)) {
            return ISearchManager.Stub.asInterface(
                    this.mSearchManager);
        } else if ("statusbar".equals(name)) {
            return IStatusBarService.Stub.asInterface(
                    this.mStatusBarManager);
        } else if ("input".equals(name)) {
            return IInputManager.Stub.asInterface(this.mInputManager);
        } else if ("mount".equals(name)) {
            return IMountService.Stub.asInterface(
                    this.mMountService);
        } else if ("adb".equals(name)) {
            return IAdbService.Stub.asInterface(
                    this.mAdbService);
        } else if ("wallpaper".equals(name)) {
            return IWallpaperManager.Stub.asInterface(
                    this.mWallpaperManager);
        } else if ("uimode".equals(name)) {
            return IUimodeManager.Stub.asInterface(
                    this.mUiModeManager);
        } else if ("battery".equals(name)) {
            return IBatteryStats.Stub.asInterface(this.mBatteryStats);
        } else if ("vibrator".equals(name)) {
            return IVibratorService.Stub.asInterface(
                    this.mVibratorService);
        } else if ("permission".equals(name)) {
            return IPermissionService.Stub.asInterface(
                    this.mPermissionService);
        } else if ("location".equals(name)) {
            return ILocationManager.Stub.asInterface(
                    this.mLocationManager);
        } else if ("sound".equals(name)) {
            return IAudioService.Stub.asInterface(this.mAudioService);
        } else if ("wifi".equals(name)) {
            return IWifiService.Stub.asInterface(this.mWifiService);
        } else if ("net".equals(name)) {
            return IConnectivityService.Stub.asInterface(
                    this.mConnectivityService);
        } else if ("phone".equals(name)) {
            return ITelephonyRegistry.Stub.asInterface(
                    this.mTelephonyRegistry);
        } else if ("telephony".equals(name)) {
            return ITelephony.Stub.asInterface(this.mTelephony);
        } else if ("clipboard".equals(name)) {
            return IClipboard.Stub.asInterface(this.mClipboard);
        } else if ("textservices".equals(name)) {
            return ITextServicesManager.Stub.asInterface(
                    this.mTextServicesManager);
        } else if ("nfc".equals(name)) {
            return INfcService.Stub.asInterface(this.mNfcService);
        } else if ("bluetooth".equals(name)) {
            return IBluetooth.Stub.asInterface(this.mBluetoothService);
        } else if ("companiondevicemanager".equals(name)) {
            return ICompanionDeviceManager.Stub.asInterface(
                    this.mCompanionDeviceManager);
        } else if ("context_hub".equals(name)) {
            return IContextHubService.Stub.asInterface(this.mContextHubService);
        } else if ("dropbox".equals(name)) {
            return IDrop revertedBoxManager.Stub.asInterface(
                    this.mDropBoxManager);
        } else if ("usage_stats".equals(name)) {
            return IUsageStatsService.Stub.asInterface(
                    this.mUsageStatsService);
        } else if ("app_identity".equals(name)) {
            return IAppIdentityService.Stub.asInterface(
                    this.mAppIdentityService);
        } else if ("wifi_p2p".equals(name)) {
            return IWifiP2pService.Stub.asInterface(this.mWifiP2pService);
        } else if ("serial".equals(name)) {
            return ISerialService.Stub.asInterface(this.mSerialService);
        } else if ("usb".equals(name)) {
            return IUsbManager.Stub.asInterface(this.mUsbManager);
        } else if ("tetheringservice".equals(name)) {
            return ITethering.Stub.asInterface(this.mTethering);
        } else if ("ota_package".equals(name)) {
            return IOtaPackageService.Stub.asInterface(
                    this.mPackageManagerService);
        } else if ("recovery".equals(name)) {
            return IRecoverySystem.Stub.asInterface(this.mRecoverySystem);
        } else if ("data_usage".equals(name)) {
            return IDataUsageService.Stub.asInterface(
                    this.mDataUsageService);
        } else if ("ota_package_installer".equals(name)) {
            return IOtaPackageInstallaer.Stub.asInterface(this.mPackageManagerService);
        } else if ("network_stats".equals(name)) {
            return INetworkStatsService.Stub.asInterface(this.mNetworkStatsService);
        } else if ("app_ops