Android汽车服务篇(一) CarService

这篇具有很好参考价值的文章主要介绍了Android汽车服务篇(一) CarService。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. 简介

        Android Automotive OS作为车载操作系统, 需要与车辆上其他的子系统互联互通. 

        Android Automotive OS 定义了标准的硬件抽象层HAL(Hardware Abstraction Layer)来规范各个子系统与Framework的调用接口, 并且通过CarService以及相关的Car API对上层应用提供标准编程接口.

        下文中我们把 Android Automotive OS 简称为AAOS 

         AAOS并没有大刀阔斧的改变Android原有的整体架构, 几乎所有的核心服务(AMS, WMS, PKMS)与手机并无区别,采用的是同一套代源码,   所以我们可以将AAOS 理解为Android OS + Android Automotive Services更为贴切.

        传统的手机系统加上相关的汽车服务,构成了现在的AAOS, 而其中CarService就是提供汽车相关功能的最主要的模块.

        本文重点来介绍一下 CarService , 也就是 Android 汽车服务.

二. CarService的组成

        对于应用来说,并不会直接通过以上服务的实例调用相关功能,而是通过对应的Car API完成对服务的调用, 做过Android开发的,肯定都知道安卓的通信模式基于 C/S模式,  有客户端,服务端, ,每个服务有对应的代理对象(比如ActivityManager相对服务AMS,就是客户端 ,  PackageManager相对服务 PKMS, 它就是客户端).

          作为 AAOS的核心进程, 谷歌在CarService中实现了许多与汽车密切相关的服务, 我们大致列举一下子服务,  同理每个汽车服务, 也会有自己对应的客户端, 表格如下(非完整):

 Service端 功能 Client端
AppFocusService 管理同类应用焦点的服务 CarAppFocusManager
CarAudioService 汽车音频服务 CarAudioManager
CarPackageManagerService 汽车包管理服务 CarPackageManager
CarDiagnosticService 汽车诊断服务 CarDiagnosticManager
CarPowerManagerService 汽车电源管理服务 CarPowerManager
IInstrumentClusterNavigaiton 仪表导航服务
IInstrumentClusterManagerServcie 仪表服务 IInstrumentClusterManager
CarProjecitonService 投屏服务 CarProjecitonManager
VmsSubscriberService 车辆地图服务 VmsSubscriberManager
CarBluetoothService 汽车蓝牙服务 CarBluetoothManager
CarStorageMonitoringService 汽车存储监控服务 CarStorageMonitoringManager
CarDrivingStateService 汽车驾驶状态服务 CarDrivingStateManager
CarUXRestrictionsService 汽车用户体验限制服务 CarUXRestrictionsManager
CarConfigurationService 汽车配置服务 CarConfigurationManager
CarTrustedDeviceService 授信设备管理 CarTrustAgentEnrollmentManager
CarMediaService 媒体管理服务 CarMediaManager
CarBugreportManagerService 错误报告服务 CarBugreportManager

[备注]:aosp的版本一直在更新, 服务也是越来越多, 笔者只列举了部分出来. 供参考

从命名上还是比较容易将上述对象与相关的服务对应起来, 比较特殊的是 CarInfoManager, 

CarSensorManager,   CarHvacManager,   CarCabinManager, CarVendor-ExtensionManager以及CarPropertyManager都是对应 CarPropertyService.  这个服务后面文章也会详细介绍的

三. CarService启动流程

        了解CarService的主要组成后, 我们再来看看CarService的启动流程,  看看它在启动过程中做了些什么事情, 作为 AAOS的核心服务, CarService需要始终在后台运行, 并在在系统启动的早期进行创建.  时序图:

        Android汽车服务篇(一) CarService

细节代码如下:

/frameworks/base/services/java/com/android/server/SystemServer.java

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

然后跳转到SystemServiceManager.java文件中的startService方法

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        try {
            serviceClass = (Class<SystemService>)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            Slog.i(TAG, "Starting " + className);
            throw new RuntimeException("Failed to create service " + className
                    + ": service class not found, usually indicates that the caller should "
                    + "have called PackageManager.hasSystemFeature() to check whether the "
                    + "feature is available on this device before trying to start the "
                    + "services that implement it", ex);
        }
        return startService(serviceClass);
    }

 public <T extends SystemService> T startService(Class<T> serviceClass) {

     final String name = serviceClass.getName();
     ....
      try {     //注释1
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
     ....
     startService(service);
     return service;
...
}

public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            //注释2 启动CarService
            service.onStart();
.....
}

