Rework NetworkStatus's status tracking a bit.
NetworkStatus now tracks the status of each interface separately, and uses that information to make correct comparisons for notifications. Previously, it would only send notifications using whatever interface was last in the enumeration list, and if an earlier interface had a higher configuration level than that, the notification would incorrectly be sent as occurring on the last interface. We now send notifications for each interface separately. The status shown by the deskbar icon remains that of the most highly configured detected interface. Fixes #8468.
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
/*
|
||||
* Copyright 2006-2009, Haiku, Inc. All rights reserved.
|
||||
* Copyright 2006-2012, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, [email protected]
|
||||
* Hugo Santos, [email protected]
|
||||
* Dario Casalinuovo
|
||||
* Rene Gollent, [email protected]
|
||||
*/
|
||||
|
||||
|
||||
@@ -105,8 +106,7 @@ NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode,
|
||||
bool inDeskbar)
|
||||
: BView(frame, kDeskbarItemName, resizingMode,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS),
|
||||
fInDeskbar(inDeskbar),
|
||||
fStatus(kStatusUnknown)
|
||||
fInDeskbar(inDeskbar)
|
||||
{
|
||||
_Init();
|
||||
|
||||
@@ -326,11 +326,18 @@ NetworkStatusView::FrameResized(float width, float height)
|
||||
void
|
||||
NetworkStatusView::Draw(BRect updateRect)
|
||||
{
|
||||
if (fTrayIcons[fStatus] == NULL)
|
||||
int32 status = kStatusUnknown;
|
||||
for (std::map<BString, int32>::const_iterator it
|
||||
= fInterfaceStatuses.begin(); it != fInterfaceStatuses.end(); ++it) {
|
||||
if (it->second > status)
|
||||
status = it->second;
|
||||
}
|
||||
|
||||
if (fTrayIcons[status] == NULL)
|
||||
return;
|
||||
|
||||
SetDrawingMode(B_OP_ALPHA);
|
||||
DrawBitmap(fTrayIcons[fStatus]);
|
||||
DrawBitmap(fTrayIcons[status]);
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
}
|
||||
|
||||
@@ -409,11 +416,14 @@ NetworkStatusView::MouseDown(BPoint point)
|
||||
BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
||||
menu->SetAsyncAutoDestruct(true);
|
||||
menu->SetFont(be_plain_font);
|
||||
BString wifiInterface;
|
||||
BNetworkDevice wifiDevice;
|
||||
|
||||
// Add interfaces
|
||||
|
||||
for (int32 i = 0; i < fInterfaces.CountItems(); i++) {
|
||||
BString& name = *fInterfaces.ItemAt(i);
|
||||
for (std::map<BString, int32>::const_iterator it
|
||||
= fInterfaceStatuses.begin(); it != fInterfaceStatuses.end(); ++it) {
|
||||
const BString& name = it->first;
|
||||
|
||||
BString label = name;
|
||||
label += ": ";
|
||||
@@ -423,30 +433,33 @@ NetworkStatusView::MouseDown(BPoint point)
|
||||
BMessage* info = new BMessage(kMsgShowConfiguration);
|
||||
info->AddString("interface", name.String());
|
||||
menu->AddItem(new BMenuItem(label.String(), info));
|
||||
|
||||
// We only show the networks of the first wireless device we find.
|
||||
if (wifiInterface.IsEmpty()) {
|
||||
wifiDevice.SetTo(name);
|
||||
if (wifiDevice.IsWireless())
|
||||
wifiInterface = name;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fInterfaces.IsEmpty())
|
||||
if (!fInterfaceStatuses.empty())
|
||||
menu->AddSeparatorItem();
|
||||
|
||||
// Add wireless networks, if any
|
||||
|
||||
for (int32 i = 0; i < fInterfaces.CountItems(); i++) {
|
||||
BNetworkDevice device(fInterfaces.ItemAt(i)->String());
|
||||
if (!device.IsWireless())
|
||||
continue;
|
||||
|
||||
if (!wifiInterface.IsEmpty()) {
|
||||
std::set<BNetworkAddress> associated;
|
||||
BNetworkAddress address;
|
||||
uint32 cookie = 0;
|
||||
while (device.GetNextAssociatedNetwork(cookie, address) == B_OK)
|
||||
while (wifiDevice.GetNextAssociatedNetwork(cookie, address) == B_OK)
|
||||
associated.insert(address);
|
||||
|
||||
wireless_network network;
|
||||
int32 count = 0;
|
||||
cookie = 0;
|
||||
while (device.GetNextNetwork(cookie, network) == B_OK) {
|
||||
while (wifiDevice.GetNextNetwork(cookie, network) == B_OK) {
|
||||
BMessage* message = new BMessage(kMsgJoinNetwork);
|
||||
message->AddString("device", device.Name());
|
||||
message->AddString("device", wifiInterface);
|
||||
message->AddString("name", network.name);
|
||||
|
||||
BMenuItem* item = new WirelessNetworkMenuItem(network.name,
|
||||
@@ -465,9 +478,6 @@ NetworkStatusView::MouseDown(BPoint point)
|
||||
menu->AddItem(item);
|
||||
}
|
||||
menu->AddSeparatorItem();
|
||||
|
||||
// We only show the networks of the first wireless device we find.
|
||||
break;
|
||||
}
|
||||
|
||||
menu->AddItem(new BMenuItem(B_TRANSLATE(
|
||||
@@ -522,9 +532,9 @@ NetworkStatusView::_PrepareRequest(struct ifreq& request, const char* name)
|
||||
|
||||
|
||||
int32
|
||||
NetworkStatusView::_DetermineInterfaceStatus(const char* name)
|
||||
NetworkStatusView::_DetermineInterfaceStatus(
|
||||
const BNetworkInterface& interface)
|
||||
{
|
||||
BNetworkInterface interface(name);
|
||||
uint32 flags = interface.Flags();
|
||||
int32 status = kStatusNoLink;
|
||||
|
||||
@@ -542,41 +552,40 @@ NetworkStatusView::_DetermineInterfaceStatus(const char* name)
|
||||
void
|
||||
NetworkStatusView::_Update(bool force)
|
||||
{
|
||||
int32 oldStatus = fStatus;
|
||||
fStatus = kStatusUnknown;
|
||||
fInterfaces.MakeEmpty();
|
||||
|
||||
BNetworkRoster& roster = BNetworkRoster::Default();
|
||||
BNetworkInterface interface;
|
||||
uint32 cookie = 0;
|
||||
|
||||
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
|
||||
if ((interface.Flags() & IFF_LOOPBACK) == 0) {
|
||||
fInterfaces.AddItem(new BString(interface.Name()));
|
||||
int32 status = _DetermineInterfaceStatus(interface.Name());
|
||||
if (status > fStatus)
|
||||
fStatus = status;
|
||||
int32 oldStatus = kStatusUnknown;
|
||||
if (fInterfaceStatuses.find(interface.Name())
|
||||
!= fInterfaceStatuses.end()) {
|
||||
oldStatus = fInterfaceStatuses[interface.Name()];
|
||||
}
|
||||
int32 status = _DetermineInterfaceStatus(interface);
|
||||
if (oldStatus != status) {
|
||||
BNotification notification(B_INFORMATION_NOTIFICATION);
|
||||
notification.SetGroup(B_TRANSLATE("Network Status"));
|
||||
notification.SetTitle(interface.Name());
|
||||
notification.SetMessageID(interface.Name());
|
||||
notification.SetIcon(fNotifyIcons[status]);
|
||||
if (status == kStatusConnecting
|
||||
|| (status == kStatusReady
|
||||
&& oldStatus == kStatusConnecting)
|
||||
|| (status == kStatusNoLink
|
||||
&& oldStatus == kStatusReady)
|
||||
|| (status == kStatusNoLink
|
||||
&& oldStatus == kStatusConnecting)) {
|
||||
// A significant state change, raise notification.
|
||||
notification.SetContent(kStatusDescriptions[status]);
|
||||
notification.Send();
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
fInterfaceStatuses[interface.Name()] = status;
|
||||
}
|
||||
}
|
||||
|
||||
if (fStatus != oldStatus) {
|
||||
// A little notification on major status changes for primary interface
|
||||
BNotification notification(B_INFORMATION_NOTIFICATION);
|
||||
notification.SetGroup(B_TRANSLATE("Network Status"));
|
||||
notification.SetTitle(interface.Name());
|
||||
notification.SetMessageID(interface.Name());
|
||||
notification.SetIcon(fNotifyIcons[fStatus]);
|
||||
if (fStatus == kStatusConnecting
|
||||
|| (fStatus == kStatusReady && oldStatus == kStatusConnecting)
|
||||
|| (fStatus == kStatusNoLink && oldStatus == kStatusReady)
|
||||
|| (fStatus == kStatusNoLink && oldStatus == kStatusConnecting)) {
|
||||
// A significant state change, raise notification.
|
||||
notification.SetContent(kStatusDescriptions[fStatus]);
|
||||
notification.Send();
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
#include <ObjectList.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
class BMessageRunner;
|
||||
class BNetworkInterface;
|
||||
|
||||
|
||||
enum {
|
||||
@@ -27,6 +30,7 @@ enum {
|
||||
kStatusCount
|
||||
};
|
||||
|
||||
|
||||
class NetworkStatusView : public BView {
|
||||
public:
|
||||
NetworkStatusView(BRect frame, int32 resizingMode,
|
||||
@@ -53,15 +57,16 @@ class NetworkStatusView : public BView {
|
||||
void _ShowConfiguration(BMessage* message);
|
||||
bool _PrepareRequest(struct ifreq& request,
|
||||
const char* name);
|
||||
int32 _DetermineInterfaceStatus(const char* name);
|
||||
int32 _DetermineInterfaceStatus(
|
||||
const BNetworkInterface& interface);
|
||||
void _Update(bool force = false);
|
||||
void _OpenNetworksPreferences();
|
||||
|
||||
BObjectList<BString> fInterfaces;
|
||||
std::map<BString, int32>
|
||||
fInterfaceStatuses;
|
||||
bool fInDeskbar;
|
||||
BBitmap* fTrayIcons[kStatusCount];
|
||||
BBitmap* fNotifyIcons[kStatusCount];
|
||||
int32 fStatus;
|
||||
};
|
||||
|
||||
#endif // NETWORK_STATUS_VIEW_H
|
||||
|
||||
Reference in New Issue
Block a user