查看WIFI中WLAN偏好设置功能是否正常代码流程的步骤:
根据字符查找出对应的字符串
grep -r “打开网络通知” packages/apps/Settings
packages/apps/Settings/res/values-zh-rCN/strings.xml: “打开网络通知”
进一步通过命令查找对应的字符
grep -r “wifi_notify_open_networks” packages/apps/Settings
packages/apps/Settings/res/xml/wifi_configure_settings.xml: android:title="@string/wifi_notify_open_networks"
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="wifi_configure_settings_screen"
android:title="@string/wifi_configure_settings_preference_title">
<SwitchPreference
android:key="enable_wifi_wakeup"
android:title="@string/wifi_wakeup"
android:icon="@drawable/ic_auto_wifi"
android:summary="@string/wifi_wakeup_summary" />
<SwitchPreference
android:key="use_open_wifi_automatically"
android:icon="@drawable/ic_open_wifi_autoconnect"
android:title="@string/use_open_wifi_automatically_title"
android:summary="@string/use_open_wifi_automatically_summary" />
//省略其他
</PreferenceScreen>
知道其key值为:notify_open_networks,然后通过key值属性继续往下跟踪, 可以知道其所在路径文件是:
packages/apps/Settings/src/com/android/settings/wifi/NotifyOpenNetworksPreferenceController.java: private static final String KEY_NOTIFY_OPEN_NETWORKS = “notify_open_networks”;
查看下知道Switch开关所控制的Setting字符是:
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON
其对应的菜单点击事件是
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), KEY_NOTIFY_OPEN_NETWORKS)) {
return false;
}
if (!(preference instanceof SwitchPreference)) {
return false;
}
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
((SwitchPreference) preference).isChecked() ? 1 : 0);
return true;
}
得到对应的Setting控制节点后,需要查看该节点控制的函数位置,通过查找可以知道该控制函数位于framework/opt/net/wifi/serivce下
frameworks/opt/net/wifi/service/java/com/android/server/wifi/OpenNetworkNotifier.java: Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON;
public class OpenNetworkNotifier extends AvailableNetworkNotifier {
public static final String TAG = "WifiOpenNetworkNotifier";
private static final String STORE_DATA_IDENTIFIER = "OpenNetworkNotifierBlacklist";
private static final String TOGGLE_SETTINGS_NAME =
Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON;
public OpenNetworkNotifier(
Context context,
Looper looper,
FrameworkFacade framework,
Clock clock,
WifiMetrics wifiMetrics,
WifiConfigManager wifiConfigManager,
WifiConfigStore wifiConfigStore,
WifiStateMachine wifiStateMachine,
ConnectToNetworkNotificationBuilder connectToNetworkNotificationBuilder) {
super(TAG, STORE_DATA_IDENTIFIER, TOGGLE_SETTINGS_NAME,
SystemMessage.NOTE_NETWORK_AVAILABLE, context, looper, framework, clock,
wifiMetrics, wifiConfigManager, wifiConfigStore, wifiStateMachine,
connectToNetworkNotificationBuilder);
}
}
OpenNetworkNotifier 主要是继承函数AvailableNetworkNotifier 实现,而我们需要关注点是其传递的参数:
第二个参数:STORE_DATA_IDENTIFIER
第三个参数:TOGGLE_SETTINGS_NAME 即 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON
第四个参数:SystemMessage.NOTE_NETWORK_AVAILABLE
然后查看AvailableNetworkNotifier 中的具体调用过程,其初始化过程如下:
frameworks/opt/net/wifi/service/java/com/android/server/wifi/AvailableNetworkNotifier.java
public AvailableNetworkNotifier(
String tag,
String storeDataIdentifier,
String toggleSettingsName,
int notificationIdentifier,
Context context,
Looper looper,
FrameworkFacade framework,
Clock clock,
WifiMetrics wifiMetrics,
WifiConfigManager wifiConfigManager,
WifiConfigStore wifiConfigStore,
WifiStateMachine wifiStateMachine,
ConnectToNetworkNotificationBuilder connectToNetworkNotificationBuilder) {
mTag = tag;
mStoreDataIdentifier = storeDataIdentifier;
mToggleSettingsName = toggleSettingsName;
mSystemMessageNotificationId = notificationIdentifier;
mContext = context;
mHandler = new Handler(looper);
mFrameworkFacade = framework;
mWifiMetrics = wifiMetrics;
mClock = clock;
mConfigManager = wifiConfigManager;
mWifiStateMachine = wifiStateMachine;
mNotificationBuilder = connectToNetworkNotificationBuilder;
mScreenOn = false;
mSrcMessenger = new Messenger(new Handler(looper, mConnectionStateCallback));
mBlacklistedSsids = new ArraySet<>();
wifiConfigStore.registerStoreData(new SsidSetStoreData(mStoreDataIdentifier,
new AvailableNetworkNotifierStoreData()));
// Setting is in seconds
mNotificationRepeatDelay = mFrameworkFacade.getIntegerSetting(context,
Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
DEFAULT_REPEAT_DELAY_SEC) * 1000L;
NotificationEnabledSettingObserver settingObserver = new NotificationEnabledSettingObserver(
mHandler);
settingObserver.register();
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USER_DISMISSED_NOTIFICATION);
filter.addAction(ACTION_CONNECT_TO_NETWORK);
filter.addAction(ACTION_PICK_WIFI_NETWORK);
filter.addAction(ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE);
mContext.registerReceiver(
mBroadcastReceiver, filter, null /* broadcastPermission */, mHandler);
}
我们重点需要关注的参数是:
mToggleSettingsName = toggleSettingsName;
mSystemMessageNotificationId = notificationIdentifier;
函数对Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON参数的监听处于以下函数中:
private class NotificationEnabledSettingObserver extends ContentObserver {
NotificationEnabledSettingObserver(Handler handler) {
super(handler);
}
public void register() {
mFrameworkFacade.registerContentObserver(mContext,
Settings.Global.getUriFor(mToggleSettingsName), true, this);
mSettingEnabled = getValue();
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
mSettingEnabled = getValue();
clearPendingNotification(true /* resetRepeatTime */);
}
private boolean getValue() {
boolean enabled =
mFrameworkFacade.getIntegerSetting(mContext, mToggleSettingsName, 1) == 1;
mWifiMetrics.setIsWifiNetworksAvailableNotificationEnabled(mTag, enabled);
Log.d(mTag, "Settings toggle enabled=" + enabled);
return enabled;
}
}
通过以上函数的判断主要输出的参数是:mSettingEnabled,而其判断函数是:
private boolean isControllerEnabled() {
return mSettingEnabled && !UserManager.get(mContext)
.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, UserHandle.CURRENT);
}
进而找到对WIFI的扫描结果的处理是:
public void handleScanResults(@NonNull List<ScanDetail> availableNetworks) {
if (!isControllerEnabled()) {
clearPendingNotification(true /* resetRepeatTime */);
return;
}
if (availableNetworks.isEmpty() && mState == STATE_SHOWING_RECOMMENDATION_NOTIFICATION) {
clearPendingNotification(false /* resetRepeatTime */);
return;
}
// Not enough time has passed to show a recommendation notification again
if (mState == STATE_NO_NOTIFICATION
&& mClock.getWallClockMillis() < mNotificationRepeatTime) {
return;
}
// Do nothing when the screen is off and no notification is showing.
if (mState == STATE_NO_NOTIFICATION && !mScreenOn) {
return;
}
// Only show a new or update an existing recommendation notification.
if (mState == STATE_NO_NOTIFICATION
|| mState == STATE_SHOWING_RECOMMENDATION_NOTIFICATION) {
ScanResult recommendation =
recommendNetwork(availableNetworks, new ArraySet<>(mBlacklistedSsids));
if (recommendation != null) {
postInitialNotification(recommendation);
} else {
clearPendingNotification(false /* resetRepeatTime */);
}
}
}
此处比较明了Notify的显示和Cancel函数:
//Clear notification
public void clearPendingNotification(boolean resetRepeatTime) {
if (resetRepeatTime) {
mNotificationRepeatTime = 0;
}
if (mState != STATE_NO_NOTIFICATION) {
getNotificationManager().cancel(mSystemMessageNotificationId);
if (mRecommendedNetwork != null) {
Log.d(mTag, "Notification with state="
+ mState
+ " was cleared for recommended network: "
+ mRecommendedNetwork.SSID);
}
mState = STATE_NO_NOTIFICATION;
mRecommendedNetwork = null;
}
}
//notification的显示:
private void postNotification(Notification notification) {
getNotificationManager().notify(mSystemMessageNotificationId, notification);
}
private void handleConnectToNetworkAction() {
mWifiMetrics.incrementConnectToNetworkNotificationAction(mTag, mState,
ConnectToNetworkNotificationAndActionCount.ACTION_CONNECT_TO_NETWORK);
if (mState != STATE_SHOWING_RECOMMENDATION_NOTIFICATION) {
return;
}
postNotification(mNotificationBuilder.createNetworkConnectingNotification(mTag,
mRecommendedNetwork));
mWifiMetrics.incrementConnectToNetworkNotification(mTag,
ConnectToNetworkNotificationAndActionCount.NOTIFICATION_CONNECTING_TO_NETWORK);
Log.d(mTag,
"User initiated connection to recommended network: " + mRecommendedNetwork.SSID);
WifiConfiguration network = createRecommendedNetworkConfig(mRecommendedNetwork);
Message msg = Message.obtain();
msg.what = WifiManager.CONNECT_NETWORK;
msg.arg1 = WifiConfiguration.INVALID_NETWORK_ID;
msg.obj = network;
msg.replyTo = mSrcMessenger;
mWifiStateMachine.sendMessage(msg);
mState = STATE_CONNECTING_IN_NOTIFICATION;
mHandler.postDelayed(
() -> {
if (mState == STATE_CONNECTING_IN_NOTIFICATION) {
handleConnectionFailure();
}
},
TIME_TO_SHOW_CONNECTING_MILLIS);
}
至此基本找出WIFI 当有开放网络流程时候的通知栏状态的提示信息。