车载之-自定义系统服务

源码梳理

  • SystemServer的启动,SystemServer是由Zygote启动的。
   /**
     * The main entry point from zygote.
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }
  • 继续看run()方法,看关键代码,开启服务。
    startBootstrapServices主要是针对底层相关的服务;
    startCoreServices主要针对用户相关的服务;
    startOtherServices主要针对应用相关的服务,而对于我们应用的开发,百分之99都是修改此方法。
  private void run() {
...
  // Start services.
        try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }

...

}
  • 我们关注一下服务 的启动形式,我们进入startBootstrapServices方法内,我们发现规律,基本上服务都是由mSystemServiceManager.startService这个方法启动的。
 // Wait for installd to finish starting up so that it has a chance to
        // create critical directories such as /data/user with the appropriate
        // permissions.  We need this to complete before we initialize other services.
        traceBeginAndSlog("StartInstaller");
        Installer installer = mSystemServiceManager.startService(Installer.class);
        traceEnd();

        // In some cases after launching an app we need to access device identifiers,
        // therefore register the device identifier policy before the activity manager.
        traceBeginAndSlog("DeviceIdentifiersPolicyService");
        mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
        traceEnd();

        // Uri Grants Manager.
        traceBeginAndSlog("UriGrantsManagerService");
        mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
        traceEnd();
  • 并且启动的所有服务都是集成自SystemService这个类,例如:Installer,DeviceIdentifiersPolicyService,UriGrantsManagerService.Lifecycle等,其可以监听系统的启动流程
    其对于我们比较重要的方法有,onStart与onBootPhase方法。
    onStart在启动时回;
    onBootPhase在启动过程中回调,其携带的参数时SystemService中的常量,比如PHASE_WAIT_FOR_DEFAULT_DISPLAY,PHASE_LOCK_SETTINGS_READY,PHASE_SYSTEM_SERVICES_READY等。
    收到PHASE_ACTIVITY_MANAGER_READY消息,就可以做发送广播等操作。
    收到PHASE_THIRD_PARTY_APPS_CAN_START消息,其表示其启动第三方引用。
    收到PHASE_BOOT_COMPLETED表示应用程序与用户可以进行交互了。
//com.android.server.SystemService
    /**
     * Called when the dependencies listed in the @Service class-annotation are available
     * and after the chosen start phase.
     * When this method returns, the service should be published.
     */
    public abstract void onStart();
    
     /**
     * Called on each phase of the boot process. Phases before the service's start phase
     * (as defined in the @Service annotation) are never received.
     *
     * @param phase The current boot phase.
     */
    public void onBootPhase(int phase) {}


  • 还有设计比较巧妙的地方是,Java只支持单继承,而如果ActivityManagerService是需要进程间通讯的,需要集成Binder,这样就不能集成SystemService,所以其增加了内部类LifeCycle来创建ActivityManagerService,从而持有其实例。
    public static final class Lifecycle extends SystemService {
        private final ActivityManagerService mService;
        private static ActivityTaskManagerService sAtm;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityManagerService(context, sAtm);
        }

        public static ActivityManagerService startService(
                SystemServiceManager ssm, ActivityTaskManagerService atm) {
            sAtm = atm;
            return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
        }

        @Override
        public void onStart() {
            mService.start();
        }

        @Override
        public void onBootPhase(int phase) {
            mService.mBootPhase = phase;
            if (phase == PHASE_SYSTEM_SERVICES_READY) {
                mService.mBatteryStatsService.systemServicesReady();
                mService.mServices.systemServicesReady();
            } else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
                mService.startBroadcastObservers();
            } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
                mService.mPackageWatchdog.onPackagesReady();
            }
        }

        @Override
        public void onCleanupUser(int userId) {
            mService.mBatteryStatsService.onCleanupUser(userId);
        }

        public ActivityManagerService getService() {
            return mService;
        }
    }
  • 服务创建后需要将服务注册到ServiceManager中,调用ServiceManager.addService()方法进行注册。

    public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                    DUMP_FLAG_PRIORITY_HIGH);
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this),
                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            }
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));

            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                    "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

            synchronized (this) {
                ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                        false,
                        0,
                        new HostingRecord("system"));
                app.setPersistent(true);
                app.pid = MY_PID;
                app.getWindowProcessController().setPid(MY_PID);
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                mPidsSelfLocked.put(app);
                mProcessList.updateLruProcessLocked(app, false, null);
                updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }

        // Start watching app ops after we and the package manager are up and running.
        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
                new IAppOpsCallback.Stub() {
                    @Override public void opChanged(int op, int uid, String packageName) {
                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
                            if (mAppOpsService.checkOperation(op, uid, packageName)
                                    != AppOpsManager.MODE_ALLOWED) {
                                runInBackgroundDisabled(uid);
                            }
                        }
                    }
                });
    }

