'차량 보안'에 해당되는 글 3건

https://wizzie.top/carservice/android_carservice_structureAndInit/

 

Android carservice架构及启动流程

文档内容:carservice架构介绍,内容有Car APP、Car API、Car Service等部分,carservice启动流程

wizzie.top

 

1. 설명영구 링크

1.1. 그림영구 링크

Google은 上介绍汽车架构:

车载HAL是汽车与车辆网络服务之间的接义义(同时保护传入的数据) :

车载HAL은 Android Automotive架构:

  • 자동차 앱: 包括OEM 와 第 3 方开发 의 앱
  • Car API: CarSensorManager가 API에 있습니다.位于/platform/packages/services/Car/car-lib
  • CarService: 系统中与车상식적인 교통수단, 位于/플랫폼/패키지/서비스/Car/
  • 차량 HAL: 하드웨어/인터페이스/자동차/차량/2.0/default/(하드웨어/인터페이스/자동차/차량/2.0/default/impl/vhal_v2_0/)

1.1.1. 프레임워크 CarService영구 링크

기계적 인조 인간 O/P는 자동차가 HAL을 사용하는 차량HAL통신으로 사용됩니다. ,进而过车载总线(例如CAN总线)与车身进行讯,同时它们还为应사용 가능한 앱은 从而让APP과 같은 앱입니다.

  • 자동차***매니저:packages/services/Car/car-lib/src/android/car/hardware
  • 자동차***서비스:packages/services/Car/service/src/com/android/car/

1.2. 앱스토어영구 링크

1.2.1. APP层确认是否支持车载功能영구 링크

  1. 이전에 앱을 사용하는 Car API가 Car API를 사용하여 실행되었습니다.
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
    .....
}

예:

//packages/apps/SettingsIntelligence/src/com/android/settings/intelligence/suggestions/eligibility/AutomotiveEligibilityChecker.java
    public static boolean isEligible(Context context, String id, ResolveInfo info) {
        PackageManager packageManager = context.getPackageManager();
        //是否支持车载功能
        boolean isAutomotive = packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
        //是否有车载功能支持的资格
        boolean isAutomotiveEligible =
                info.activityInfo.metaData.getBoolean(META_DATA_AUTOMOTIVE_ELIGIBLE, false);
        if (isAutomotive) {
            if (!isAutomotiveEligible) {
                Log.i(TAG, "Suggestion is ineligible for FEATURE_AUTOMOTIVE: " + id);
            }
            return isAutomotiveEligible;
        }
        return true;
    }
//frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
    @GuardedBy("mAvailableFeatures")
    final ArrayMap<String, FeatureInfo> mAvailableFeatures;

    @Override
    public boolean hasSystemFeature(String name, int version) {
        // allow instant applications
        synchronized (mAvailableFeatures) {
            final FeatureInfo feat = mAvailableFeatures.get(name);
            if (feat == null) {
                return false;
            } else {
                return feat.version >= version;
            }
        }
    }
  1. 일반적으로 Binder访问PackageManagerService,mAvailableFeatures리면적 内容是통로过读取/system/etc/permissions하단 XML 문서(对应SDK적 位置—프레임워크/네이티브/데이터/etc아래 XML 문서 중 기능 字段)
//frameworks/native/data/etc/car_core_hardware.xml
<permissions>
    <!-- Feature to specify if the device is a car -->
    <feature name="android.hardware.type.automotive" />
    .....
</permission>
//frameworks/native/data/etc/android.hardware.type.automotive.xml
<!-- These features determine that the device running android is a car. -->
<permissions>
    <feature name="android.hardware.type.automotive" />
</permissions>

1.2.2. APP创建Car API, 接收底层回调영구 링크

자동차 제작은 平台最高等级的API( packages/services/Car/car-lib/src/android/car/Car.java), 为外界提供汽车所有服务와数据的访问

  1. CommunicrecreateCar 방법으로 새로운 Car实例
  2. 통신 연결 방식 CarService
  3. 当成功连接时可以通过getCarManagermethod获取一个一个相关的manager, 比如Hvaccommunication过get CarManager 방법을 사용하면 CarHvacManager, 当获取到manager后就可以进行以操作

HvacController.java의 예:

