SystemUI9.0系统应用图标加载流程

初始化:
SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java 

@Override 
public void onFinishInflate() { 
        mNavButtons = findViewById(R.id.nav_buttons); 
        mLockScreenButtons = findViewById(R.id.lock_screen_nav_buttons); 

        mNotificationsButton = findViewById(R.id.notifications); 
        if (mNotificationsButton != null) { 
            mNotificationsButton.setOnClickListener(this::onNotificationsClick); 
        } 
        View mStatusIcons = findViewById(R.id.statusIcons); 
        if (mStatusIcons != null) { 
            // Attach the controllers for Status icons such as wifi and bluetooth if the standard 
            // container is in the view. 
            StatusBarIconController.DarkIconManager mDarkIconManager = 
                    new StatusBarIconController.DarkIconManager( 
                            mStatusIcons.findViewById(R.id.statusIcons)); 
            mDarkIconManager.setShouldLog(true); 
            Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); 
        } 
} 

或者 SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java 

@Override 
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
        super.onViewCreated(view, savedInstanceState); 
        mStatusBar = (PhoneStatusBarView) view; 
        mKeyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE); 
        if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) { 
            mStatusBar.go(savedInstanceState.getInt(EXTRA_PANEL_STATE)); 
        } 
        if (TinnoFeature.FEATURE_SPRINT_WFC_SUPPORT) { 
            mWifiCall = view.findViewById(R.id.wifi_call); 
            WfcIconUpdate.getIntance(getContext()).registrationListener(mWifiCall); 
        } 
        mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons)); 
        mDarkIconManager.setShouldLog(true); 
        Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); 
        mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area); 
        mClockView = mStatusBar.findViewById(R.id.clock); 
        showSystemIconArea(false); 
        showClock(false); 
        initEmergencyCryptkeeperText(); 
        initOperatorName(); 
} 

或者 SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java 

@Override 
public void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
    if (TinnoFeature.TINNO_VDF_COMMON_FEATURE_SUPPORT) { 
        mBatteryShowPercentListener.setListener(true, getContext()); 
        IntentFilter filter = new IntentFilter(); 
        filter.addAction(Intent.ACTION_BATTERY_CHANGED); 
        getContext().registerReceiver(mBroadcastReceiver, filter); 
    } 
    Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager); 
    requestApplyInsets(); 
}

以上三处都会调用到如下代码: 
SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java 

    @Override 
    public void addIconGroup(IconManager group) { 
        mIconGroups.add(group); 
        List<Slot> allSlots = getSlots(); 
        for (int i = 0; i < allSlots.size(); i++) { 
            Slot slot = allSlots.get(i); 
            List<StatusBarIconHolder> holders = slot.getHolderListInViewOrder(); 
            boolean blocked = mIconBlacklist.contains(slot.getName()); 

            for (StatusBarIconHolder holder : holders) { 
                int tag = holder.getTag(); 
                int viewIndex = getViewIndex(getSlotIndex(slot.getName()), holder.getTag()); 
                group.onIconAdded(viewIndex, slot.getName(), blocked, holder);//加载所有系统图标
            } 
        } 
    } 

当前类StatusBarIconControllerImpl的构造器初始化在类:
Dependency.java的start():

public void start() {
.......
mProviders.put(StatusBarIconController.class, () ->
        new StatusBarIconControllerImpl(mContext));
.......
}

StatusBarIconControllerImpl.java的构造器:
public StatusBarIconControllerImpl(Context context) {
    super(context.getResources().getStringArray(
            com.android.internal.R.array.config_statusBarIcons), context);
.........
}

数组 config_statusBarIcons在:
android/frameworks/base/core/res/res/values/config.xml

<string-array name="config_statusBarIcons"> 
        <item><xliff:g id="id">@string/status_bar_alarm_clock</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_rotate</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_headset</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_data_saver</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_ime</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_sync_failing</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_sync_active</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_nfc</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_tty</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_speakerphone</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_cdma_eri</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_data_connection</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_bluetooth</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_cast</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_vpn</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_mute</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_volume</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_location</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_zen</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_ethernet</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_wifi</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_hotspot</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_mobile</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_airplane</xliff:g></item> 
        <item><xliff:g id="id">@string/status_bar_battery</xliff:g></item> 
    </string-array>

