FW(CarSystemUI)(一)启动流程

前言:
CarSystemUi本质也是一个apk,通过 android:persistent="true"属性配置后,通过AMS拉起该应用

SystemUI清单文件


    <application
        android:name=".SystemUIApplication"
        android:persistent="true"   
        android:allowClearUserData="false"
        android:backupAgent=".backup.BackupHelper"
        android:killAfterRestore="false"
        android:hardwareAccelerated="true"
        android:label="@string/app_label"
        android:icon="@drawable/icon"
        android:process="com.android.systemui"
        android:supportsRtl="true"
        android:theme="@style/Theme.SystemUI"
		android:networkSecurityConfig="@xml/network_security_config"
        android:defaultToDeviceProtectedStorage="true"
        android:directBootAware="true"
        tools:replace="android:appComponentFactory"
        android:appComponentFactory=".SystemUIAppComponentFactory">

以上清单文件配置了  SystemUIApplication作为应用类

所以有了以下启动调用堆栈

at com.android.systemui.car.navigationbar.NavigationBarViewFactory.getWindowCached(NavigationBarViewFactory.java:157)
at com.android.systemui.car.navigationbar.NavigationBarViewFactory.getTopWindow(NavigationBarViewFactory.java:100)
at com.android.systemui.car.navigationbar.CarNavigationBarController.getTopWindow(CarNavigationBarController.java:165
at com.android.systemui.car.navigationbar.CarNavigationBar.buildNavBarWindows(CarNavigationBar.java:389)
at com.android.systemui.car.navigationbar.CarNavigationBar.createNavigationBar(CarNavigationBar.java:376)
at com.android.systemui.car.navigationbar.CarNavigationBar.start(CarNavigationBar.java:303)
at com.android.systemui.SystemUIApplication.startServicesIfNeeded(SystemUIApplication.java:204)
at com.android.systemui.SystemUIApplication.startServicesIfNeeded(SystemUIApplication.java:143)
at com.android.systemui.SystemUIService.onCreate(SystemUIService.java:70)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4186)
at android.app.ActivityThread.access$1500(ActivityThread.java:237)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7664)

at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
SystemUIService

public class SystemUIService extends Service {

    private final Handler mMainHandler;
    private final DumpHandler mDumpHandler;
    private final BroadcastDispatcher mBroadcastDispatcher;
    private final LogBufferFreezer mLogBufferFreezer;
    private final BatteryStateNotifier mBatteryStateNotifier;

    @Inject
    public SystemUIService(
            @Main Handler mainHandler,
            DumpHandler dumpHandler,
            BroadcastDispatcher broadcastDispatcher,
            LogBufferFreezer logBufferFreezer,
            BatteryStateNotifier batteryStateNotifier) {
        super();
        mMainHandler = mainHandler;
        mDumpHandler = dumpHandler;
        mBroadcastDispatcher = broadcastDispatcher;
        mLogBufferFreezer = logBufferFreezer;
        mBatteryStateNotifier = batteryStateNotifier;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        // Start all of SystemUI
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();

        // Finish initializing dump logic
        mLogBufferFreezer.attach(mBroadcastDispatcher);

        // If configured, set up a battery notification
        if (getResources().getBoolean(R.bool.config_showNotificationForUnknownBatteryState)) {
            mBatteryStateNotifier.startListening();
        }

        // For debugging RescueParty
        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_sysui", false)) {
            throw new RuntimeException();
        }

        if (Build.IS_DEBUGGABLE) {
            // b/71353150 - looking for leaked binder proxies
            BinderInternal.nSetBinderProxyCountEnabled(true);
            BinderInternal.nSetBinderProxyCountWatermarks(1000,900);
            BinderInternal.setBinderProxyCountCallback(
                    new BinderInternal.BinderProxyLimitListener() {
                        @Override
                        public void onLimitReached(int uid) {
                            Slog.w(SystemUIApplication.TAG,
                                    "uid " + uid + " sent too many Binder proxies to uid "
                                    + Process.myUid());
                        }
                    }, mMainHandler);
        }

        // Bind the dump service so we can dump extra info during a bug report
        startServiceAsUser(
                new Intent(getApplicationContext(), SystemUIAuxiliaryDumpService.class),
                UserHandle.SYSTEM);
    }

在以上代码中,SystemUiService.onCreate中会去获得当前应用的application,强转为SystemUIApplication后去调用startServicesIfNeeded()函数.

上述服务启动路径反向可以追溯到
com.android.server.SystemServer

 public static void main(String[] args) {
        new SystemServer().run();
    }

再上诉静态函数中会创建SystemServer对象,并执行run方法 这里的run并不是一个Thread,只是一个函数.