//packages/apps/Car/Hvac/src/com/android/car/hvac/HvacController.java
  private Object mHvacManagerReady = new Object();

 @Override
    public void onCreate() {
        super.onCreate();
        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
            if (SystemProperties.getBoolean(DEMO_MODE_PROPERTY, false)) {
                IBinder binder = (new LocalHvacPropertyService()).getCarPropertyService();
                initHvacManager(new CarHvacManager(binder, this, new Handler()));
                return;
            }
            //创建Car实例,即new Car对象
            mCarApiClient = Car.createCar(this, mCarConnectionCallback);
            //connect连接,调用startCarService启动CarService
            mCarApiClient.connect();
        }
    }

    private final CarConnectionCallback mCarConnectionCallback =
            new CarConnectionCallback() {
                @Override
                public void onConnected(Car car) {
                    synchronized (mHvacManagerReady) {
                        try {
                            //getCarManager获取manager
                            //在获取到CarHvacManager后,可以直接调用CarHvacManager提供的接口
                            //例如mHvacManager.getPropertyList();
                            initHvacManager((CarHvacManager) mCarApiClient.getCarManager(
                                    android.car.Car.HVAC_SERVICE));
                            mHvacManagerReady.notifyAll();
                        } catch (CarNotConnectedException e) {
                            Log.e(TAG, "Car not connected in onServiceConnected");
                        }
                    }
                }

                @Override
                public void onDisconnected(Car car) {
                }
            };

    private void initHvacManager(CarHvacManager carHvacManager) {
        mHvacManager = carHvacManager;
        List<CarPropertyConfig> properties = null;
        try {
            properties = mHvacManager.getPropertyList();
            mPolicy = new HvacPolicy(HvacController.this, properties);
            //注册回调
            mHvacManager.registerCallback(mHardwareCallback);
        } catch (android.car.CarNotConnectedException e) {
            Log.e(TAG, "Car not connected in HVAC");
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mHvacManager != null) {
            //取消注册回调
            mHvacManager.unregisterCallback(mHardwareCallback);
        }
        if (mCarApiClient != null) {
            mCarApiClient.disconnect();
        }
    }

    //接收处理callback消息
    private final CarHvacManager.CarHvacEventCallback mHardwareCallback =
            new CarHvacManager.CarHvacEventCallback() {
                @Override
                public void onChangeEvent(final CarPropertyValue val) {
                    int areaId = val.getAreaId();
                    switch (val.getPropertyId()) {
                        case CarHvacManager.ID_ZONED_AC_ON:
                            handleAcStateUpdate(getValue(val));
                            break;
                        case CarHvacManager.ID_ZONED_FAN_DIRECTION:
                            handleFanPositionUpdate(areaId, getValue(val));
                        .....
                        default:
                            if (Log.isLoggable(TAG, Log.DEBUG)) {
                                Log.d(TAG, "Unhandled HVAC event, id: " + val.getPropertyId());
                            }
                    }
                }

                @Override
                public void onErrorEvent(final int propertyId, final int zone) {
                }
            };

예를 들어 라디오 앱의 RadioTunerExt.java文件:

//packages/apps/Car/Radio/src/com/android/car/radio/platform/RadioTunerExt.java
    RadioTunerExt(Context context) {
        //创建Car实例,即new Car对象
        mCar = Car.createCar(context, mCarServiceConnection);
        //connect连接,调用startCarService启动CarService
        mCar.connect();
    }

    private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            synchronized (mLock) {
                try {
                    //getCarManager获取manager
                    mCarAudioManager = (CarAudioManager)mCar.getCarManager(Car.AUDIO_SERVICE);
                    if (mPendingMuteOperation != null) {
                        boolean mute = mPendingMuteOperation;
                        mPendingMuteOperation = null;
                        Log.i(TAG, "Car connected, executing postponed operation: "
                                + (mute ? "mute" : "unmute"));
                        setMuted(mute);
                    }
        .....

2. 목차영구 링크

2.1. CarService一级目录结构说明( packages/services/Car/)영구 링크

목차:packages/services/Car/

.
├── Android.mk
├── apicheck.mk
├── apicheck_msg_current.txt
├── apicheck_msg_last.txt
├── car-cluster-logging-renderer    //LoggingClusterRenderingService继承InstrumentClusterRenderingService
├── car-default-input-service   //按键消息处理
├── car-lib         //提供给汽车App特有的接口,许多定制的模块都在这里实现,包括Sensor,HVAC,Cabin,ActiveParkingAssiance,Diagnostic,Vendor等
├── car-maps-placeholder    //地图软件相关
├── car_product         //系统编译相关
├── car-support-lib     //android.support.car
├── car-systemtest-lib  //系统测试相关
├── car-usb-handler     //开机自启,用于管理车机USB
├── CleanSpec.mk
├── evs  
├── obd2-lib
├── PREUPLOAD.cfg
├── procfs-inspector
├── service    //com.android.car是一个后台运行的组件,可以长时间运行并且不需要和用户去交互的,这里即使应用被销毁,它也可以正常工作
├── tests
├── tools   //是一系列的工具,要提到的是里面的emulator,测试需要用到的。python写的,通过adb可以连接vehicleHal的工具,用于模拟测试
├── TrustAgent
└── vehicle-hal-support-lib

2.2. 자동차 APP영구 링크

  • packages/services/Car/car_product/build/car.mk里面决정了是否编译상关apk(system/priv-app)
  • 출처 위치::packages/apps/Car/

这个文件中列了汽车系统中的专有模块(首字母大写的模块基本上書是汽车系统中专유있는 앱) :

//packages/services/Car/car_product/build/car.mk
# Automotive specific packages
PRODUCT_PACKAGES += \
    CarService \
    CarTrustAgentService \
    CarDialerApp \                      # 电话应用,包含拨号键盘、通话记录等
    CarRadioApp \                       # 收音机应用
    OverviewApp \
    CarLauncher \
    CarLensPickerApp \                  # 活动窗口选择应用(Launcher)
    LocalMediaPlayer \                  # 提供本地播放服务的应用
    CarMediaApp \                       # 媒体应用,包含播放界面等
    CarMessengerApp \                   # 消息管理应用,包含消息及TTS相关功能
    CarHvacApp \                        # 空调应用,空调显示及操作界面
    CarMapsPlaceholder \
    CarLatinIME \                       # 输入法应用
    CarSettings \                       # 设置应用
    CarUsbHandler \
    android.car \
    car-frameworks-service \
    com.android.car.procfsinspector \
    libcar-framework-service-jni \
....
PRODUCT_PACKAGES += \
    Bluetooth \
    OneTimeInitializer \
    Provision \
    SystemUI \
    SystemUpdater                       # 系统升级应用

2.3. 자동차 API영구 링크

  • 源码位置: /platform/packages/services/Car/car-lib,因为对手机와 平板没有의미 义,仅用于开发汽车,所以没有包含在Framework SDK中

자동차 API(详细路径: packages/services/Car/car-lib/src/android/car/)유如下:

자동차 API 분류:


2.4. 차량 서비스영구 링크

  • 출처 위치:packages/services/Car/

CarServcie模块与很多模块city需要交互(供参考):

  • 向上给APP提供API接口;
  • 向下与MCU进行信,进而와车身网络进行交互;
  • 给其他模块提供标项信息;
  • 给Camera模块提供Digital RVC控等信息等;
  • 可以获取DSP版本、前屏版本号等;
  • 持有Power模块的锁,carservice挂了就会息屏


2.5. AIDL영구 링크

Android는 Android에서 사용하기로 결정했습니다.

如要使用 AIDL 创建绑定服务,请执行以下步骤:

  1. 创建.aidl文件:此文件定义带유방법签名的编程接口
  2. 개발자:Android SDK工具会基于您的.aidl文件,使用Java编程语言生成接口。此接口拥有一个name为Stub的内部抽象类, 用于扩见Binder类并实现AIDL接口中的方法您必须扩Stub类并实现这些방법
  3. 向客户端公开接口,实现Service并写onBind(),从而返回Stub类的实现

2.5.1. 예를 들어 ICarInputListener영구 링크

  1. AIDL문서:
    //packages/services/Car/car-lib/src/android/car/input/ICarInputListener.aidl
    /**
     * Binder API for Input Service.
     *
     * @hide
     */
    oneway interface ICarInputListener {
     /** Called when key event has been received. */
     void onKeyEvent(in KeyEvent keyEvent, int targetDisplay) = 1;
    }
    
  2. 같은 종류의 AIDL接口中的内部抽象类Stub
//packages/services/Car/car-lib/src/android/car/input/CarInputHandlingService.java
    private class InputBinder extends ICarInputListener.Stub {
        private final EventHandler mEventHandler;

        InputBinder() {
            mEventHandler = new EventHandler(CarInputHandlingService.this);
        }

        @Override
        public void onKeyEvent(KeyEvent keyEvent, int targetDisplay) throws RemoteException {
            mEventHandler.doKeyEvent(keyEvent, targetDisplay);
        }
    }
  1. 客户端调사용 服务端적 지원

추신:如果需要返回对象则需要实现Service.onBind(Intent)방법, 该方法会返回一个IBinder对象到客户端

//packages/services/Car/service/src/com/android/car/CarInputService.java
    private final ServiceConnection mInputServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            if (DBG) {
                Log.d(CarLog.TAG_INPUT, "onServiceConnected, name: "
                        + name + ", binder: " + binder);
            }
            mCarInputListener = ICarInputListener.Stub.asInterface(binder);

            try {
                binder.linkToDeath(() -> CarServiceUtils.runOnMainSync(() -> {
                    Log.w(CarLog.TAG_INPUT, "Input service died. Trying to rebind...");
                    mCarInputListener = null;
                    // Try to rebind with input service.
                    mCarInputListenerBound = bindCarInputService();
                }), 0);
            } catch (RemoteException e) {
                Log.e(CarLog.TAG_INPUT, e.getMessage(), e);
            }
        }

2.6. carservice 작동 흐름 과정영구 링크

대진류과정:

  1. SystemServer는 CarServiceHelperService를 지원합니다.
  2. 여기에서 사용되는 startService后, CarServiceHelperService의 onStart 방법을 통해 bindService의 방법은 CarService(一个系统级别의 APK, 位于system/priv-app)입니다.
  3. 启动CarService后首先调사용 onCreate, 创建ICarImpl对象并初始化, 에서 此时创建了一系列car상형核心服务, 并遍历init初始化
  4. onBind에 사용되는 Bind将该ICarImpl对象返回给CarServiceHelperService,CarServiceHelperService는 Binder에서 사용되는 1个Binder对象ICarServiceHelperImpl传递给CarService,建立双向跨进程

2.6.1. 설명서영구 링크

2.6.2. CarServiceHelperService 서비스영구 링크

frameworks/base/services/java/com/android/server/SystemServer.java - run() —-> startOtherServices()

    private static final String CAR_SERVICE_HELPER_SERVICE_CLASS =
            "com.android.internal.car.CarServiceHelperService";
            ......
            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
                traceBeginAndSlog("StartCarServiceHelperService");
                mSystemServiceManager.startService(CAR_SERVICE_HELPER_SERVICE_CLASS);
                traceEnd();
            }