实践

  • 创建AIDL接口
/frameworks/base/core/java/android/app/IToolManager.aidl
//android.app
interfadce IToolManager{
		String handler();
}
  • 服务端
//frameworks/base/services/core/java/com/android/server/tool/ToolManagerService.java
package com.android.server.tool;

import android.app.IToolManager;
import android.os.RemoteException;


/**
 * 服务端   AMS PMS WMS
 */
public class ToolManagerService extends IToolManager.Stub {
    @Override
    public String request(String msg) throws RemoteException {
        return "ToolManagerService接收数据:"+msg;
    }
  • 客户端
//frameworks/base/core/java/android/app/ToolManager.java
package android.app;

import android.annotation.SystemService;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Singleton;
import android.os.ServiceManager;
import android.annotation.Nullable;

/**
 * 客户端
 */
@SystemService(Context.TOOL_SERVICE)
public class ToolManager {
    /**
     * @hide
     */
    public ToolManager() {
    }
    /**
     * @hide
     */
    public static IToolManager getServerice(){
        return I_TOOL_MANAGER_SINGLETON.get();
    }

    @UnsupportedAppUsage
    private static final Singleton<IToolManager> I_TOOL_MANAGER_SINGLETON =
            new Singleton<IToolManager>() {
                @Override
                protected IToolManager create() {
                    final IBinder b= ServiceManager.getService(Context.TOOL_SERVICE);
                    final IToolManager im=IToolManager.Stub.asInterface(b);
                    return im;
                }
            };


    @Nullable
    public String handle(@Nullable String msg){
        try{
            return getServerice().request(msg);
        }catch (RemoteException e){
            throw e.rethrowFromSystemServer();
        }
    }
}
  • 添加常量
/frameworks/base/core/java/android/context/Context.java
添加 public static final String TOOL_SERVICE = "tool";
  • 注册Binder
frameworks/base/services/java/com/android/server/SystemServer.java
//在startOtherServices方法中
  ServiceManager.addService(Context.TOOL_SERVICE,new ToolManagerService());

SystemServiceRegistry用于给客户端获取服务的类,有一个static块 执行了registerService用于注册.

frameworks/base/core/java/android/app/SystemServiceRegistry.java
 registerService(Context.TOOL_SERVICE, ToolManager.class,
                new CachedServiceFetcher<ToolManager>() {
                    @Override
                    public ToolManager createService(ContextImpl ctx) {
                        return new ToolManager();
                    }});
  • 修改SeLinux安全权限
    system/sepolicy/prebuilts/api/32.0/private/
    与 system/sepolicy/private/ 目录下,
    分别修改以下三个文件
  1. service_contexts
    #配置自定义服务selinux角色
    chen u:object_r:tool_service:s0
    用户:角色:类型:安全级别

  2. service.te
    #配置自定义服务类型的权限
    type tool_service, app_api_service, ephemeral_app_api_service, system_server_service,
    service_manager_type;

  3. untrusted_app_all.te
    #允许所有app使用自定义服务
    allow untrusted_app_all tool_service:service_manager find;

  • 更新编译
  1. 更新api
    make update-api
  2. 编译
    m
  3. 运行模拟器
    emulator
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
车中控系统的界面需求主要包括以下个方面: 1. 易用性:车载中控系统的界面应简洁、直观,方便驾驶和乘客使用。按钮、图标和应该清晰可见,操作流应该简单明了,避免复的操作步骤。 2. 可视性:车载中控系统界面需要在车辆行驶过程中提供清晰可见的显示效果。屏幕应该具备足够的亮度和对比度,以适应不同的光线条件。同时,界面设计应考虑到驾驶员的视线范围,避免干扰驾驶安全。 3. 响应性:车载中控系统的界面需要具备良好的响应速度,快速响应用户的操作指令。减少延迟和卡顿的情况,提供流畅的交互体验。 4. 自定义性:部分车主可能有个性化的需求,希望能够自定义界面的布局、颜色等,以满足个人喜好和需求。因此,车载中控系统的界面应该提供一定程度的自定义功能。 5. 多模态交互:车载中控系统的界面可以支持多种交互方式,如触摸屏、物理按键、语音控制等。这样可以适应不同用户的操作习惯和需求。 6. 安全性:考虑到驾驶安全,车载中控系统的界面应该设计合理,减少驾驶员分散注意力的情况。重要的功能和信息应该易于识别和操作,以确保驾驶员能够专注于道路行驶。 综上所述,车载中控系统的界面需求包括易用性、可视性、响应性、自定义性、多模态交互和安全性。这些需求的满足可以提供良好的用户体验,并确保驾驶的便利性和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈德山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值