StatusBarIconControllerImpl构造器的super函数实例化其父类StatusBarIconList的实例化:
StatusBarIconList.java:

private ArrayList<Slot> mSlots = new ArrayList<>();
public StatusBarIconList(String[] slots, Context context) {
    /// M: Add for Plugin feature @ {
    mStatusBarExt = OpSystemUICustomizationFactoryBase.getOpFactory(context)
                                 .makeSystemUIStatusBar(context);
    slots = mStatusBarExt.addSlot(slots);
    /// @ }
    final int N = slots.length;
    for (int i=0; i < N; i++) {
        mSlots.add(new Slot(slots[i], null));
    }
}
......
protected ArrayList<Slot> getSlots() {
    return new ArrayList<>(mSlots);
}
......

至此,StatusBarIconControllerImpl.java中的 addIconGroup()调用函数 getSlots()完成初始化.
成员变量mSlots的参数中包含所有系统状态栏要显示的图标名称信息。
SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java 

public static class IconManager implements DemoMode { 
       ...... 
       protected void onIconAdded(int index, String slot, boolean blocked, 
                StatusBarIconHolder holder) { 
            addHolder(index, slot, blocked, holder); 
        } 

       protected StatusIconDisplayable addHolder(int index, String slot, boolean blocked, 
                StatusBarIconHolder holder) { 
            if("mobile type".equals(slot)){ 
                return addMobileType(index, slot, blocked, holder.getIcon()); 
            } 
            switch (holder.getType()) { 
                case TYPE_ICON: //添加除wifi,信号塔外的所有系统图标
                    return addIcon(index, slot, blocked, holder.getIcon()); 

                case TYPE_WIFI: //添加Wifi系统图标
                    return addSignalIcon(index, slot, holder.getWifiState()); 

                case TYPE_MOBILE: //添加信号塔系统图标
                    return addMobileIcon(index, slot, holder.getMobileState());//信号塔 
            } 
            return null; 
        } 
        ...... 
   } 

下面以添加信号塔图标,及其信号塔图标刷新为例,说明状态栏系统图标加载及其刷新流程:

protected StatusBarMobileView addMobileIcon(int index, String slot, MobileIconState state) { 
            StatusBarMobileView view = onCreateStatusBarMobileView(slot); 
            List<SubscriptionInfo> si = SubscriptionManager.from(mContext).getActiveSubscriptionInfoList(); 
            if(TinnoFeature.TINNO_VDF_COMMON_FEATURE_SUPPORT && si != null && si.size() == 2){ 
                view.setTag(mSlotNum); 
                mSlotNum++; 
                if(mSlotNum == 2){ 
                    mSlotNum = 0; 
                } 
            } 
            // TINNO END 
            view.applyMobileState(state); 
            mGroup.addView(view, index, onCreateLayoutParams()); 

            if (mIsInDemoMode) { 
                mDemoStatusIcons.addMobileView(state); 
            } 
            return view; 
...... 
} 

//注意:mGroup是layout:system_icons.xml中的id/statusIcons:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/system_icons"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_vertical">
    <com.android.systemui.statusbar.phone.StatusIconContainer android:id="@+id/statusIcons"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:paddingEnd="@dimen/signal_cluster_battery_padding"
        android:gravity="center_vertical"
        android:orientation="horizontal"/>
    <com.android.systemui.BatteryMeterView android:id="@+id/battery"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:clipToPadding="false"
        android:clipChildren="false" />
</LinearLayout>

private StatusBarMobileView onCreateStatusBarMobileView(String slot) { 
            StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, slot); 
            return view; 
        } 

//SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java 
public static StatusBarMobileView fromContext(Context context, String slot) { 
        LayoutInflater inflater = LayoutInflater.from(context); 
        StatusBarMobileView v = (StatusBarMobileView) 
                inflater.inflate(R.layout.status_bar_mobile_signal_group, null); 

        v.setSlot(slot); 
        v.init(); 
        v.setVisibleState(STATE_ICON); 
        return v; 
    } 