—–> frameworks/base/services/core/java/com/android/server/SystemServiceManager.java - startService

    @SuppressWarnings("unchecked")
    public SystemService startService(String className) {
        ....
        return startService(serviceClass);
    }

    public <T extends SystemService> T startService(Class<T> serviceClass) {
        ...
        startService(service);
        ...
    }

    public void startService(@NonNull final SystemService service) {
        ......
        try {
            service.onStart();
            ...
        }

2.6.3. Carservice 서비스 정의영구 링크

—–> 프레임워크/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java - onStart()

    //这就是系统中和汽车相关的核心服务CarService,相关源代码在packages/services/Car/service目录下
    private static final String CAR_SERVICE_INTERFACE = "android.car.ICar";

    @Override
    public void onStart() {
        Intent intent = new Intent();
        intent.setPackage("com.android.car");  //绑定包名,设置广播仅对该包有效
        //绑定action,表明想要启动能够响应设置的这个action的活动,并在清单文件AndroidManifest.xml中设置action属性
        intent.setAction(CAR_SERVICE_INTERFACE);
        //绑定后回调
        if (!getContext().bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
                UserHandle.SYSTEM)) {
            Slog.wtf(TAG, "cannot start car service");
        }
        System.loadLibrary("car-framework-service-jni");
    }
  • service源码路径:packages/services/Car/service/AndroidManifest.xml

sharedUserId는 类似SystemUI, 它编译出来同样是一个 APK文件

설계 문서 경로 위치:/system/priv-app/CarService/CarService.apk

//packages/services/Car/service/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
        package="com.android.car"
        coreApp="true"
        android:sharedUserId="android.uid.system"> 
        ......
<application android:label="Car service"
                 android:directBootAware="true"
                 android:allowBackup="false"
                 android:persistent="true">
        <service android:name=".CarService"
                android:singleUser="true">
            <intent-filter>
                <action android:name="android.car.ICar" />
            </intent-filter>
        </service>
        <service android:name=".PerUserCarService" android:exported="false" />
    </application>

2.6.4. BindService 서비스 제공영구 링크

context.bindService() ——> onCreate() ——> onBind() ——> Service running ——> onUnbind() ——> onDestroy() ——> Service stop

onBind()는 IBind를 사용하여 IBind를 실행합니다.服务时候把调 이용자 ( Context, 例如Activity)는 会 화 서비스 결정에서 1 起, Context 退 了, 서비스 就会调사용 onUnbind-> onDestroy 와 같습니다.

所以调사용bindService의 생활은 다음과 같습니다.onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestroy

Service每一次的开启关闭过程中,只有onStart可被多次调사용 (통계다次startService调용),其他onCreate,onBind,onUnbind,onDestroy재일个生命周期中只能被调사용일次


2.7. 자동차 서비스영구 링크

2.7.1. 생성중영구 링크

——–> 패키지/서비스/Car/service/src/com/android/car/CarService.java - onCreate()

ICarImpl 실사 제작

    @Nullable
    private static IVehicle getVehicle() {
        try {
            //该service启动文件hardware/interfaces/automotive/vehicle/2.0/default/android.hardware.automotive.vehicle@2.0-service.rc
            return android.hardware.automotive.vehicle.V2_0.IVehicle.getService();
        } ....
        return null;
    }

    @Override
    public void onCreate() {
        Log.i(CarLog.TAG_SERVICE, "Service onCreate");
        //获取hal层的Vehicle service
        mVehicle = getVehicle();

        //创建ICarImpl实例
        mICarImpl = new ICarImpl(this,
                mVehicle,
                SystemInterface.Builder.defaultSystemInterface(this).build(),
                mCanBusErrorNotifier,
                mVehicleInterfaceName);
        //然后调用ICarImpl的init初始化方法
        mICarImpl.init();
        //设置boot.car_service_created属性
        SystemProperties.set("boot.car_service_created", "1");

        linkToDeath(mVehicle, mVehicleDeathRecipient);
        //最后将该service注册到ServiceManager
        ServiceManager.addService("car_service", mICarImpl);
        super.onCreate();
    }
