CarService启动Cluster的过程分析

CarService启动Cluster的过程分析

基于Android 8.1系统源码

本文涉及到的源码路径:

packages/services/Car/car_product/build/car.mk

packages/services/Car/service/res/values/config.xml
packages/services/Car/service/src/com/android/car/CarService.java
packages/services/Car/service/src/com/android/car/ICarImpl.java
packages/services/Car/service/src/com/android/car/cluster/InstrumentClusterService.java

packages/services/Car/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/SampleClusterServiceImpl.java
packages/services/Car/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java

frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/services/core/java/com/android/server/car/CarServiceHelperService.java
SystemServer启动CarService

SystemServer里会启动CarServiceHelperService,如下:

            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
                traceBeginAndSlog("StartCarServiceHelperService");
                mSystemServiceManager.startService(CarServiceHelperService.class);
                traceEnd();
            }

CarServiceHelperService.onStart()会bind到CarService,如下:

        Intent intent = new Intent();
        intent.setPackage("com.android.car");
        intent.setAction(CAR_SERVICE_INTERFACE);	// "android.car.ICar"
        if (!context.bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
            Slog.wtf(TAG, "cannot start car service");
        }

注意:这里用的是bindService方式,mCarServiceConnection是ServiceConnection类对象,它能监听目标Service的状态,当目标Service所在进程异常退出时,会导致其onServiceDisconnected()方法被调用。

CarService启动ClusterActivity

CarService.onCreate()里会创建ICarImpl的实例,并调用ICarImpl.init()方法;

ICarImpl.init()里会启动一大堆Service,其中就包括InstrumentClusterService,如下:

        // Be careful with order. Service depending on other service should be inited later.
        List<CarServiceBase> allServices = new ArrayList<>(Arrays.asList(
                mSystemActivityMonitoringService,
                mCarPowerManagementService,
                //add ExtCarPowerManagementService
                mExtCarPowerManagementService,
                mCarSensorService,
                mCarPackageManagerService,
                mCarInputService,
                mGarageModeService,
                mCarInfoService,
                mAppFocusService,
                mCarAudioService,
                mCarCabinService,
                mCarHvacService,
                mCarRadioService,
                mCarNightService,
                mInstrumentClusterService,
                mCarProjectionService,
                mSystemStateControllerService,
                mCarVendorExtensionService,
                mCarBluetoothService,
                mCarDiagnosticService,
                mPerUserCarServiceHelper
        ));
        mAllServices = allServices.toArray(new CarServiceBase[0]);
    }

    public void init() {
        traceBegin("VehicleHal.init");
        mHal.init();
        traceEnd();
        traceBegin("CarService.initAllServices");
        for (CarServiceBase service : mAllServices) {
            service.init();
        }
        traceEnd();
    }

继续看InstrumentClusterService.init()方法,里面会调用bindInstrumentClusterRendererService()来bind到SampleClusterServiceImpl这个Service,如下:

    private boolean bindInstrumentClusterRendererService() {
        String rendererService = mContext.getString(R.string.instrumentClusterRendererService);
        if (TextUtils.isEmpty(rendererService)) {
            Log.i(TAG, "Instrument cluster renderer was not configured");
            return false;
        }

        Log.d(TAG, "bindInstrumentClusterRendererService, component: " + rendererService);

        Intent intent = new Intent();
        intent.setComponent(ComponentName.unflattenFromString(rendererService));
        Bundle extras = new Bundle();
        extras.putBinder(
                InstrumentClusterRenderingService.EXTRA_KEY_CALLBACK_SERVICE,
                mClusterCallback);
        intent.putExtras(extras);
        return mContext.bindService(intent, mRendererServiceConnection, Context.BIND_AUTO_CREATE);
    }

继续,SampleClusterServiceImpl.onCreate()方法里面在另一Display上启动了MainClusterActivity,如下:

        Display clusterDisplay = getInstrumentClusterDisplay(this);
        if (clusterDisplay == null) {
            Log.e(TAG, "Unable to find instrument cluster display");
            return;
        }
        
        ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchDisplayId(clusterDisplay.getDisplayId());
        Intent intent = new Intent(this, MainClusterActivity.class);
        intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent, options.toBundle());

我们再回头看下InstrumentClusterService.init().bindInstrumentClusterRendererService()这个方法,关注它在调用bindService()时的第二个参数mRendererServiceConnection

mRendererServiceConnectionServiceConnection类的实例,其源码如下:

    private final ServiceConnection mRendererServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            IInstrumentCluster service = IInstrumentCluster.Stub.asInterface(binder);

			// ...
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // Try to rebind with instrument cluster.
            mRendererBound = bindInstrumentClusterRendererService();
        }
    };

mRendererServiceConnection.onServiceDisconnected()里面,会重新调用bindInstrumentClusterRendererService()来rebind;也就是当SampleClusterServiceImpl挂掉时会重新启动它。

注:

  • R.string.instrumentClusterRendererService就是指的android.car.cluster.sample/.SampleClusterServiceImpl

    packages/services/Car/service/res/values/config.xml有:

    <string name="instrumentClusterRendererService">android.car.cluster.sample/.SampleClusterServiceImpl</string>
  • SampleClusterServiceImpl继承自InstrumentClusterRenderingService,所以它是一个Service;
  • InstrumentClusterService.bindInstrumentClusterRendererService()方法会bind这个SampleClusterServiceImpl
扩展

需要注意,CarService本质上是一个特殊的APP,在其AndroidManifest.xml里有:

        <service android:name=".CarService"
                android:singleUser="true">
            <intent-filter>
                <action android:name="android.car.ICar" />
            </intent-filter>
        </service>

即其核心是com.android.car/.CarService这个service;

它编译后生成CarService.apk;在真机上,它是在/system/priv-app/CarService/CarService.apk这里。

DirectRenderingClusterSample实质上也是一个APP,其主Activity是android.car.cluster.sample/.MainClusterActivity;还有个关键的Service即android.car.cluster.sample/.SampleClusterServiceImpl

需要注意的是,在packages/services/Car/car_product/build/car.mk里面决定了是否编译DirectRenderingClusterSample

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值