WifiNotificationControllerpublic final class WifiNotificationController extends Object
Fields Summary |
---|
private static final int | ICON_NETWORKS_AVAILABLEThe icon to show in the 'available networks' notification. This will also
be the ID of the Notification given to the NotificationManager. | private final long | NOTIFICATION_REPEAT_DELAY_MSWhen a notification is shown, we wait this amount before possibly showing it again. | private boolean | mNotificationEnabledWhether the user has set the setting to show the 'available networks' notification. | private NotificationEnabledSettingObserver | mNotificationEnabledSettingObserverObserves the user setting to keep {@link #mNotificationEnabled} in sync. | private long | mNotificationRepeatTimeThe {@link System#currentTimeMillis()} must be at least this value for us
to show the notification again. | private android.app.Notification | mNotificationThe Notification object given to the NotificationManager. | private boolean | mNotificationShownWhether the notification is being shown, as set by us. That is, if the
user cancels the notification, we will not receive the callback so this
will still be true. We only guarantee if this is false, then the
notification is not showing. | private static final int | NUM_SCANS_BEFORE_ACTUALLY_SCANNINGThe number of continuous scans that must occur before consider the
supplicant in a scanning state. This allows supplicant to associate with
remembered networks that are in the scan results. | private int | mNumScansSinceNetworkStateChangeThe number of scans since the last network state change. When this
exceeds {@link #NUM_SCANS_BEFORE_ACTUALLY_SCANNING}, we consider the
supplicant to actually be scanning. When the network state changes to
something other than scanning, we reset this to 0. | private final android.content.Context | mContext | private final WifiStateMachine | mWifiStateMachine | private android.net.NetworkInfo | mNetworkInfo | private volatile int | mWifiState |
Constructors Summary |
---|
WifiNotificationController(android.content.Context context, WifiStateMachine wsm)
mContext = context;
mWifiStateMachine = wsm;
mWifiState = WifiManager.WIFI_STATE_UNKNOWN;
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mContext.registerReceiver(
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN);
resetNotification();
} else if (intent.getAction().equals(
WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
WifiManager.EXTRA_NETWORK_INFO);
// reset & clear notification on a network connect & disconnect
switch(mNetworkInfo.getDetailedState()) {
case CONNECTED:
case DISCONNECTED:
case CAPTIVE_PORTAL_CHECK:
resetNotification();
break;
}
} else if (intent.getAction().equals(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
checkAndSetNotification(mNetworkInfo,
mWifiStateMachine.syncGetScanResultsList());
}
}
}, filter);
// Setting is in seconds
NOTIFICATION_REPEAT_DELAY_MS = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l;
mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(new Handler());
mNotificationEnabledSettingObserver.register();
|
Methods Summary |
---|
private synchronized void | checkAndSetNotification(android.net.NetworkInfo networkInfo, java.util.List scanResults)
// TODO: unregister broadcast so we do not have to check here
// If we shouldn't place a notification on available networks, then
// don't bother doing any of the following
if (!mNotificationEnabled) return;
if (mWifiState != WifiManager.WIFI_STATE_ENABLED) return;
NetworkInfo.State state = NetworkInfo.State.DISCONNECTED;
if (networkInfo != null)
state = networkInfo.getState();
if ((state == NetworkInfo.State.DISCONNECTED)
|| (state == NetworkInfo.State.UNKNOWN)) {
if (scanResults != null) {
int numOpenNetworks = 0;
for (int i = scanResults.size() - 1; i >= 0; i--) {
ScanResult scanResult = scanResults.get(i);
//A capability of [ESS] represents an open access point
//that is available for an STA to connect
if (scanResult.capabilities != null &&
scanResult.capabilities.equals("[ESS]")) {
numOpenNetworks++;
}
}
if (numOpenNetworks > 0) {
if (++mNumScansSinceNetworkStateChange >= NUM_SCANS_BEFORE_ACTUALLY_SCANNING) {
/*
* We've scanned continuously at least
* NUM_SCANS_BEFORE_NOTIFICATION times. The user
* probably does not have a remembered network in range,
* since otherwise supplicant would have tried to
* associate and thus resetting this counter.
*/
setNotificationVisible(true, numOpenNetworks, false, 0);
}
return;
}
}
}
// No open networks in range, remove the notification
setNotificationVisible(false, 0, false, 0);
| void | dump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)
pw.println("mNotificationEnabled " + mNotificationEnabled);
pw.println("mNotificationRepeatTime " + mNotificationRepeatTime);
pw.println("mNotificationShown " + mNotificationShown);
pw.println("mNumScansSinceNetworkStateChange " + mNumScansSinceNetworkStateChange);
| private synchronized void | resetNotification()Clears variables related to tracking whether a notification has been
shown recently and clears the current notification.
mNotificationRepeatTime = 0;
mNumScansSinceNetworkStateChange = 0;
setNotificationVisible(false, 0, false, 0);
| private void | setNotificationVisible(boolean visible, int numNetworks, boolean force, int delay)Display or don't display a notification that there are open Wi-Fi networks.
// Since we use auto cancel on the notification, when the
// mNetworksAvailableNotificationShown is true, the notification may
// have actually been canceled. However, when it is false we know
// for sure that it is not being shown (it will not be shown any other
// place than here)
// If it should be hidden and it is already hidden, then noop
if (!visible && !mNotificationShown && !force) {
return;
}
NotificationManager notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
Message message;
if (visible) {
// Not enough time has passed to show the notification again
if (System.currentTimeMillis() < mNotificationRepeatTime) {
return;
}
if (mNotification == null) {
// Cache the Notification object.
mNotification = new Notification();
mNotification.when = 0;
mNotification.icon = ICON_NETWORKS_AVAILABLE;
mNotification.flags = Notification.FLAG_AUTO_CANCEL;
mNotification.contentIntent = TaskStackBuilder.create(mContext)
.addNextIntentWithParentStack(
new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK))
.getPendingIntent(0, 0, null, UserHandle.CURRENT);
}
CharSequence title = mContext.getResources().getQuantityText(
com.android.internal.R.plurals.wifi_available, numNetworks);
CharSequence details = mContext.getResources().getQuantityText(
com.android.internal.R.plurals.wifi_available_detailed, numNetworks);
mNotification.tickerText = title;
mNotification.color = mContext.getResources().getColor(
com.android.internal.R.color.system_notification_accent_color);
mNotification.setLatestEventInfo(mContext, title, details, mNotification.contentIntent);
mNotificationRepeatTime = System.currentTimeMillis() + NOTIFICATION_REPEAT_DELAY_MS;
notificationManager.notifyAsUser(null, ICON_NETWORKS_AVAILABLE, mNotification,
UserHandle.ALL);
} else {
notificationManager.cancelAsUser(null, ICON_NETWORKS_AVAILABLE, UserHandle.ALL);
}
mNotificationShown = visible;
|
|