Android10.0 SystemUI—keyguard锁屏加载分析

源代码 2024-9-21 19:23:25 121 0 来自 中国
学习条记:参考资源 https://blog.csdn.net/qq_15347925/article/details/116722133
一、流程概述

1、SystemUI启动完成后,进入的第一个界面为锁屏界面。
2、锁屏keyguard属于SystemUI。
3、锁屏开机大抵分为两部门,第一部门是从WindowManagerService开始,处理惩罚锁屏表现等流程。第二部门是KeyguardViewMediator的启动;

1.png 二、详细先容

1 WindowManagerService部门:

WindowManagerService在SystemService中的startOtherServices()方法里启动。
            t.traceBegin("StartWindowManagerService");            // WMS needs sensor service ready            ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);            mSensorServiceStart = null;            wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,                    new SprdPhoneWindowManager(), mActivityManagerService.mActivityTaskManager);            ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);            ServiceManager.addService(Context.INPUT_SERVICE, inputManager,                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);            t.traceEnd();SystemServer在启动SystemUI()的方法上,末了调用WindowManagerService的onSystemUiStarted方法。
    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();    }继续跟进,会发现WindowManagerService的onSystemUiStarted方法,实际调用的是PhoneWindowManager中的onSystemUiStarted();(通过接口进行回调)
    @Override    public void onSystemUiStarted() {        bindKeyguard();    }在PhoneWindowManager中会调用bindKeyguard,KeyguardServiceDelegate作为KeyguardService的委派。
    private void bindKeyguard() {        synchronized (mLock) {            if (mKeyguardBound) {                return;            }            mKeyguardBound = true;        }        mKeyguardDelegate.bindService(mContext);    }在KeyguardServiceDelegate的bindService方法中绑定KeyguardService。
public void bindService(Context context) {        Intent intent = new Intent();        final Resources resources = context.getApplicationContext().getResources();                //从设置文件中获取KeyguardService         final ComponentName keyguardComponent = ComponentName.unflattenFromString(             resources.getString(com.android.internal.R.string.config_keyguardComponent));        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);        intent.setComponent(keyguardComponent);        //绑定KeyguardService        if (!context.bindServiceAsUser(intent, mKeyguardConnection,                Context.BIND_AUTO_CREATE, mHandler, UserHandle.SYSTEM)) {            Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent);            mKeyguardState.showing = false;            mKeyguardState.showingAndNotOccluded = false;            mKeyguardState.secure = false;            synchronized (mKeyguardState) {                // TODO: Fix synchronisation model in this class. The other state in this class                // is at least self-healing but a race condition here can lead to the scrim being                // stuck on keyguard-less devices.                mKeyguardState.deviceHasKeyguard = false;            }        } else {            if (DEBUG) Log.v(TAG, "*** Keyguard started");        }    }在ServiceConnection的毗连乐成回调中,创建KeyguardService包装类KeyguardServiceWrapper。包装类除了KeyguardService,另有KeyguardStateMonitor状态监视器。实际调用照旧通过KeyguardService。
private final ServiceConnection mKeyguardConnection = new ServiceConnection() {     @Override     public void onServiceConnected(ComponentName name, IBinder service) {         if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");         // KeyguardServiceWrapper包装类调用KeyguardService的Binder实例         mKeyguardService = new KeyguardServiceWrapper(mContext,                 IKeyguardService.Stub.asInterface(service), mCallback);         if (mKeyguardState.systemIsReady) {             // If the system is ready, it means keyguard crashed and restarted.             mKeyguardService.onSystemReady();             if (mKeyguardState.currentUser != UserHandle.USER_NULL) {                 // There has been a user switch earlier                 mKeyguardService.setCurrentUser(mKeyguardState.currentUser);             }            // 调用KeyguardService的IPC接口                       ..            ..     }     @Override     public void onServiceDisconnected(ComponentName name) {         if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)");         mKeyguardService = null;         mKeyguardState.reset();         ..     } }在绑定以后,PhoneWindowManager可以调用署理类KeyguardServiceDelegate间接调用KeyguardService的binder接口进行各种锁屏相干状态回调。
2 KeyguardViewMediato 部门

初次开机Keyguard showLock流程:
体系启动完成-->honeWindowManager.systemReady()-->mKeyguardDelegate.onSystemReady()
-->mKeyguardService.onSystemReady()-->KeyguardService.onSystemReady()
在KeyguardService绑定乐成后调用了onSystemReady方法。onSystemReady终极的处理惩罚流程是在KeyguardViewMediator的onSystemReady方法
frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
        @Override // Binder interface        public void onSystemReady() {            Trace.beginSection("KeyguardService.mBinder#onSystemReady");            checkPermission();    //权限的查抄.            mKeyguardViewMediator.onSystemReady();            Trace.endSection();        }KeyguardViewMediator中的onSystemReady方法发送了一条handler消息。颠末消息通报会由handleSystemReady方法处理惩罚。handleSystemReady方法的关键调用是doKeyguardLocked。
frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
    public void onSystemReady() {        mHandler.obtainMessage(SYSTEM_READY).sendToTarget();    }   private void handleSystemReady() {        synchronized (this) {            if (DEBUG) Log.d(TAG, "onSystemReady");            mSystemReady = true;            //关键处理惩罚            doKeyguardLocked(null);  // handleSystemReady方法的关键调用是doKeyguardLocked。            mUpdateMonitor.registerCallback(mUpdateCallback);        }        // Most services aren't available until the system reaches the ready state, so we        // send it here when the device first boots.        maybeSendUserPresentBroadcast();    }    /**     * Enable the keyguard if the settings are appropriate.     */   private void doKeyguardLocked(Bundle options) {        //如果其他应用制止我们表现,那么就不表现。。比方:接打电话        if (!mExternallyEnabled || PowerOffAlarmManager.isAlarmBoot()) {            return;        }                //如果锁屏正在表现,那我们就不去表现        if (mStatusBarKeyguardViewManager.isShowing()) {            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");            resetStateLocked();            if (DEBUG) {                Log.d(TAG, "doKeyguard: not showing because it is already showing");            }            return;        }       // 判定是否无sim卡也可使用手机       // Settings中没有启用锁屏        ......        //颠末上述判定后,再去表现锁屏        showLocked(options);    }       /**      * showLocked表现锁屏方法紧张处理惩罚:哀求CPU不休眠,发送表现锁屏消息。      */    private void showLocked(Bundle options) {       Trace.beginSection("KeyguardViewMediator#showLocked aqcuiring mShowKeyguardWakeLock");        if (DEBUG) Log.d(TAG, "showLocked");        // ensure we stay awake until we are finished displaying the keyguard        // 获取PARTIAL_WAKE_LOCK,不受电源键影响,不让CPU进入休眠状态         mShowKeyguardWakeLock.acquire();    // 获取之后是无法让CPU休眠,不要忘记开释,不让会增长体系功耗。        Message msg = mHandler.obtainMessage(SHOW, options);        mHandler.sendMessage(msg);        Trace.endSection();    }    /**     * handleShow() 处理惩罚锁屏消息的方法     */    private void handleShow(Bundle options) {        ..        synchronized (KeyguardViewMediator.this) {            ..            setShowingLocked(true);            //  表现keyguard            mStatusBarKeyguardViewManager.show(options);            ..            // 开释mShowKeyguardWakeLock            mShowKeyguardWakeLock.release();        }        mKeyguardDisplayManager.show();        Trace.endSection();    }在handleShow中调用StatusBarKeyguardViewManager方法,锁屏处理惩罚由KeyguardViewMediator转移到StatusBarKeyguardViewManager。
3 其他各紧张部门

3.1 StatusBarKeyguardViewManager

StatusBarKeyguardViewManager中show方法设置keyguard是否表现,关照statusbar表现锁屏,重置view的状态,进行锁屏。
public void show(Bundle options) {        mShowing = true;        mStatusBarWindowManager.setKeyguardShowing(true);        //重置状态        reset(true /* hideBouncerWhenShowing */);        StatsLog.write(StatsLog.KEYGUARD_STATE_CHANGED,            StatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);    }StatusBarKeyguardViewManager中reset方法,紧张调用showBouncerOrKeyguard方法。判定表现默认锁屏界面照旧表现密码锁屏。默认锁屏界面由StatusBar管理,而密码解锁则调用KeyguardBouncer类。
// 判定是调用安全锁屏照旧调用滑动锁屏protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {   //是否必要表现密码锁屏界面,即得到当前是哪一种安全模式    if (mBouncer.needsFullscreenBouncer() && !mDozing) {         // The keyguard might be showing (already). So we need to hide it.        //潜伏锁屏,表现密码解锁界面        mStatusBar.hideKeyguard();         mBouncer.show(true /* resetSecuritySelection */);    } else {        mStatusBar.showKeyguard();  //表现锁屏,潜伏密码解锁界面        if (hideBouncerWhenShowing) {            hideBouncer(shouldDestroyViewOnReset() /* destroyView */);            mBouncer.prepare();        }    }    updateStates();}在我这手机打日志,发现走的是else分支,mStatusBar.showKeyguard()应该是手机锁解锁界面的前面谁人屏幕锁屏界面。由于我将else分支的mStatusBar.showKeyguard()改为了mStatusBar.hideKeyguard()就没有了屏幕锁屏界面。
3.2 KeyguardBouncer

在StatusBarKeyguardViewManager类中,StatusBar类则管理默认锁屏界面,KeyguardBouncer类控制密码解锁界面的,KeyguardBouncer会进行锁屏view的添补,KeyguardHostView是自界说容器,内部锁屏相干的处理惩罚在KeyguardSecurityContainer中。
private void showPrimarySecurityScreen() {        mKeyguardView.showPrimarySecurityScreen();    }继续往下跟进,会发现终极会调用到KeyguardSecurityContainer类中,在showSecurityScreen方法中会根据锁屏的范例得到锁屏的view,并添加到KeyguardSecurityViewFlipper 。
  // 该方法showSecurityScreen(),用来判定加载哪种解锁界面,比方:pin锁、密码锁。如果当前范例,与传过来的参数范例一样,则是同一范例,不必要重新加载,否则重新添加视图。  private void showSecurityScreen(SecurityMode securityMode) {        if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")");                //判定此参数安全模式是否与当前安全模式雷同,如果雷同则直接返回。        if (securityMode == mCurrentSecuritySelection) return;                        KeyguardSecurityView oldView = getSecurityView(mCurrentSecuritySelection);        KeyguardSecurityView newView = getSecurityView(securityMode);    // 关键方法,根据安全模式得到对应的view        // Emulate Activity life cycle        //设置相干回调        if (oldView != null) {            oldView.onPause();            oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view        }        if (securityMode != SecurityMode.None) {            newView.onResume(KeyguardSecurityView.VIEW_REVEALED);            newView.setKeyguardCallback(mCallback);        }        // Find and show this child.        final int childCount = mSecurityViewFlipper.getChildCount();        //探求当前安全模式对应的view,并进行展示。(此时PIN码解锁解锁已在getSecurityView()中添加至mSecurityViewFlipper)        //到这里view的展示也到达了本文流程的止境。        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);        for (int i = 0; i < childCount; i++) {            if (mSecurityViewFlipper.getChildAt(i).getId() == securityViewIdForMode) {                mSecurityViewFlipper.setDisplayedChild(i);                break;            }        }        // 更新当前的安全选择        mCurrentSecuritySelection = securityMode;        mSecurityCallback.onSecurityModeChanged(securityMode,                securityMode != SecurityMode.None && newView.needsInput());    }        private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {        // 获取对应范例锁的视图 id,        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);        KeyguardSecurityView view = null;        final int children = mSecurityViewFlipper.getChildCount();        // 从mSecurityViewFlipper中取出此安全模式对应view id的view,按照开机初次抵达这里的情况,此时获取的view为null        for (int child = 0; child < children; child++) {            if (mSecurityViewFlipper.getChildAt(child).getId() == securityViewIdForMode) {                view = ((KeyguardSecurityView)mSecurityViewFlipper.getChildAt(child));                break;            }        }        //根据安全模式得到对应的layoutId        int layoutId = getLayoutIdFor(securityMode);        //如果mSecurityViewFlipper还没有此view而且存在此安全模式对应的layoutId        if (view == null && layoutId != 0) {            //inflater Layout            final LayoutInflater inflater = LayoutInflater.from(mContext);            View v = inflater.inflate(layoutId, mSecurityViewFlipper, false);//view在这里被绘制,进行各项初始化。            view = (KeyguardSecurityView) v;//            //如果是KeyguardSimPinPukMeView则必要设置phoneid,KeyguardSimPinPukMeView将根据此phoneid展示对应资源            if (view instanceof KeyguardSimPinPukMeView) {                KeyguardSimPinPukMeView pinPukView = (KeyguardSimPinPukMeView) view;                final int phoneId = mSecurityModel.getPhoneIdUsingSecurityMode(securityMode);                pinPukView.setPhoneId(phoneId);            }            //将此view添参加mSecurityViewFlipper中            mSecurityViewFlipper.addView(v);//在这里添加view至mSecurityViewFlipper            updateSecurityView(v); //更新KeyguardSecurityView        }        return view;    }   private int getSecurityViewIdForMode(SecurityMode securityMode) {        switch (securityMode) {            case Pattern: return R.id.keyguard_pattern_view;            case PIN: return R.id.keyguard_pin_view;            case Password: return R.id.keyguard_password_view;            case SimPinPukMe1:            case SimPinPukMe2:            case SimPinPukMe3:            case SimPinPukMe4:                return R.id.keyguard_sim_pin_puk_me_view ;        }        return 0;}  protected int getLayoutIdFor(SecurityMode securityMode) {        switch (securityMode) {            case Pattern: return R.layout.keyguard_pattern_view;//手势            case PIN: return R.layout.keyguard_pin_view;//PIN码            case Password: return R.layout.keyguard_password_view;//密码解锁             case SimPinPukMe1:            case SimPinPukMe2:            case SimPinPukMe3:            case SimPinPukMe4:                return R.layout.mtk_keyguard_sim_pin_puk_me_view;//sim_pin_puk_me                        default:                return 0;        }}到这里,view展示,其启动流程也到此结束。
3.3 StatusBar

StatusBar也是继续SystemUI,启动流程和SystemUI划一。并在start的时间添加创建StatusBar相干的view。
public void start() {    // 省略部门代码...    // 创建整个SystemUI视图并添加到WindowManager中    createAndAddWindows(result);    // 省略部门代码...}public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {    // 创建整个SystemUI视图    makeStatusBarView(result);    // 把视图添加到Window中    mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);    mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());}makeStatusBarView()负责创建整个SystemUI视图,此中包罗状态栏。
代码路径: packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {      // ...      // 1. 实例化整个SystemUI视图,包罗状态栏,关照面版, 锁屏      mStatusBarWindow = (StatusBarWindowView) mInjectionInflater.injectable(      LayoutInflater.from(context)).inflate(R.layout.super_status_bar, null);}
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-11-22 00:04, Processed in 0.194332 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表