在run函数中


    private void run() {
          //其他代码
         Looper.prepareMainLooper();
         Looper.getMainLooper().setSlowLogThresholdMs(
                    SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
        
               // Start services.
        try {
            t.traceBegin("StartServices");
            startBootstrapServices(t);
            startCoreServices(t);
            startOtherServices(t);//这里面就会启动很多服务  包括SystemUi服务
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            t.traceEnd(); // StartServices
        }
        
         Looper.loop();
    }

  //创建SystemContext,用来启动各个服务
  private void createSystemContext() {
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

    //调用该函数,这个函数里面会启动很多服务,其中就包括systemui
    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        final Context context = mSystemContext;
    //其他代码
            t.traceBegin("StartSystemUI");
            try {
                startSystemUi(context, windowManagerF);
            } catch (Throwable e) {
                reportWtf("starting System UI", e);
            }
            t.traceEnd();
    //其他代码
     }

    private static void startSystemUi(Context context, WindowManagerService windowManager) {
        PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
        Intent intent = new Intent();
        intent.setComponent(pm.getSystemUiServiceComponent());
        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.SYSTEM);
        windowManager.onSystemUiStarted();
    }

上述run函数中,会调用到startOtherServices去调用SystemUIService

//SysmteContext创建代码

public final class ActivityThread extends ClientTransactionHandler {
//其他代码
    @UnsupportedAppUsage
    public static ActivityThread systemMain() {
        // The system process on low-memory devices do not get to use hardware
        // accelerated drawing, since this can add too much overhead to the
        // process.
        if (!ActivityManager.isHighEndGfx()) {
            ThreadedRenderer.disable(true);
        } else {
            ThreadedRenderer.enableForegroundTrimming();
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(true, 0);
        return thread;
    }

//其他代码
    
    @UnsupportedAppUsage
    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }
//其他代码
}

可以看到Context最终创建是通过ContextImpl.createSystemContext(this),传入了当前的ActivityThread创建出来.

继续追溯源码

class ContextImpl extends Context {
//其他代码
//createSystemContext中创建了当前对象的示例,并且创建了LoadedApk 持有了当前传入的ActivityThread对象

@UnsupportedAppUsage
    static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, null,
                0, null, null);
        context.setResources(packageInfo.getResources());
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        context.mIsSystemOrSystemUiContext = true;
        return context;
    }
//其他代码
}

至此 Context的创建就结束了.

接下来继续追溯startServiceAsUser函数,看看服务是如何被拉起的

依然是ContextImpl对象中

class ContextImpl extends Context {
//其他代码
  @Override
    public ComponentName startServiceAsUser(Intent service, UserHandle user) {
        return startServiceCommon(service, false, user);
    }


    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            ComponentName cn = ActivityManager.getService().startService(
                    mMainThread.getApplicationThread(), service,
                    service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                    getOpPackageName(), getAttributionTag(), user.getIdentifier());
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                } else if (cn.getPackageName().equals("?")) {
                    throw new IllegalStateException(
                            "Not allowed to start service " + service + ": " + cn.getClassName());
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
//其他代码
}

可以看到最终通过ActivityManager.getService()获取了一个类然后去调用的startService,并且传入了一堆形参.
继续跟踪ActivityManager的源码

public class ActivityManager {

    @UnsupportedAppUsage
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };


//其他代码
    /**
     * @hide
     */
    @UnsupportedAppUsage
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }
//其他代码
}

//以下是AIDL文件
interface IActivityManager {
    ComponentName startService(in IApplicationThread caller, in Intent service,
            in String resolvedType, boolean requireForeground, in String callingPackage,
            in String callingFeatureId, int userId);
}

在ActivityManager调用getService的时候会调用到跨进程通过AIDL调用到IActivityManager 的对象函数去了

而startOtherServices中会通过上诉流程创建的Context去拉起Systmeui的Service

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenSBI启动流程可以简述如下: 1. 在OpenSBI启动时,第一条执行的指令是_start函数,该函数位于fw_start.S文件中。 2. 在fw_start.S文件中,首先会进行一些初始化工作,然后跳转到main函数进行主要的启动流程。 3. 在main函数中,会首先获取每个HART的scratch结构体信息。 4. Scratch结构体是OpenSBI对每个HART的私有信息的表示,包含了一些重要的字段用于启动过程。 5. 其中,fw_start字段表示固件与OpenSBI库链接的起始地址,fw_size字段表示固件的大小。 6. next_addr字段表示下一个引导阶段的地址,next_arg1字段表示下一个引导阶段的参数。 7. next_mode字段表示下一个引导阶段的特权模式。 8. warmboot_addr字段表示用于热重启的入口地址。 9. platform_addr字段表示sbi_platform的地址,用于与硬件平台相关的初始化。 10. hartid_to_scratch字段表示HART ID到scratch结构体的转换函数的地址。 11. trap_exit字段表示陷阱退出函数的地址。 12. tmp0字段是一个临时存储字段。 13. options字段包含了OpenSBI库的选项信息。 14. 在启动流程中,每个HART都会按顺序执行操作,直到所有HART都完成了boot阶段的操作。 15. 在boot阶段的最后,会设置boot阶段表示为BOOT_STATUS_BOOT_HART_DONE标志,表示该HART已完成boot阶段,其他HART也要执行10以后的步骤。 综上所述,OpenSBI启动流程包括了_start函数的执行、初始化工作、获取scratch结构体信息、设置各字段的值以及标志位的设置等步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值