private void init() { 
        mMobileGroup = findViewById(R.id.mobile_group); 
        mMobile = findViewById(R.id.mobile_signal);/*****/ 
        mMobileType = findViewById(R.id.mobile_type); 
        mMobileRoaming = findViewById(R.id.mobile_roaming); 
        mMobileSprintRoaming = findViewById(R.id.mobile_sprint_roaming);  
        mIn = findViewById(R.id.mobile_in); 
        mOut = findViewById(R.id.mobile_out); 
        mInoutContainer = findViewById(R.id.inout_container); 
        /// M: Add for [Network Type and volte on Statusbar] @{ 
        mNetworkType    = findViewById(R.id.network_type); 
        mVolteType      = findViewById(R.id.volte_indicator_ext); 
        /// @} 
        mMobileDrawable = new SignalDrawableCustom(getContext()); 
 
        List<SubscriptionInfo> si = SubscriptionManager.from(getContext()).getActiveSubscriptionInfoList(); 
        if (TinnoFeature.TINNO_VDF_COMMON_FEATURE_SUPPORT && si != null && si.size() == 2) { 
            int iconWidth = getContext().getResources().getDimensionPixelSize(R.dimen.signal_icon_size_for_half); 
            mMobileDrawable.setIntrinsicHeight(iconWidth); 
        }
        mMobile.setImageDrawable(mMobileDrawable);/*****/ 
        。。。。。。。
    } 

SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java 

public static class IconManager implements DemoMode {//静态内部类 
     ....... 
     protected StatusIconDisplayable addHolder(int index, String slot, boolean blocked, 
                StatusBarIconHolder holder) { 
            // TINNO BEGIN 
            // DATE20181208,StatusBar requirment, Signal bar By XIBIN, CEAAEP-984 
            if("mobile type".equals(slot)){ 
                return addMobileType(index, slot, blocked, holder.getIcon()); 
            } 
            // TINNO END 
            switch (holder.getType()) { 
                case TYPE_ICON: 
                    return addIcon(index, slot, blocked, holder.getIcon()); 

                case TYPE_WIFI: 
                    return addSignalIcon(index, slot, holder.getWifiState()); 

                case TYPE_MOBILE: 
                    return addMobileIcon(index, slot, holder.getMobileState()); 
            } 

            return null; 
        } 
        ....... 
} 

以上是信号塔图标初始化流程,以下是信号塔刷新流程: 
SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java 

class MobilePhoneStateListener extends PhoneStateListener { 
       public void onSignalStrengthsChanged(SignalStrength signalStrength) { 
                if (DEBUG) { 
                   Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength + 
                        ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel()))); 
                } 
            mSignalStrength = signalStrength; 
            updateTelephony();
        } 
} 

private final void updateTelephony() { 
        if (DEBUG && FeatureOptions.LOG_ENABLE) { 
        } 
        mCurrentState.connected = hasService() && mSignalStrength != null; 
        handleIWLANNetwork(); 
        if (mCurrentState.connected) { 
            if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) { 
                mCurrentState.level = mSignalStrength.getCdmaLevel(); 
            } else { 
                mCurrentState.level = mSignalStrength.getLevel(); 
            } 
            /// M: Customize the signal strength level. @ { 
            mCurrentState.level = mStatusBarExt.getCustomizeSignalStrengthLevel( 
                    mCurrentState.level, mSignalStrength, mServiceState); 
            /// @ } 
        } 
        if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) { 
            mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType); 
        } else { 
            mCurrentState.iconGroup = mDefaultIcons; 
        } 
        /// M: Add for data network type. 
        mCurrentState.dataNetType = mDataNetType; 
        mCurrentState.dataConnected = mCurrentState.connected 
                && mDataState == TelephonyManager.DATA_CONNECTED; 
        /// M: Add for op network tower type. 
        mCurrentState.customizedState = mStatusBarExt.getCustomizeCsState(mServiceState, 
                mCurrentState.customizedState); 
        /// M: Add for cs call state change. 
        mCurrentState.isInCsCall = mStatusBarExt.isInCsCall(); 
        /// M: Add for op signal strength tower icon. 
        mCurrentState.customizedSignalStrengthIcon = mStatusBarExt.getCustomizeSignalStrengthIcon( 
                mSubscriptionInfo.getSubscriptionId(), 
                mCurrentState.customizedSignalStrengthIcon, 
                mSignalStrength, 
                mDataNetType, 
                mServiceState); 

        mCurrentState.roaming = isRoaming(); 
        if (isCarrierNetworkChangeActive()) { 
            mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE; 
        } else if (isDataDisabled() && !mConfig.alwaysShowDataRatIcon) { 
            mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED; 
        } 
        if (isEmergencyOnly() != mCurrentState.isEmergency) { 
            mCurrentState.isEmergency = isEmergencyOnly(); 
            mNetworkController.recalculateEmergency(); 
        } 
        // Fill in the network name if we think we have it. 
        if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null 
                && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) { 
            mCurrentState.networkName = mServiceState.getOperatorAlphaShort(); 
        } 
        /// M: For network type big icon. 
        mCurrentState.networkIcon = 
                NetworkTypeUtils.getNetworkTypeIcon(mServiceState, mConfig, hasService()); 
        /// M: For volte type icon. 
        mCurrentState.volteIcon = getVolteIcon(); 

        notifyListenersIfNecessary(); 
    } 
    public void notifyListenersIfNecessary() { 
        if (isDirty()) { 
            saveLastState(); 
            notifyListeners(); 
        } 
    } 

