From 5c46b171392ac6c49b56eae7bf1e636d3d854c08 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 14 Apr 2012 08:33:56 -0400 Subject: [PATCH] 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. --- src/apps/networkstatus/NetworkStatusView.cpp | 105 ++++++++++--------- src/apps/networkstatus/NetworkStatusView.h | 11 +- 2 files changed, 65 insertions(+), 51 deletions(-) diff --git a/src/apps/networkstatus/NetworkStatusView.cpp b/src/apps/networkstatus/NetworkStatusView.cpp index 94ce723882..d04a69dc7e 100644 --- a/src/apps/networkstatus/NetworkStatusView.cpp +++ b/src/apps/networkstatus/NetworkStatusView.cpp @@ -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, axeld@pinc-software.de * Hugo Santos, hugosantos@gmail.com * Dario Casalinuovo + * Rene Gollent, rene@gollent.com */ @@ -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::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::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 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(); - } } diff --git a/src/apps/networkstatus/NetworkStatusView.h b/src/apps/networkstatus/NetworkStatusView.h index 09c7661973..8508efe6cc 100644 --- a/src/apps/networkstatus/NetworkStatusView.h +++ b/src/apps/networkstatus/NetworkStatusView.h @@ -14,7 +14,10 @@ #include #include +#include + 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 fInterfaces; + std::map + fInterfaceStatuses; bool fInDeskbar; BBitmap* fTrayIcons[kStatusCount]; BBitmap* fNotifyIcons[kStatusCount]; - int32 fStatus; }; #endif // NETWORK_STATUS_VIEW_H