//packages/services/Car/service/src/com/android/car/ICarImpl.java
    private final VehicleHal mHal;
    //构造函数启动一大堆服务
    public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
            CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) {
        mContext = serviceContext;
        mSystemInterface = systemInterface;
        //创建VehicleHal对象
        mHal = new VehicleHal(vehicle);
        mVehicleInterfaceName = vehicleInterfaceName;
        mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
        mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(),
                systemInterface);
        mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal());
        .....
        //InstrumentClusterService service启动
        mInstrumentClusterService = new InstrumentClusterService(serviceContext,
                mAppFocusService, mCarInputService);
        mSystemStateControllerService = new SystemStateControllerService(serviceContext,
                mCarPowerManagementService, mCarAudioService, this);
        mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext);
        // mCarBluetoothService = new CarBluetoothService(serviceContext, mCarPropertyService,
        //        mPerUserCarServiceHelper, mCarUXRestrictionsService);
        mVmsSubscriberService = new VmsSubscriberService(serviceContext, mHal.getVmsHal());
        mVmsPublisherService = new VmsPublisherService(serviceContext, mHal.getVmsHal());
        mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal());
        mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext,
                systemInterface);
        mCarConfigurationService =
                new CarConfigurationService(serviceContext, new JsonReaderImpl());
        mUserManagerHelper = new CarUserManagerHelper(serviceContext);

        //注意排序,service存在依赖
        List<CarServiceBase> allServices = new ArrayList<>();
        allServices.add(mSystemActivityMonitoringService);
        allServices.add(mCarPowerManagementService);
        allServices.add(mCarPropertyService);
        allServices.add(mCarDrivingStateService);
        allServices.add(mCarUXRestrictionsService);
        allServices.add(mCarPackageManagerService);
        allServices.add(mCarInputService);
        allServices.add(mCarLocationService);
        allServices.add(mGarageModeService);
        allServices.add(mAppFocusService);
        allServices.add(mCarAudioService);
        allServices.add(mCarNightService);
        allServices.add(mInstrumentClusterService);
        allServices.add(mCarProjectionService);
        allServices.add(mSystemStateControllerService);
        // allServices.add(mCarBluetoothService);
        allServices.add(mCarDiagnosticService);
        allServices.add(mPerUserCarServiceHelper);
        allServices.add(mCarStorageMonitoringService);
        allServices.add(mCarConfigurationService);
        allServices.add(mVmsSubscriberService);
        allServices.add(mVmsPublisherService);

        if (mUserManagerHelper.isHeadlessSystemUser()) {
            mCarUserService = new CarUserService(serviceContext, mUserManagerHelper);
            allServices.add(mCarUserService);
        }

        mAllServices = allServices.toArray(new CarServiceBase[allServices.size()]);
    }

    @MainThread
    void init() {
        traceBegin("VehicleHal.init");
        mHal.init();
        traceEnd();
        traceBegin("CarService.initAllServices");
        //启动的所有服务遍历调用init初始化(各个都继承了CarServiceBase)
        for (CarServiceBase service : mAllServices) {
            service.init();
        }
        traceEnd();
    }

2.7.2. 바인딩에 대한영구 링크

상단 화면의 mICarImpl 생성:

  1. onBind()를 사용하는 방법은 BindService()를 사용하여 의도적으로 사용하는 bindServiceAsUser방법입니다.
  2. onUnbind()는 unbindService()의 의도를 고려하여 서비스를 정의합니다.
//packages/services/Car/service/src/com/android/car/CarService.java
    @Override
    public IBinder onBind(Intent intent) {
        return mICarImpl;
    }

所以此处的mICarImpl会제작为IBinder返回给CarServiceHelperService.java - bindServiceAsUser방법중의 参数mCarServiceConnection (回调)

2.7.3. 파괴시영구 링크

mICarImpl이 제공하는 기능은 다음과 같습니다.

    @Override
    public void onDestroy() {
        Log.i(CarLog.TAG_SERVICE, "Service onDestroy");
        mICarImpl.release();
        mCanBusErrorNotifier.removeFailureReport(this);

        if (mVehicle != null) {
            try {
                mVehicle.unlinkToDeath(mVehicleDeathRecipient);
                mVehicle = null;
            } catch (RemoteException e) {
                // Ignore errors on shutdown path.
            }
        }

        super.onDestroy();
    }

2.8. ServiceConnection을 반환합니다.영구 링크

ICarImpl初始化完毕,会作为IBinder返回给CarServiceHelperService.java - bindServiceAsUser方法中绑定此服务的mCarServiceConnection(回调)

mCarServiceConnection初始化如下:

  1. CarServiceHelperService의 mCarService에서 ICarImpl을 사용할 수 있습니다.
  2. mCarService.transact는 ICar.aidl을 사용하는 통합 솔루션 setCarServiceHelper를 사용합니다.