调用父类:SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java 

   public void notifyListenersIfNecessary() { 
        if (isDirty()) { 
            saveLastState(); 
            notifyListeners(); 
        } 
    } 
    public final void notifyListeners() { 
        notifyListeners(mCallbackHandler); 
    } 
    public abstract void notifyListeners(SignalCallback callback); 

SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java 

public void notifyListeners(SignalCallback callback) { 
        MobileIconGroup icons = getIcons(); 

        String contentDescription = getStringIfExists(getContentDescription()); 
        String dataContentDescription = getStringIfExists(icons.mDataContentDescription); 
        if (mCurrentState.inetCondition == 0) { 
            dataContentDescription = mContext.getString(R.string.data_connection_no_internet); 
        } 
        final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED 
                && mCurrentState.userSetup; 

        /// M: Customize the signal strength icon id. @ { 
        int iconId = getCurrentIconId(); 
        iconId = mStatusBarExt.getCustomizeSignalStrengthIcon( 
                    mSubscriptionInfo.getSubscriptionId(), 
                    iconId, 
                    mSignalStrength, 
                    mDataNetType, 
                    mServiceState); 
        /// @ } 

        // Show icon in QS when we are connected or data is disabled. 
        boolean showDataIcon = mCurrentState.dataConnected || dataDisabled; 
        IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode, iconId, contentDescription); 

        int qsTypeIcon = 0; 
        IconState qsIcon = null; 
        String description = null; 
        // Only send data sim callbacks to QS. 
        if (mCurrentState.dataSim) { 
        qsTypeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.mQsDataType : 0; 
        qsIcon = new IconState(mCurrentState.enabled 
                    && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription); 
            description = mCurrentState.isEmergency ? null : mCurrentState.networkName; 
        }
        boolean activityIn = mCurrentState.dataConnected 
                && !mCurrentState.carrierNetworkChangeMode 
                && mCurrentState.activityIn; 
        boolean activityOut = mCurrentState.dataConnected 
                && !mCurrentState.carrierNetworkChangeMode 
                && mCurrentState.activityOut; 
        showDataIcon &= mCurrentState.isDefault || dataDisabled; 
        int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.mDataType : 0; 

        /// M: Add for lwa. 
        typeIcon = mCurrentState.lwaRegState == NetworkTypeUtils.LWA_STATE_CONNCTED 
                && showDataIcon ? NetworkTypeUtils.LWA_ICON : typeIcon; 
        /** M: Support [Network Type on StatusBar], change the implement methods. 
          * Get the network icon base on service state. 
          * Add one more parameter for network type. 
          * @ { **/ 
        int networkIcon = mCurrentState.networkIcon; 
        /// M: Support volte icon.Bug fix when airplane mode is on go to hide volte icon 
        int volteIcon = mCurrentState.airplaneMode && !isImsOverWfc() 
                ? 0 : mCurrentState.volteIcon; 

        /// M: when data disabled, common show data icon as x, but op do not need show it @ { 
        mStatusBarExt.isDataDisabled(mSubscriptionInfo.getSubscriptionId(), dataDisabled); 
        /// @ } 

        /// M: Customize the data type icon id. @ { 
        typeIcon = mStatusBarExt.getDataTypeIcon( 
                        mSubscriptionInfo.getSubscriptionId(), 
                        typeIcon, 
                        mDataNetType, 
                        mCurrentState.dataConnected ? TelephonyManager.DATA_CONNECTED : 
                            TelephonyManager.DATA_DISCONNECTED, 
                        mServiceState); 
        /// @ } 
        /// M: Customize the network type icon id. @ { 
        networkIcon = mStatusBarExt.getNetworkTypeIcon( 
                        mSubscriptionInfo.getSubscriptionId(), 
                        networkIcon, 
                        mDataNetType, 
                        mServiceState); 
        /// @ } 
        callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, networkIcon, volteIcon, 
                qsTypeIcon,activityIn, activityOut, dataContentDescription, description, 
                 icons.mIsWide, mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming, 
                 mCurrentState.isDefaultData); 

        /// M: update plmn label @{ 
        mNetworkController.refreshPlmnCarrierLabel(); 
        /// @} 
    } 

