相关源码:
\frameworks\base\packages\SystemUI\src\com\android\systemui\Dependency.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBarSignalPolicy.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\CollapsedStatusBarFragment.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBarIconController.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBarIconControllerImpl.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\NetworkController.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\WifiSignalController.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\SignalController.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\NetworkControllerImpl.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\WifiIcons.java

在文章中《Android P SystemUI之StatusBar UI布局status_bar.xml解析》讲到,wifi,蓝牙等系统图标的UI是在system_icons.xml中。

system_icons.xml

<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"    android:orientation="horizontal">    <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>

关键点:android:id="@+id/statusIcons",我需要查看是哪里加载了statusIcons。

CollapsedStatusBarFragment.java

private DarkIconManager mDarkIconManager;@Overridepublic void onViewCreated(View view, @Nullable Bundle savedInstanceState) {    super.onViewCreated(view, savedInstanceState);    mStatusBar = (PhoneStatusBarView) view;    if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) {        mStatusBar.go(savedInstanceState.getInt(EXTRA_PANEL_STATE));    }    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();}

关键点1: mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons));
关键点2:Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);

这里创建了一个DarkIconManager,添加了statusIcons的view,并且添加到StatusBarIconController中。

StatusBarIconController.java

StatusBarIconController是一个接口,并且包含一个DarkIconManager的内部类,

Dependency.java

Dependency也是在SystemBars中启动的,执行如下:

@Overridepublic void start() {//省略一部分代码//...    mProviders.put(StatusBarIconController.class, () ->            new StatusBarIconControllerImpl(mContext));//省略一部分代码//...}

我们只关心StatusBarIconController这一块,实现的是StatusBarIconControllerImpl。

StatusBarIconControllerImpl.java

private final ArrayList<IconManager> mIconGroups = new ArrayList<>();@Overridepublic 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);        }    }}/** * Signal icons need to be handled differently, because they can be * composite views */@Overridepublic void setSignalIcon(String slot, WifiIconState state) {    int index = getSlotIndex(slot);    if (state == null) {        removeIcon(index, 0);        return;    }    StatusBarIconHolder holder = getIcon(index, 0);    if (holder == null) {        holder = StatusBarIconHolder.fromWifiIconState(state);        setIcon(index, holder);    } else {        holder.setWifiState(state);        handleSet(index, holder);    }}@Overridepublic void setIcon(int index, @NonNull StatusBarIconHolder holder) {    boolean isNew = getIcon(index, holder.getTag()) == null;    super.setIcon(index, holder);    if (isNew) {        addSystemIcon(index, holder);    } else {        handleSet(index, holder);    }}private void addSystemIcon(int index, StatusBarIconHolder holder) {    String slot = getSlotName(index);    int viewIndex = getViewIndex(index, holder.getTag());    boolean blocked = mIconBlacklist.contains(slot);    mIconLogger.onIconVisibility(getSlotName(index), holder.isVisible());    mIconGroups.forEach(l -> l.onIconAdded(viewIndex, slot, blocked, holder));}

通过setSignalIcon设置系统图标,包括Wifi,蓝牙等。

StatusBarSignalPolicy.java

    @Override    public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,            boolean activityIn, boolean activityOut, String description, boolean isTransient,            String statusLabel) {        boolean visible = statusIcon.visible && !mBlockWifi;        boolean in = activityIn && mActivityEnabled && visible;        boolean out = activityOut && mActivityEnabled && visible;        WifiIconState newState = mWifiIconState.copy();        newState.visible = visible;        newState.resId = statusIcon.icon;        newState.activityIn = in;        newState.activityOut = out;        newState.slot = mSlotWifi;        newState.airplaneSpacerVisible = mIsAirplaneMode;        newState.contentDescription = statusIcon.contentDescription;        MobileIconState first = getFirstMobileState();        newState.signalSpacerVisible = first != null && first.typeId != 0;        updateWifiIconWithState(newState);        mWifiIconState = newState;    }    private void updateWifiIconWithState(WifiIconState state) {   if (state.visible && state.resId > 0) {       mIconController.setSignalIcon(mSlotWifi, state);       mIconController.setIconVisibility(mSlotWifi, true);   } else {       mIconController.setIconVisibility(mSlotWifi, false);   }}

setWifiIndicators()收到wifi状态变化后执行,调用updateWifiIconWithState()更新图标。

注册Wifi监听回调的地方:

public StatusBarSignalPolicy(Context context, StatusBarIconController iconController) {    mContext = context;    mSlotAirplane = mContext.getString(com.android.internal.R.string.status_bar_airplane);    mSlotMobile   = mContext.getString(com.android.internal.R.string.status_bar_mobile);    mSlotWifi     = mContext.getString(com.android.internal.R.string.status_bar_wifi);    mSlotEthernet = mContext.getString(com.android.internal.R.string.status_bar_ethernet);    mSlotVpn      = mContext.getString(com.android.internal.R.string.status_bar_);    mActivityEnabled = mContext.getResources().getBoolean(R.bool.config_showActivity);    mIconController = iconController;    mNetworkController = Dependency.get(NetworkController.class);    mSecurityController = Dependency.get(SecurityController.class);//注册wifi状态回调    mNetworkController.addCallback(this);    mSecurityController.addCallback(this);}

NetworkController,java

NetworkController包含了接口SignalCallback

WifiSignalController.java

@Overridepublic void notifyListeners(SignalCallback callback) {    // only show wifi in the cluster if connected or if wifi-only    boolean wifiVisible = mCurrentState.enabled            && (mCurrentState.connected || !mHasMobileData);    String wifiDesc = wifiVisible ? mCurrentState.ssid : null;    boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;    String contentDescription = getStringIfExists(getContentDescription());    if (mCurrentState.inetCondition == 0) {        contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));    }    IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);    IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),            contentDescription);    callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,            ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,            wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel);}

回调执行了setWifiIndicators,去更新wifi状态。

NetworkControllerImpl.java

NetworkControllerImpl实现了接口NetworkController,并且保存了StatusBarSignalPolicy的回调对象,监听了wifi状态变化。

NetworkControllerImpl继承了BroadcastReceiver,在onReceive中接收广播。

onReceive()监听了各种状态的变化。

@Overridepublic void onReceive(Context context, Intent intent) {    if (CHATTY) {        Log.d(TAG, "onReceive: intent=" + intent);    }    final String action = intent.getAction();    switch (action) {        case ConnectivityManager.CONNECTIVITY_ACTION:        case ConnectivityManager.INET_CONDITION_ACTION:            updateConnectivity();            break;        case Intent.ACTION_AIRPLANE_MODE_CHANGED:            refreshLocale();            updateAirplaneMode(false);            break;        case TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED:            // We are using different subs now, we might be able to make calls.            recalculateEmergency();            break;        case TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:            // Notify every MobileSignalController so they can know whether they are the            // data sim or not.            for (int i = 0; i < mMobileSignalControllers.size(); i++) {                MobileSignalController controller = mMobileSignalControllers.valueAt(i);                controller.handleBroadcast(intent);            }            break;        case TelephonyIntents.ACTION_SIM_STATE_CHANGED:            // Avoid rebroadcast because SysUI is direct boot aware.            if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {                break;            }            // Might have different subscriptions now.            updateMobileControllers();            break;        case TelephonyIntents.ACTION_SERVICE_STATE_CHANGED:            mLastServiceState = ServiceState.newFromBundle(intent.getExtras());            if (mMobileSignalControllers.size() == 0) {                // If none of the subscriptions are active, we might need to recalculate                // emergency state.                recalculateEmergency();            }            break;        case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:            mConfig = Config.readConfig(mContext);            mReceiverHandler.post(this::handleConfigurationChanged);            break;        default:            int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,                    SubscriptionManager.INVALID_SUBSCRIPTION_ID);            if (SubscriptionManager.isValidSubscriptionId(subId)) {                if (mMobileSignalControllers.indexOfKey(subId) >= 0) {                    mMobileSignalControllers.get(subId).handleBroadcast(intent);                } else {                    // Can't find this subscription...  We must be out of date.                    updateMobileControllers();                }            } else {                // No sub id, must be for the wifi.                mWifiSignalController.handleBroadcast(intent);            }            break;    }}

关注点: mWifiSignalController.handleBroadcast(intent);

WifiIcons.java

Wifi图标显示在WifiIcons定义如下:

public class WifiIcons {    static final int[][] WIFI_SIGNAL_STRENGTH = {            { R.drawable.stat_sys_wifi_signal_0,              R.drawable.stat_sys_wifi_signal_1,              R.drawable.stat_sys_wifi_signal_2,              R.drawable.stat_sys_wifi_signal_3,              R.drawable.stat_sys_wifi_signal_4 },            { R.drawable.stat_sys_wifi_signal_0_fully,              R.drawable.stat_sys_wifi_signal_1_fully,              R.drawable.stat_sys_wifi_signal_2_fully,              R.drawable.stat_sys_wifi_signal_3_fully,              R.drawable.stat_sys_wifi_signal_4_fully }        };    public static final int[][] QS_WIFI_SIGNAL_STRENGTH = {            { R.drawable.ic_qs_wifi_0,              R.drawable.ic_qs_wifi_1,              R.drawable.ic_qs_wifi_2,              R.drawable.ic_qs_wifi_3,              R.drawable.ic_qs_wifi_4 },            { R.drawable.ic_qs_wifi_full_0,              R.drawable.ic_qs_wifi_full_1,              R.drawable.ic_qs_wifi_full_2,              R.drawable.ic_qs_wifi_full_3,              R.drawable.ic_qs_wifi_full_4 }        };    static final int QS_WIFI_NO_NETWORK = R.drawable.ic_qs_wifi_no_network;    static final int WIFI_NO_NETWORK = R.drawable.stat_sys_wifi_signal_null;    static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length;}

整理一下wifi信号发生的整个流程:

NetworkControllerImpl–>WifiSignalController–>SignalController–>WifiSignalController–>StatusBarSignalPolicy–>StatusBarIconController–>StatusBarIconControllerImpl–>CollapsedStatusBarFragment–>system_icons.xml

其中WifiSignalController

更多相关文章

  1. android 获取以太网的连接状态
  2. android 判断网络连接状态
  3. 各Android版本WifiStateMachine状态机
  4. android 蓝牙打印程序源代码
  5. 如何修改 Android 状态栏高度?
  6. Android菜鸟的成长笔记(15)—— Android中的状态保存探究(下)
  7. Android 蓝牙开发(整理大全)
  8. android 实现根据receiver的注册状态 进行register或unregister
  9. Android去掉状态栏和标题栏的两种方式

随机推荐

  1. IBM X6服务器linux数据恢复过程
  2. 抖音用户评论和ID的采集方法
  3. 0802 PHP编程作业
  4. php foreach循环语句
  5. 08-03作业
  6. 1. php变量的8种数据类型? 2. php变量类型
  7. PHP基础课第二次作业
  8. 作业标题:0803 php变量与常量作业
  9. php变量与常量
  10. 数据类型及类型转换