//frameworks/opt/car/services/src/com/android/internal/car/CarServiceHelperService.java
private static final String CAR_SERVICE_INTERFACE = "android.car.ICar";
private IBinder mCarService;
private final ICarServiceHelperImpl mHelper = new ICarServiceHelperImpl();

private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Slog.i(TAG, "**CarService connected**");
            //1. 返回的ICarImpl被保存在了CarServiceHelperService的mCarService
            mCarService = iBinder;
            // Cannot depend on ICar which is defined in CarService, so handle binder call directly
            // instead. 
            // void setCarServiceHelper(in IBinder helper)
            Parcel data = Parcel.obtain();
            data.writeInterfaceToken(CAR_SERVICE_INTERFACE);
            //将ICarServiceHelperImpl类型的对象作为数据跨进程传递
            data.writeStrongBinder(mHelper.asBinder());
            try {
                //2.跨进程传输
                //对端是mCarService即ICarImpl,调用binder的transact进行跨进程通信
                //其code代表需要调用的对端方法,data为携带的传输数据
                //FIRST_CALL_TRANSACTION  = 0x00000001,即调用对端ICar.aidl中定义的第一个方法setCarServiceHelper
                mCarService.transact(IBinder.FIRST_CALL_TRANSACTION, // setCarServiceHelper
                        data, null, Binder.FLAG_ONEWAY);
            } catch (RemoteException e) {
                Slog.w(TAG, "RemoteException from car service", e);
                handleCarServiceCrash();
            }
        }

        @Override 
        public void onServiceDisconnected(ComponentName componentName) {
            handleCarServiceCrash();
        }
    };

2.9. 跨进程setCarServiceHelper영구 링크

    @Override
    public void setCarServiceHelper(IBinder helper) {
        int uid = Binder.getCallingUid();
        if (uid != Process.SYSTEM_UID) {
            throw new SecurityException("Only allowed from system");
        }
        synchronized (this) {
            //将ICarServiceHelper的代理端保存在ICarImpl内部mICarServiceHelper
            mICarServiceHelper = ICarServiceHelper.Stub.asInterface(helper);
            //同时也传给了SystemInterface
            //此时他们有能力跨进程访问CarServiceHelperService
            mSystemInterface.setCarServiceHelper(mICarServiceHelper);
        }
    }

3. 참고영구 링크

Android Automotive용 CarService 서비스

深入理解Android의 시작 서비스와 바인딩 서비스

안드로이드와 자동차

안드로이드 O CarService

Java 주석(Annotation)

Google 공식 문서 - AIDL

AIDL 단방향 以及in, out,inout参数의 논리

Android AIDL사용법 알아보기

일구气从零读懂CAN总线

本地进程间通信——Unix域套接字

'차량 보안' 카테고리의 다른 글

ISO 21434 CAL Level  (0) 2023.06.29
Car Hacking Training  (0) 2023.05.18
블로그 이미지

wtdsoul

,

ISO 21434 CAL Level

차량 보안 2023. 6. 29. 14:15

https://www.autoelectronics.co.kr/article/articleView.asp?idx=4655 

 

ISO 21434 통한 실질적 사이버 보안 대응

Vector가 작성한 이 기사는 ISO 21434에 따른 체계적인 보안 엔지니어링에 대해 설명하고 있으며 ISO 21434의 효율적인 구현을 위한 글로벌 프로젝트의 실제 사례 소개한다.

www.autoelectronics.co.kr

ISO 21434를 통한 실질적인 보안 엔지니어링 

다음 사례는 ISO 21434가 실제로 어떻게 단계적으로 적용되는지 보여준다. 사례 연구는 첨단 운전자 지원 시스템 (Advanced Driver Assistance Systems, ADAS) 프로젝트에서 가져온 것으로 기사의 형식에 맞게 단순화하였다.

1단계: 아이템 정의 
아이템 정의는 구성 요소의 범위를 정의하기 위해 필요하다. 정의된 범위는 시스템의 자산을 식별하기 위한 참조로 사용된다. 이 예에서 아이템은 넓은 의미에서 전체 ADAS 시스템을 말한다. 최상위 네트워크 아키텍처는 그림 3과 같으며, CAN 프로토콜을 통해 모든 통신이 이루어진다고 가정한다. 외부 인터페이스는 기본 아키텍처를 기반으로 식별된다. 이 시스템은 4G 네트워크를 통해 OEM 클라우드 인프라와 통신할 수 있는 기능이 있으며 게이트웨이 모듈에 연결된 OBD 단자가 있다.




그림 3 | ADAS 네트워크 아키텍처의 예



2단계: 자산 식별 
다음 단계는 아이템 범위에 속한 모든 자산을 나열하는 것이다. 자산은 예를 들어 기능 안전 목표, 재정적 위험, 운영 비용 및 개인 정보 보호와 같이 손상될 때의 위험 또는 가치를 기반으로 선택된다. 다음은 ADAS 시스템의 자산(Asset, A) 예이다.