通过CallbackHandler回调到具体显示的view:

SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java 
   

    @Override 
    public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon, 
            final int statusType, final int networkIcon, final int volteType, 
            final int qsType,final boolean activityIn, 
            final boolean activityOut, final String typeContentDescription, 
            final String description, final boolean isWide, final int subId, boolean roaming, 
            boolean isDefaultData) {
        post(new Runnable() { 
            @Override 
            public void run() { 
                for (SignalCallback signalCluster : mSignalCallbacks) {//此处是一个callback集合,其中包含com.android.systemui.statusbar.phone.StatusBarSignalPolicy.java 
                    ///M: Support[Network Type and volte on StatusBar]. 
                    /// add more parameter networkIcon and volte. 
                    signalCluster.setMobileDataIndicators(statusIcon, qsIcon, statusType, 
                            networkIcon, volteType, qsType, activityIn, activityOut, 
                            typeContentDescription, description, isWide, subId, roaming, 
                            isDefaultData); 
                } 
            } 
        }); 
    } 

SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java 

public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, 
            int networkType, int volteIcon, int qsType, boolean activityIn, boolean activityOut, 
            String typeContentDescription, String description, boolean isWide, int subId, 
            boolean roaming, boolean isDefaultData) { 
        MobileIconState state = getState(subId); 
        if (state == null) { 
            return; 
        } 

        // Visibility of the data type indicator changed 
        boolean typeChanged = statusType != state.typeId && (statusType == 0 || state.typeId == 0); 
        state.visible = statusIcon.visible && !mBlockMobile; 
        state.strengthId = statusIcon.icon; 
        state.typeId = statusType; 
        state.contentDescription = statusIcon.contentDescription; 
        state.typeContentDescription = typeContentDescription; 
        state.roaming = roaming; 
        state.activityIn = activityIn && mActivityEnabled; 
        state.activityOut = activityOut && mActivityEnabled; 
        state.networkIcon = networkType; 
        state.volteIcon = volteIcon; 

        /// M: Add for plugin features. @ { 
        state.mDataActivityIn = activityIn; 
        state.mDataActivityOut = activityOut; 
        state.mDefaultData = isDefaultData; 
        /// @ } 

        // Always send a copy to maintain value type semantics 
        mIconController.setMobileIcons(mSlotMobile, MobileIconState.copyStates(mMobileStates)); 

        if (typeChanged) { 
            WifiIconState wifiCopy = mWifiIconState.copy(); 
            updateShowWifiSignalSpacer(wifiCopy); 
            if (!Objects.equals(wifiCopy, mWifiIconState)) { 
                updateWifiIconWithState(wifiCopy); 
                mWifiIconState = wifiCopy; 
            } 
        } 
    } 

/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java 

public void setMobileIcons(String slot, List<MobileIconState> states); 

SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java 

    @Override 
    public void setMobileIcons(String slot, List<MobileIconState> iconStates) { 
        
        Slot mobileSlot = getSlot(slot); 
        int slotIndex = getSlotIndex(slot); 
        for (MobileIconState state : iconStates) { 
            StatusBarIconHolder holder = mobileSlot.getHolderForTag(state.subId); 
            if (holder == null) { 
                holder = StatusBarIconHolder.fromMobileIconState(state); 
                setIcon(slotIndex, holder); 
            } else { 
                holder.setMobileState(state); 
                handleSet(slotIndex, holder); 
            } 
        } 
    } 
    private void handleSet(int index, StatusBarIconHolder holder) { 
        int viewIndex = getViewIndex(index, holder.getTag()); 
        mIconLogger.onIconVisibility(getSlotName(index), holder.isVisible()); 
        mIconGroups.forEach(l -> l.onSetIconHolder(viewIndex, holder)); 
    } 

SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java 

public static class IconManager implements DemoMode { 
..... 
public void onSetIconHolder(int viewIndex, StatusBarIconHolder holder) { 
            switch (holder.getType()) { 
                case TYPE_ICON: 
                    onSetIcon(viewIndex, holder.getIcon()); 
                    return; 
                case TYPE_WIFI: 
                    onSetSignalIcon(viewIndex, holder.getWifiState()); 
                    return; 

                case TYPE_MOBILE: 
                    onSetMobileIcon(viewIndex, holder.getMobileState()); 
                default: 
                    break; 
            } 
        } 
...... 
} 

public void onSetMobileIcon(int viewIndex, MobileIconState state) {
    StatusBarMobileView view = (StatusBarMobileView) mGroup.getChildAt(viewIndex);
    if (view != null) {
        view.applyMobileState(state);
    }
    if (mIsInDemoMode) {
        mDemoStatusIcons.updateMobileState(state);
    }
}

SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java 
   

public void applyMobileState(MobileIconState state) { 
        if (DEBUG) { 
            Log.d(getMobileTag(), "[" + this.hashCode() + "][visibility=" + getVisibility() 
                + "] applyMobileState: state = " + state); 
        } 
        mDataStateListener.setListener(true, state.subId , getContext()); 

        if (state == null) { 
            setVisibility(View.GONE); 
            mState = null; 
            return; 
        } 

        if (mState == null) { 
            mState = state.copy(); 
            initViewState();//第一次初始化信号塔 
            return; 
        } 

        if (!mState.equals(state)) { 
            updateState(state.copy());//刷新信号塔 
        } 
    } 

初始化信号塔 

private void initViewState() { 
        setContentDescription(mState.contentDescription); 
        if (!mState.visible) { 
            mMobileGroup.setVisibility(View.GONE); 
        } else { 
            mMobileGroup.setVisibility(View.VISIBLE); 
        } 
        mMobileDrawable.setLevel(mState.strengthId); 
        if (mState.typeId > 0) { 
            if (!mStatusBarExt.disableHostFunction()) { 
                mMobileType.setContentDescription(mState.typeContentDescription); 
                if(TinnoFeature.TINNO_VDF_COMMON_FEATURE_SUPPORT){ 
                    handleMobileTypeImageResource(mState.typeId); 
                }else{ 
                    mMobileType.setImageResource(mState.typeId); 
                } 
            } 
            setMobileTypeVisibility(View.VISIBLE); 
        } else { 
              setMobileTypeVisibility(View.GONE); 
              mMobileType.setImageDrawable(null); 
        } 
        mMobileRoaming.setVisibility(mState.roaming ? View.VISIBLE : View.GONE); 

        //TINNO UDAAP-322 by myu 
        if(TinnoFeature.TINNO_SPRINT_COMMON_FEATURE_SUPPORT){ 
            Log.d(TAG,"initViewState sprint case"); 
            mMobileSprintRoaming.setVisibility(mState.roaming ? View.VISIBLE : View.GONE); 
            mMobileRoaming.setVisibility(View.GONE); 
            //add by qipeng.wang for bug:UDAAP-2061 begin 
            boolean isShowMobileType = (!mState.roaming) && (mState.typeId > 0); 
            setMobileTypeVisibility(isShowMobileType ? View.VISIBLE : View.GONE); 
        }else{ 
            Log.d(TAG,"initViewState not sprint case"); 
            mMobileSprintRoaming.setVisibility(View.GONE); 
        } 

        mIn.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE); 
        mOut.setVisibility(mState.activityIn ? View.VISIBLE : View.GONE); 
        mInoutContainer.setVisibility((mState.activityIn || mState.activityOut) 
                ? View.VISIBLE : View.GONE); 

        /// M: Add for [Network Type and volte on Statusbar] @{ 
        setCustomizeViewProperty(); 
        /// @} 

        showWfcIfAirplaneMode(); 

        /// M: Add data group for plugin feature. @ { 
        mStatusBarExt.addCustomizedView(mState.subId, mContext, mMobileGroup); 
        setCustomizedOpViews(); 
        /// @ } 
    } 

刷新信号塔 