注释1处,  通过SystemServiceManager封装的方法来创建服务, 此处SystemServiceManager通过反射创建了CarServiceHelperService对象, 并调用其onStart方法, 进入到CarServiceHelperService.java文件中

public void onStart() {
        Intent intent = new Intent();
        intent.setPackage("com.android.car");
        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");
    }

注释二处   在onStart方法中, 创建了一个Intent    设置包名 和 Action  并调用bindServiceAsUser创建和绑定关联CarService,  同时加载了相关的JNI库(car-framework-service-jni).

通过以上的源码片段, 我们知道Intent的目标包名为"com.android.car", action为"android.car.ICar",  源码全局搜索与之相匹配的Service   

packages/services/Car/service/src/com/android/car/CarService.java

<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">



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

 通过上述流程, CarService在系统启动的早期就会随其他服务一同启动, 它的启动时机与 LocationManagerService/NotificationManagerService/WallpaperManagerService是一致的. 

从这点来说,CarService具有和其他系统主要服务有同等的地位, 不同的是 CarService是在独立的进程中运行, 而其他的服务运行在 SystemServer进程.

另一方面,从CarService的清单文件中可以看出, CarService使用的 system UID运行, 这也保证CarService拥有系统服务所具有的特性和权限.

除此之外, AAOS汽车服务的主要功能实现都集中在CarService中, 与Android原有的 Framework在源码上的耦合比较小, 在源码管理上, CarService的源码以单独的仓库进行管理.

下面来通过一个简单的架构示意图说明CarService与Android原有的系统服务之间的关系:CarService运行在独立的进程中. 其作为原有Android服务的补充,在汽车设备上运行

Android汽车服务篇(一) CarService

                                                                  AAOS 架构图

四. CarService源码分析

        当服务启动之后, 首先调用其onCreate方法.  CarService的onCreate方法实现如下:

 @Override
    public void onCreate() {
        Log.i(CarLog.TAG_SERVICE, "Service onCreate");
        //获取通知管理NotificationManager对象
        mCanBusErrorNotifier = new CanBusErrorNotifier(this /* context */);
        mVehicle = getVehicle();

        if (mVehicle == null) {
            throw new IllegalStateException("Vehicle HAL service is not available.");
        }
        try {
            mVehicleInterfaceName = mVehicle.interfaceDescriptor();
        } catch (RemoteException e) {
            throw new IllegalStateException("Unable to get Vehicle HAL interface descriptor", e);
        }

        Log.i(CarLog.TAG_SERVICE, "Connected to " + mVehicleInterfaceName);

        mICarImpl = new ICarImpl(this,
                mVehicle,
                SystemInterface.Builder.defaultSystemInterface(this).build(),
                mCanBusErrorNotifier,
                mVehicleInterfaceName);
        mICarImpl.init();

        linkToDeath(mVehicle, mVehicleDeathRecipient);

        ServiceManager.addService("car_service", mICarImpl);
        //设置SystemProperty属性  carService已创建
        SystemProperties.set("boot.car_service_created", "1");
        super.onCreate();
    }

主要做了两件事情:

1.  获取mVehicle 车辆相关的HIDL Binder远程对象;

2. 创建了mICarImpl对象, 并将其添加到ServiceManager管理的服务列表中.

这里的 ICarImpl起着创建并管理各个服务的作用. 在它的构造函数中,创建了各个服务的实例,并添加到服务列表中,源码如下:

packages/services/Car/service/src/com/android/car/ICarImpl.java