- A1: ADAS가 송수신하는 네트워크 메시지
- A2: 안전 메커니즘을 포함한 ADAS 소프트웨어
- A3: 보안 키
- A4: 운전 이력 및 기록 데이터

3단계: 위협 분석 및 위험 평가(Threat analysis and risk assessment, TARA) 
식별된 자산을 기반으로 다음 단계인 TARA를 수행한다. TARA는 자산이 위협에 의해 사이버 공격을 받았을 경우에 대해 피해 시나리오의 영향 등급과 공격 가능성 등급을 체계적으로 평가하여 위험 수준을 1(매우 낮음)에서 5(매우 높음)까지의 척도로 결정한다. 나아가 결정된 위험 수준에 따라 위험 처리 조치를 계획하고 실행할 수 있다. ISO 21434는 CAL1(낮음)에서 CAL4(높음)까지 모든 위협에 대해 사이버 보안 보증 수준(Cybersecurity assurance level, CAL) 적용을 선택적으로 제안한다. 다음은 피해 시나리오(Damage Scenario, DS)에 대한 몇 가지 예이다.

- A1-DS1: 추돌 상황에서 운전자가 브레이크 페달을 밟아도 차량이 멈추지 않음
- A2-DS2: 자율 주행에서 수동 전환 시 차선 변경이 안되어 차선 변경 실패로 인한 사고 발생

이를 기반으로 위협(Threat, T)을 식별하며 다음과 같다.

- A1-DS1-T1: 제동 메시지 송수신 서비스 거부(DOS) 로 인해 제동 제어기가 제동을 수행하지 않음.
- A2-DS2-T2: ADAS 조향 SW가 변경되어 오염된 SW로 인해 ADAS 수동 전환 기능이 동작하지 않음. 

표 1은 공격 가능성 등급과 영향 등급을 보여준다. 위에서 식별된 자산과 피해 시나리오를  기반으로 위협을 평가하여 위험 수준과 CAL을 산출하였다.




표 1  | TARA 분석의 예



4단계: 사이버 보안 목표 및 사이버 보안 요구 사항 
위험을 완화하기 위해 사이버 보안 목표를 식별하고 효과에 따라 평가한다. 사이버 보안 목표는 최상위 수준의 사이버 보안 요구 사항이다. 각 사이버 보안 목표로부터 하나 이상의 사이버 보안 요구사항들이 도출되고, 모든 사이버 보안 요구사항에 대해 하나 이상의 기술적 사이버 보안 요구사항이 도출된다. 이 예에서는 다음과 같다.

- 사이버 보안 목표(Cybersecurity Goal, SG) A1-T1-SG1 
   시스템은 운전자 지원 시스템에서 보낸 메시지가 조작되는 것을 방지해야 한다.
- 사이버 보안 요구 사항(Cybersecurity Req., SeR) SG1-SeR1 
   운전자 지원과 센서 간의 통신 무결성이 보장되어야 한다.
- 기술 사이버 보안 요구 사항(Technical Cybersecurity Req., TSeR) SG1-SeR1-TSeR1 
   메시지 인증 코드 (MAC)은 RSA2048 알고리즘을 사용하여 SHE(Secure Hardware Extension)와 호환되는 HTA(Hardware Trust Anchor)로 계  산되어야 한다.
- 기술 사이버 보안 요구 사항(Technical Cybersecurity Req., TSeR) SG1-SeR1-TSeR2
   MAC은 x바이트로 줄인 형태로 사용한다.

5단계: 추적성 
추적성은 일관성을 유지하고 위험부담을 완화하는 데 도움이 된다. 변경 사항이 발생하고 지속적인 빌드 활동 중에도 적용범위와 일관성을 보장하는 데 필수적이다.
그림 4는 요구사항을 설계와 테스트에 연결시키는 추상화 모델을 보여준다. 한 예로, 부정적인 요구 사항, 즉 해커가 공격하기 위해 필요한 내용을 분석하고, 이로부터 해당 공격의 실현 가능성을 낮추기 위한 솔루션을 도출한다. 이것은 초기 TARA 및 보안 요구 사항 정의에서 완전한 추적성을 보장한다.




그림 4 | 삼중 피크 추상화모델에서 사이버 보안의 추적성



6단계: 설계  
ADAS 시스템은 자산에 대해 TARA에서 발견된 위험 때문에 설계 변경을 필요로 한다. 사이버 보안 목표 SG1은 시스템이 네트워크 신호의 조작을 막기 위해 탐지 및 방지 메커니즘을 갖추고 있어야 한다는 점을 강조한다. 사이버 보안 개념을 기반으로 하여 탐지 및 방지 메커니즘을 설계할 수 있다.