private void updateState(MobileIconState state) {
        setContentDescription(state.contentDescription); 
        if (mState.visible != state.visible) { 
            mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE); 
            // To avoid StatusBarMobileView will not show in extreme case, 
            // force request layout once if visible state changed. 
            requestLayout(); 
        } 
        if (mState.strengthId != state.strengthId) { 
            mMobileDrawable.setLevel(state.strengthId); 
        } 
        if (mState.typeId != state.typeId) { 
            if (state.typeId != 0) { 
                if (!mStatusBarExt.disableHostFunction()) { 
                    mMobileType.setContentDescription(state.typeContentDescription); 
                   if(TinnoFeature.TINNO_VDF_COMMON_FEATURE_SUPPORT){ 
                      handleMobileTypeImageResource(mState.typeId); 
                    }else{ 
                      mMobileType.setImageResource(state.typeId); 
                    } 
                } 
                setMobileTypeVisibility(VISIBLE); 
            } else { 
                setMobileTypeVisibility(GONE); 
                mMobileType.setImageDrawable(null); 
            } 
        } 
        mMobileRoaming.setVisibility(state.roaming ? View.VISIBLE : View.GONE); 

        //TINNO UDAAP-322 by myu 
        if(TinnoFeature.TINNO_SPRINT_COMMON_FEATURE_SUPPORT){ 
            Log.d(TAG,"updateState sprint case"); 
             //add by qipeng.wang for bug:UDAAP-2061 begin 
            mMobileSprintRoaming.setVisibility(state.roaming ? View.VISIBLE : View.GONE); 
            mMobileRoaming.setVisibility(View.GONE); 
            boolean isShowMobileType = (!state.roaming) && (state.typeId > 0); 
            setMobileTypeVisibility(isShowMobileType ? View.VISIBLE : View.GONE); 
        }else{ 
            Log.d(TAG,"updateState not sprint case"); 
            mMobileSprintRoaming.setVisibility(View.GONE); 
        } 

        mIn.setVisibility(state.activityIn ? View.VISIBLE : View.GONE); 
        mOut.setVisibility(state.activityIn ? View.VISIBLE : View.GONE); 
        mInoutContainer.setVisibility((state.activityIn || state.activityOut) 
                ? View.VISIBLE : View.GONE); 

        /// M: Add for [Network Type and volte on Statusbar] @{ 
        if (mState.networkIcon != state.networkIcon) { 
            setNetworkIcon(state.networkIcon); 
            // if network icon change to LTE, need to update dis volte icon. 
            mStatusBarExt.setDisVolteView(mState.subId, state.volteIcon, mVolteType); 
        } 
        if (mState.volteIcon != state.volteIcon) { 
            setVolteIcon(state.volteIcon); 
        } 
        /// @} 
        mState = state; 
        // should added after set mState 
        showWfcIfAirplaneMode(); 
        setCustomizedOpViews(); 
        mDataStateListener.setListener(false, state.subId , getContext()); 
    } 

至此信号塔初始化及其刷新流程梳理完毕。

当状态栏背景色发生改变时,信号塔图标会智能变色,回调代码如下: 

    @Override 
    public void onDarkChanged(Rect area, float darkIntensity, int tint) { 
        //TINNO BEGIN 
        //shufeng.liu modify for UDAAP-1571 DATE20181126 
        /*if (!isInArea(area, this)) { 
            return; 
        }*/ 
        darkIntensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0; 
        //TINNO END 
        ColorStateList color = ColorStateList.valueOf(getTint(area, this, tint)); 
        mMobileDrawable.setDarkIntensity(darkIntensity); 
        mIn.setImageTintList(color); 
        mOut.setImageTintList(color); 
        mMobileType.setImageTintList(color); 
        mMobileRoaming.setImageTintList(color); 
        mMobileSprintRoaming.setImageTintList(color); //TINNO UDAAP-322 
        mNetworkType.setImageTintList(color); 
        mVolteType.setImageTintList(color); 
        mDotView.setDecorColor(tint); 
        mDotView.setIconColor(tint, false); 
        mMobile.setImageTintList(color); 
        /// M: Add for plugin items tint handling. @{ 
        mStatusBarExt.setCustomizedPlmnTextTint(tint); 
        mStatusBarExt.setIconTint(color); 
        /// @} 
    } 

猜你喜欢

转载自blog.csdn.net/tj_shenzhendaxue/article/details/88698042