public ICarImpl(Context serviceContext, IVehicle vehicle, SystemInterface systemInterface,
            CanBusErrorNotifier errorNotifier, String vehicleInterfaceName) {
        mContext = serviceContext;
        mSystemInterface = systemInterface;
        mHal = new VehicleHal(vehicle);
        mVehicleInterfaceName = vehicleInterfaceName;
        //创建各种重要的服务
        mUserManagerHelper = new CarUserManagerHelper(serviceContext);
        final Resources res = mContext.getResources();
        final int maxRunningUsers = res.getInteger(
                com.android.internal.R.integer.config_multiuserMaxRunningUsers);
        mCarUserService = new CarUserService(serviceContext, mUserManagerHelper,
                ActivityManager.getService(), maxRunningUsers);
        mSystemActivityMonitoringService = new SystemActivityMonitoringService(serviceContext);
        mCarPowerManagementService = new CarPowerManagementService(mContext, mHal.getPowerHal(),
                systemInterface, mUserManagerHelper);
        mCarPropertyService = new CarPropertyService(serviceContext, mHal.getPropertyHal());
        ....
        
        //将重要的服务缓存到 CarLocalServices
        CarLocalServices.addService(CarPowerManagementService.class, mCarPowerManagementService);
        CarLocalServices.addService(CarUserService.class, mCarUserService);
        CarLocalServices.addService(CarTrustedDeviceService.class, mCarTrustedDeviceService);


         // 将创建的服务对象依次添加到一个list中保存起来
         List<CarServiceBase> allServices = new ArrayList<>();
         allServices.add(mFeatureController);
         allServices.add(mCarUserService);

.....
}

这些创建的服务就是上文介绍的汽车服务. 

五. Car API 使用方式

        在上面的介绍中,我们提到CarService中各个服务本质上是AIDL接口的实现类,属于Server端,而对应的Client端就需要一个IBinder对象来访问Server端的方法,这些IBinder对象在Car API中被封装在一个个XXXManager类中。

 5.1  编译 Car API

        在使用Car API之前,我们需要先将Car API编译成jar也就是CarLib,这样才能让其它的系统应用使用, 命令如下:

make android.car android.car-system-stubs android.car-stubs

编译成功后的 android.car.jar  的输出路径为:

/out/soong/.intermediates/packages/services/Car/car-lib/android.car/android_common/javac/android.car.jar

5.2  使用 Car API

Car API 的使用并不复杂,大致有以下几个步骤

1. 首先,通过Car.createCar 创建 Car对象

if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
    Car carClient = Car.createCar(context, mCarServiceConnection);
}

通过getPackageManager().hasSystemFeature(String string)判断系统是否支持特定的模块功能

其中需要传入ServiceConnection对象, 在CarService成功连接后,收到相应的回调, 如果ServiceConnection的onServiceConnected被回调,则说明连接成功了, 便可以获取相应的服务了.

private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
            try {
                CarInfoManager manager = (CarInfoManager) carClient.getCarManager(Car.INFO_SERVICE);
            } catch (CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in onServiceConnected");
            }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }
};

2.  构建出Car对象后还需要调用connect()才会连接到CarService上.

carClient.connect();

[注意事项]connect()只能调用一次,如果当前已经处于连接状态,再次调用connect()会抛出异常,client如果没有捕获该异常,则会引起client端程序crash.

@Deprecated
public void connect() throws IllegalStateException {
    synchronized (mLock) {
        if (mConnectionState != STATE_DISCONNECTED) {
            throw new IllegalStateException("already connected or connecting");
        }
        mConnectionState = STATE_CONNECTING;
        startCarService();
    }
}

3. 除了需要连接服务,还需要在不使用CarService的时候解绑服务,  通过disconnect方法释放资源:

carClient.disconnect();

上面3个步骤是在(<=Android9)之前的使用方法, 在Android10后, 获取Car对象的方法被大大简化了

应用不必在连接并接受回调后才能使用Car API, 这意味着获取 Car Manager对象的方法可以同步而非异步执行.

android10 以后获取Car对象的方法:

if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
    Car carClient = Car.createCar(context);
    CarHvacManager manager = (CarHvacManager) carClient.getCarManager(Car.HVAC_SERVICE);
}

六. 总结

        本文主要说明了CarService这一系统服务的启动流程,以及一些关键成员的创建和初始化流程.

        同时简单介绍了一下客户端是如何获取和使用CarService对象, 如上文介绍的, CarService对象只是获取各个Manager的媒介,它本身并不承担管理传感器.空调等具体的任务.

        如果要获取车辆的相关信息,如车速, 车内空调温度,诊断信息, 或对车辆进行相关的控制,如升高和降低空调温度,控制座椅和车窗, 调节音量等,就要通过具体的Manager中的API和对应的服务来实现了.文章来源地址https://www.toymoban.com/news/detail-508401.html

