首页 > 技术文章 > systemUI

pyjetson 2021-04-20 19:13 原文

锁屏界面

1. 显示用户切换

1. updateVisibilities

// android/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
private void updateVisibilities() {
        if (mMultiUserSwitch.getParent() != mStatusIconArea && !mKeyguardUserSwitcherShowing) {
            if (mMultiUserSwitch.getParent() != null) {
                getOverlay().remove(mMultiUserSwitch);
            }
            mStatusIconArea.addView(mMultiUserSwitch, 0);
        } else if (mMultiUserSwitch.getParent() == mStatusIconArea && mKeyguardUserSwitcherShowing) {
            mStatusIconArea.removeView(mMultiUserSwitch);
        }
    // 1. 配置mKeyguardUserSwitcher
        if (mKeyguardUserSwitcher == null) {
            // If we have no keyguard switcher, the screen width is under 600dp. In this case,
            // we only show the multi-user switch if it's enabled through UserManager as well as
            // by the user.
            // 2. 配置isMultiUserEnabled
            if (mMultiUserSwitch.isMultiUserEnabled()) {
                mMultiUserSwitch.setVisibility(View.VISIBLE);
            } else {
                mMultiUserSwitch.setVisibility(View.GONE);
            }
        }
        mBatteryView.setForceShowPercent(mBatteryCharging && mShowPercentAvailable);
    }

    private void updateUserSwitcher() {
        // 如果mKeyguardUserSwitcher != null,则multi user的图标就是可以点击的
        boolean keyguardSwitcherAvailable = mKeyguardUserSwitcher != null;
        mMultiUserSwitch.setClickable(keyguardSwitcherAvailable);
        mMultiUserSwitch.setFocusable(keyguardSwitcherAvailable);
        mMultiUserSwitch.setKeyguardMode(keyguardSwitcherAvailable);
    }
亮屏时候的调用栈
updateVisibilities:197, KeyguardStatusBarView (com.android.systemui.statusbar.phone)
setVisibility:457, KeyguardStatusBarView (com.android.systemui.statusbar.phone)
updateHeaderKeyguardAlpha:2216, NotificationPanelViewController (com.android.systemui.statusbar.phone)
setQsExpansion:1688, NotificationPanelViewController (com.android.systemui.statusbar.phone)
access$7400:129, NotificationPanelViewController (com.android.systemui.statusbar.phone)
onLayoutChange:3671, NotificationPanelViewController$OnLayoutChangeListener (com.android.systemui.statusbar.phone)
layout:22862, View (android.view)
layout:6389, ViewGroup (android.view)
layoutChildren:332, FrameLayout (android.widget)
onLayout:270, FrameLayout (android.widget)
layout:22844, View (android.view)
layout:6389, ViewGroup (android.view)
performLayout:3496, ViewRootImpl (android.view)
performTraversals:2964, ViewRootImpl (android.view)
doTraversal:1969, ViewRootImpl (android.view)
run:8203, ViewRootImpl$TraversalRunnable (android.view)
run:1060, Choreographer$CallbackRecord (android.view)
doCallbacks:881, Choreographer (android.view)
doFrame:816, Choreographer (android.view)
run:1045, Choreographer$FrameDisplayEventReceiver (android.view)
handleCallback:938, Handler (android.os)
dispatchMessage:99, Handler (android.os)
loop:223, Looper (android.os)
main:7695, ActivityThread (android.app)
invoke:-1, Method (java.lang.reflect)
run:592, RuntimeInit$MethodAndArgsCaller (com.android.internal.os)
main:1084, ZygoteInit (com.android.internal.os)
1. 配置mKeyguardUserSwitcher
// frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
    public KeyguardUserSwitcher(Context context, ViewStub userSwitcher,
            KeyguardStatusBarView statusBarView,
            NotificationPanelViewController panelViewController) {
        // 配置config_keyguardUserSwitcher为false,则不走下面了,mKeyguardUserSwitcher就为null了
        boolean keyguardUserSwitcherEnabled =
                context.getResources().getBoolean(
                        com.android.internal.R.bool.config_keyguardUserSwitcher) || ALWAYS_ON;
        // 这个UserSwitcherController.class正常情况下都是true的,可以看./src/com/android/systemui/Dependency.java文件
        UserSwitcherController userSwitcherController = Dependency.get(UserSwitcherController.class);
        if (userSwitcherController != null && keyguardUserSwitcherEnabled) {
            mUserSwitcherContainer = (Container) userSwitcher.inflate();
            mBackground = new KeyguardUserSwitcherScrim(context);
            reinflateViews();
            mStatusBarView = statusBarView;
            // 在这里调用setKeyguardUserSwitcher,设置mKeyguardUserSwitcher,使其不为null
            mStatusBarView.setKeyguardUserSwitcher(this);
            panelViewController.setKeyguardUserSwitcher(this);
            mAdapter = new Adapter(context, userSwitcherController, this);
            mAdapter.registerDataSetObserver(mDataSetObserver);
            mUserSwitcherController = userSwitcherController;
            mAppearAnimationUtils = new AppearAnimationUtils(context, 400, -0.5f, 0.5f,
                    Interpolators.FAST_OUT_SLOW_IN);
            mUserSwitcherContainer.setKeyguardUserSwitcher(this);
        } else {
            mUserSwitcherContainer = null;
            mStatusBarView = null;
            mAdapter = null;
            mAppearAnimationUtils = null;
            mBackground = null;
        }
    }