이로 인해 하드웨어 설계도 변경해야 할 수 있다. 이 사례연구의 경우 HTA를 사용해야 한다. 소프트웨어의 경우MISRA 및 CERT 지침을 통한 보안 코딩은 보안 악용으로 이어질 수 있는 설계와 코드상의 오류를 방지하기 위해 적용한다. 대부분의 공격은 부적절한 설계로 인해 발생한다는 점을 항상 염두에 두어야 한다.

7단계: 통합 및 검증 
이 단계에서의 주된 목표는 통합 구현된 보안 메커니즘이 사이버 보안 목표 및 요구 사항을 충족하는지 확인하는 것이다. 다음은 일반적으로 사이버 보안 검증 및 확인을 위해 권장되는 방법들이다.

- 단위 수준 검증: 정적 및 동적 코드 품질 분석은 단위 수준에서의 강건성과 함께 MISRA 및 CERT와 같은 보안 코딩 지침에 중점을 둔다. 자동화 도구는 코드 품질 분석(Code Quality Analysis, CQA)을 수행하고 테스트 보고서를 생성하는 데 사용한다.

- 기능 테스트: 요구 사항을 기반으로 하는 테스트는 시스템 설계 및 아키텍처의 기본적 결함을 식별하는 데 도움이 될 수 있다. 이 예에서 아이템의 정의 부분에서 설명한 실제 기능은 추가적인 보안 조치로 인해 기능의 성능이 손상되지 않았음을 시스템 차원에서 테스트한다.
- 퍼지 테스트: 퍼지 테스트는 예상 범위와 영역을 넘어서는 다양한 차량 통신 프로토콜을 테스트하는 데 사용된다.
- 침투 테스트: 침투 테스트는 구성 요소 및 시스템 차원에서 독립적으로 수행되는 테스트 전략이다. Gray Box Penetration Test[5]라는 테스트방식이 높은 효율성과 효과를 보여 이에 적합함이 입증되었다.

8단계: 개발 후 단계 
유지보수 및 업데이트 관리는 제품 개발 과정 중에 준비되어야 한다. 여기에는 제품의 생산, 일반적인 운영 및 유지 관리, 그리고 마지막으로 폐기까지 포함된다. 사고 대응, 보안 경고 알림, 소프트웨어 패치와 배포 같은 활동을 위해 예산, 시간, 인력을 확보해야 한다. 이를 몇 가지 단계로 나누어 볼 수 있다.

- 생산: 제품을 제조하고 조립하는 동안 여러 사이버 보안 요구 사항을 준수해야 한다. 예를 들어, 최종 생산라인에서 HTA의 메모리에 공급업체 또는 OEM 관련 암호 키 재료를 투입하는 것을 계획하고 처리해야 한다.
- 운영 및 유지보수: 모든 조직은 지속적인 사이버 보안 활동의 일환으로 프로젝트와는 독립된 모니터링 조직을 운영할 필요가 있다. 조직은 사이버 보안 이벤트가 발생했을 때 미리 정의하고 합의한 사이버 보안 사고 대응 계획에 따라 보안 사고를 처리해야 한다.
- 폐기: 제품 폐기시에 사이버 보안과 관련된 정보가 여전이 포함되어 있을 수 있으므로 이를 위한 폐기 단계에서의 절차 등에 대해 고려가 필요하다. 


결론  

차량 내에 IT 제품의 개발과, 생산 및 운영 분야의 기업 IT가 융합되면서 자동차 사이버 보안은 큰 연계성을 얻게 되었다[1, 2, 3, 4]. 이는 자동차 기능 안전을 위한 전제 조건이며 이해하기 쉽고 체계적으로 구현되어야 한다. ISO 21434는 자동차 사이버 보안을 위한 기본적인 지침으로, 이를 위한 프레임워크를 제공한다. 그러나 이를 실제 개발 프로세스로 정의할 때 있는 그대로 가져다 쉽게 적용할 수 있는 것은 아니다. ISO 21434를 효과적이고 효율적으로 구현하기 위해서는 전문적인 경험과 가이드가 필요하다. 이는 특히 차량 법규(UNECE R.155 CSMS)와 관련하여 나중에 그 효과가 입증되어야 하는 경우에 더욱 그렇다.

사이버 보안은 단지 보안 관련 조직 뿐만 아니라 제품의 수명 주기와 관련된 모든 관련자들의 책임이다. 깊이 있는 시스템 엔지니어링부터 시작하여 전체 제품 수명 주기 동안 관리되고 추적할 수 있는 총체적인 접근 방식이 필요하다.

출처: AEM (https://www.autoelectronics.co.kr)

'차량 보안' 카테고리의 다른 글

Android car service (펌)  (0) 2025.02.09
Car Hacking Training  (0) 2023.05.18
블로그 이미지

wtdsoul

,

Car Hacking Training

차량 보안 2023. 5. 18. 09:45

'차량 보안' 카테고리의 다른 글

Android car service (펌)  (0) 2025.02.09
ISO 21434 CAL Level  (0) 2023.06.29
블로그 이미지

wtdsoul

,