到了这里,关于Android汽车服务篇(一) CarService的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于SpringBoot+微信小程序汽车服务系统的设计与实现

    早晨四点起来,开发个基于SpringBoot+微信小程序汽车服务系统。 困死我了。 送完孩子,然后去上班。 昨天有个读者朋友问小孟:程序员之间的差距为何如此之大。 有时候甚至在同一所大学,同一个专业,有的学生大四毕业可以拿到四五十w的年薪,有的学生毕业找不到工作。

    2024年02月03日
    浏览(55)
  • 汽车贴膜店展示服务预约小程序的作用是什么

    很多家庭都有车辆,除了车身自带颜色或外观,部分消费者会选择贴车衣、改色膜以及其它装饰类服务;而市场高需求下也促进了商家生意增长。 但随着线上化程度加深,传统线下门店也面临多重困境,品牌需要线上发展获得生意及内容宣传等。 那么通过【 雨科 】平台制作

    2024年02月06日
    浏览(50)
  • python上海汽车服务商家数据可视化系统设计与实现(django框架)

     博主介绍 :黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程,免费 项目配有对应开发文档、开题报告、任务书、

    2024年02月03日
    浏览(44)
  • 基于“互联网+ 服务供应链”的汽车道路救援系统对策分析

    1。 建立“互联网+服务供应链”背景下汽车道路救援系统 基于互联网的汽车道路救援,两级服务供应链结构是由服务提供商、服务 集成商和客户组成。“互联网+服务供应链”背景下汽车道路救援系统组成, 它是一种 B2B2C 的形式,与前述传统汽车道路救援 B2B2C 模式有所不同

    2024年02月10日
    浏览(42)
  • 某汽车金融企业:搭建SDLC安全体系,打造智慧金融服务样本

    某汽车金融企业是国内头部汽车金融公司,已经为超过数百万名客户提供专业的汽车金融服务。该公司通过近几年的数字化创新,在提升客户体验、提高管理效率、降低经营成本等方面已具备很强的服务能力,让客户获得更方便、更快捷、更灵活的金融服务。 发力线上汽车金

    2024年02月05日
    浏览(45)
  • VR汽车技术服务虚拟仿真实训平台更好地辅助职业上岗培训

    VR汽车虚拟仿真教学软件是一种基于虚拟现实技术的教学辅助工具。它能够模拟真实的汽车环境和操作场景,让学生能够通过虚拟仿真来学习和实践汽车相关知识和技能。 与传统的教学方式相比,VR汽车虚拟仿真教学软件具有更高的视觉沉浸感和互动性,能够更好地激发学生

    2024年02月04日
    浏览(47)
  • 通俗易懂实现功能强大的实战项目 springboot+java+vue+mysql 汽车服务管理系统

    ✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 | SpringBoot/SSM Python实战项目 | Django 微信小

    2024年01月16日
    浏览(40)
  • 东莞UG逆向建模设计汽车内外饰出stp图抄数3d造型建模代画图服务

    汽车内外饰三维扫描及逆向建模是一项复杂且技术性强的工程。它涉及到使用高精度的三维扫描仪对汽车内外饰进行全面、细致的扫描,获取其精确的三维数据。这个过程中,需要确保扫描的环境、光线、角度等因素对扫描结果的影响最小化,以保证获取的三维数据准确无误

    2024年01月24日
    浏览(50)
  • 如何在本地服务器部署TeslaMate并远程查看特斯拉汽车数据无需公网ip

    TeslaMate是一个开源软件,可以通过连接特斯拉账号,记录行驶历史,统计能耗、里程、充电次数等数据。用户可以通过web界面查看车辆状态、行程报告、充电记录等信息,并生成漂亮的图表和统计报告。 另外,TeslaMate也可以记录车子所有的位置、轨迹、速度、温度、海拔、续

    2024年02月21日
    浏览(47)
  • 【Android R】车载 Android 核心服务 - CarService 解析

    在之前的文章从应用工程师的角度再谈车载 Android 系统中提到了\\\" CarService 是车载Android系统的核心服务之一,所有应用都需要通过 CarService 来查询、控制整车的状态\\\",不仅仅是车辆控制,实际上 CarService 几乎就是整个车载Framework最核心的组件,这也让 CarService 成了各种bug的重

    2023年04月19日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包