// android/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
    public void setKeyguardUserSwitcher(KeyguardUserSwitcher keyguardUserSwitcher) {
        // 设置mKeyguardUserSwitcher,使其不为null
        mKeyguardUserSwitcher = keyguardUserSwitcher;
        mMultiUserSwitch.setKeyguardUserSwitcher(keyguardUserSwitcher);
        updateUserSwitcher();
    }
2. 配置isMultiUserEnabled()
// android/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
    public boolean isMultiUserEnabled() {
        // TODO(b/138661450) Move IPC calls to background
        // 配置qs_show_user_switcher_for_single_user为false,这里也不一定会返回false
        return whitelistIpcs(() -> mUserManager.isUserSwitcherEnabled(
                mContext.getResources().getBoolean(R.bool.qs_show_user_switcher_for_single_user)));
    }

// core\java\android\os\UserManager.java
    public boolean isUserSwitcherEnabled(boolean showEvenIfNotActionable) {
        // 多用户的时候,go设备只支持单用户
        if (!supportsMultipleUsers()) {
            return false;
        }
        // 查找一下,改user是否不允许进行USER_SWITCH操作
        if (hasUserRestriction(DISALLOW_USER_SWITCH)) {
            return false;
        }
        // If Demo Mode is on, don't show user switcher
        if (isDeviceInDemoMode(mContext)) {
            return false;
        }
        // Check the Settings.Global.USER_SWITCHER_ENABLED that the user can toggle on/off.
        // 
        // 配置config_showUserSwitcherByDefault为false
        final boolean userSwitcherSettingOn = Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.USER_SWITCHER_ENABLED,
                Resources.getSystem().getBoolean(R.bool.config_showUserSwitcherByDefault) ? 1 : 0)
                != 0;
        if (!userSwitcherSettingOn) {
            return false;
        }

        // The feature is enabled. But is it worth showing?
        return showEvenIfNotActionable
                || areThereUsersToWhichToSwitch() // There are switchable users.
                || !hasUserRestriction(UserManager.DISALLOW_ADD_USER); // New users can be added.
    }

    /** Returns whether there are any users (other than the current user) to which to switch. */
    private boolean areThereUsersToWhichToSwitch() {
        final List<UserInfo> users = getUsers(true);
        if (users == null) {
            return false;
        }
        int switchableUserCount = 0;
        for (UserInfo user : users) {
            if (user.supportsSwitchToByUser()) {
                ++switchableUserCount;
            }
        }
        return switchableUserCount > 1;
    }

2. 配置

// 1. common/overlay/overlay/frameworks/base/core/res/res/values-sw600dp/config.xml
    <!-- Set to true to enable the user switcher on the keyguard. -->
    <bool name="config_keyguardUserSwitcher">false</bool>

    <!-- If true, show multiuser switcher by default unless the user specifically disables it. -->
    <bool name="config_showUserSwitcherByDefault">false</bool>

// 2. common/overlay/overlay/frameworks/base/packages/SystemUI/res/values-sw600dp/bools.xml
<resources>
    <!-- Whether to show the user switcher in quick settings when only a single user is present. -->
    <bool name="qs_show_user_switcher_for_single_user">false</bool>
</resources>

3. go设备的流程

// android/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
        final Context context = mContext;
        updateDisplaySize(); // populates mDisplayMetrics
        updateResources();
		....
        mNotificationPanelViewController.setUserSetupComplete(mUserSetup);
        // 在isUserSwitcherEnabled函数中,由于go设备不支持多用户,所以直接返回false,就不会走到createUserSwitcher函数中
        if (UserManager.get(mContext).isUserSwitcherEnabled()) {
            createUserSwitcher();
        }
    }

    protected void createUserSwitcher() {
       	// 然后就不会创建KeyguardUserSwitcher类,然后在上面的mKeyguardUserSwitcher就为null了
        mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
                mNotificationShadeWindowView.findViewById(R.id.keyguard_user_switcher),
                mNotificationShadeWindowView.findViewById(R.id.keyguard_header),
                mNotificationPanelViewController);
    }

4. 问题

1. values文件夹中bools.xml和config.xml有什么区别?
都是一样的,只是名字不同而已,可能bools.xml里面放的,都是bool变量吧

推荐阅读