45
45
// (the remaining are placed into More...)
46
46
const NUM_VISIBLE_NETWORKS = 5;
48
const NMAppletHelperInterface = {
49
name: 'org.gnome.network_manager_applet',
51
{ name: 'ConnectToHiddenNetwork', inSignature: '', outSignature: '' },
52
{ name: 'CreateWifiNetwork', inSignature: '', outSignature: '' },
53
{ name: 'ConnectTo8021xNetwork', inSignature: 'oo', outSignature: '' },
54
{ name: 'ConnectTo3gNetwork', inSignature: 'o', outSignature: '' }
57
const NMAppletProxy = DBus.makeProxyClass(NMAppletHelperInterface);
59
48
function macToArray(string) {
60
49
return string.split(':').map(function(el) {
61
50
return parseInt(el, 16);
631
624
this.emit('network-lost');
635
case NetworkManager.DeviceState.NEED_AUTH:
636
// FIXME: make this have a real effect
637
// (currently we rely on a running nm-applet)
638
this.emit('need-auth');
640
case NetworkManager.DeviceState.FAILED:
627
if (newstate == NetworkManager.DeviceState.FAILED) {
641
628
this.emit('activation-failed', reason);
645
631
this._updateStatusItem();
748
734
this.mobileDevice = null;
749
735
this._connectionType = 'ppp';
751
this._applet_proxy = new NMAppletProxy(DBus.session,
752
'org.gnome.network_manager_applet',
753
'/org/gnome/network_manager_applet');
755
737
this._capabilities = device.current_capabilities;
756
738
if (this._capabilities & NetworkManager.DeviceModemCapabilities.GSM_UMTS) {
855
837
_createAutomaticConnection: function() {
856
// Mobile wizard is handled by nm-applet for now...
857
this._applet_proxy.ConnectTo3gNetworkRemote(this.device.get_path(),
858
Lang.bind(this, function(results, err) {
838
// Mobile wizard is too complex for the shell UI and
839
// is handled by the network panel
840
Util.spawn(['gnome-control-center', 'network',
841
'connect-3g', this.device.get_path()]);
985
961
for (let i = 0; i < accessPoints.length; i++) {
986
962
// Access points are grouped by network
987
963
let ap = accessPoints[i];
965
if (ap.get_ssid() == null) {
966
// hidden access point cannot be added, we need to know
967
// the SSID and security details to connect
968
// nevertheless, the access point can acquire a SSID when
969
// NetworkManager connects to it (via nmcli or the control-center)
970
ap._notifySsidId = ap.connect('notify::ssid', Lang.bind(this, this._notifySsidCb));
988
974
let pos = this._findNetwork(ap);
1425
1437
_createActiveConnectionItem: function() {
1426
let activeAp = this.device.active_access_point;
1427
1438
let icon, title;
1428
1439
if (this._activeConnection._connection) {
1429
1440
let connection = this._activeConnection._connection;
1431
this._activeConnectionItem = new NMNetworkMenuItem([ activeAp ], undefined,
1432
{ reactive: false });
1441
if (this._activeNetwork)
1442
this._activeConnectionItem = new NMNetworkMenuItem(this._activeNetwork.accessPoints, undefined,
1443
{ reactive: false });
1434
1445
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(connection._name,
1435
1446
'network-wireless-connected',
1438
1449
// We cannot read the connection (due to ACL, or API incompatibility), but we still show signal if we have it
1441
this._activeConnectionItem = new NMNetworkMenuItem([ activeAp ], undefined,
1442
{ reactive: false });
1451
if (this._activeNetwork)
1452
this._activeConnectionItem = new NMNetworkMenuItem(this._activeNetwork.accessPoints, undefined,
1453
{ reactive: false });
1444
1455
this._activeConnectionItem = new PopupMenu.PopupImageMenuItem(_("Connected (private)"),
1445
1456
'network-wireless-connected',
1486
1497
let accessPoints = sortAccessPoints(apObj.accessPoints);
1487
1498
if ( (accessPoints[0]._secType == NMAccessPointSecurity.WPA2_ENT)
1488
1499
|| (accessPoints[0]._secType == NMAccessPointSecurity.WPA_ENT)) {
1489
// 802.1x-enabled APs get handled by nm-applet for now...
1490
this._applet_proxy.ConnectTo8021xNetworkRemote(this.device.get_path(),
1491
accessPoints[0].dbus_path,
1492
Lang.bind(this, function(results, err) {
1500
// 802.1x-enabled APs require further configuration, so they're
1501
// handled in gnome-control-center
1502
Util.spawn(['gnome-control-center', 'network', 'connect-8021x-wifi',
1503
this.device.get_path(), accessPoints[0].dbus_path]);
1497
1505
let connection = this._createAutomaticConnection(apObj);
1498
1506
this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null)
1565
1573
this._devices.wired.section.addMenuItem(this._devices.wired.item);
1566
this._devices.wired.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1567
1574
this._devices.wired.section.actor.hide();
1568
1575
this.menu.addMenuItem(this._devices.wired.section);
1576
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1570
1578
this._devices.wireless = {
1571
1579
section: new PopupMenu.PopupMenuSection(),
1573
1581
item: this._makeToggleItem('wireless', _("Wireless"))
1575
1583
this._devices.wireless.section.addMenuItem(this._devices.wireless.item);
1576
this._devices.wireless.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1577
1584
this._devices.wireless.section.actor.hide();
1578
1585
this.menu.addMenuItem(this._devices.wireless.section);
1586
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1580
1588
this._devices.wwan = {
1581
1589
section: new PopupMenu.PopupMenuSection(),
1583
1591
item: this._makeToggleItem('wwan', _("Mobile broadband"))
1585
1593
this._devices.wwan.section.addMenuItem(this._devices.wwan.item);
1586
this._devices.wwan.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1587
1594
this._devices.wwan.section.actor.hide();
1588
1595
this.menu.addMenuItem(this._devices.wwan.section);
1596
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1590
1598
this._devices.vpn = {
1591
1599
section: new PopupMenu.PopupMenuSection(),
1598
1606
this._devices.vpn.item.updateForDevice(this._devices.vpn.device);
1599
1607
this._devices.vpn.section.addMenuItem(this._devices.vpn.item);
1600
1608
this._devices.vpn.section.addMenuItem(this._devices.vpn.device.section);
1601
this._devices.vpn.section.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1602
1609
this._devices.vpn.section.actor.hide();
1603
1610
this.menu.addMenuItem(this._devices.vpn.section);
1605
this.menu.addAction(_("Network Settings"), function() {
1606
Main.overview.hide();
1607
let app = Shell.AppSystem.get_default().get_app('gnome-network-panel.desktop');
1611
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
1612
this.menu.addSettingsAction(_("Network Settings"), 'gnome-network-panel.desktop');
1611
1614
this._activeConnections = [ ];
1612
1615
this._connections = [ ];
1660
1663
_ensureSource: function() {
1661
1664
if (!this._source) {
1662
1665
this._source = new NMMessageTraySource();
1663
this._source._destroyId = this._source.connect('destroy', Lang.bind(this, function() {
1664
this._source._destroyId = 0;
1666
this._source.connect('destroy', Lang.bind(this, function() {
1665
1667
this._source = null;
1667
1669
Main.messageTray.add(this._source);
1714
_notifyForDevice: function(device, iconName, title, text, urgency) {
1715
if (device._notification)
1716
device._notification.destroy();
1718
/* must call after destroying previous notification,
1719
or this._source will be cleared */
1720
this._ensureSource();
1722
let icon = new St.Icon({ icon_name: iconName,
1723
icon_type: St.IconType.SYMBOLIC,
1724
icon_size: this._source.ICON_SIZE
1726
device._notification = new MessageTray.Notification(this._source, title, text,
1728
device._notification.setUrgency(urgency);
1729
device._notification.setTransient(true);
1730
device._notification.connect('destroy', function() {
1731
device._notification = null;
1733
this._source.notify(device._notification);
1712
1736
_deviceAdded: function(client, device) {
1713
1737
if (device._delegate) {
1714
1738
// already seen, not adding again
1718
1742
if (wrapperClass) {
1719
1743
let wrapper = new wrapperClass(this._client, device, this._connections);
1721
// FIXME: these notifications are duplicate with those exposed by nm-applet
1722
// uncomment this code in 3.2, when we'll conflict with and kill nm-applet
1723
/* wrapper._networkLostId = wrapper.connect('network-lost', Lang.bind(this, function(emitter) {
1724
this._ensureSource();
1725
let icon = new St.Icon({ icon_name: 'network-offline',
1726
icon_type: St.IconType.SYMBOLIC,
1727
icon_size: this._source.ICON_SIZE
1729
let notification = new MessageTray.Notification(this._source,
1730
_("Connectivity lost"),
1731
_("You're no longer connected to the network"),
1733
this._source.notify(notification);
1745
wrapper._networkLostId = wrapper.connect('network-lost', Lang.bind(this, function(device) {
1746
this._notifyForDevice(device, 'network-offline',
1747
_("Connectivity lost"),
1748
_("You're no longer connected to the network"),
1749
// set critical urgency to popup the notification automatically
1750
MessageTray.Urgency.CRITICAL);
1735
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(wrapper, reason) {
1736
this._ensureSource();
1737
let icon = new St.Icon({ icon_name: 'network-error',
1738
icon_type: St.IconType.SYMBOLIC,
1739
icon_size: this._source.ICON_SIZE,
1752
wrapper._activationFailedId = wrapper.connect('activation-failed', Lang.bind(this, function(device, reason) {
1742
1753
// XXX: nm-applet has no special text depending on reason
1743
1754
// but I'm not sure of this generic message
1744
let notification = new MessageTray.Notification(this._source,
1745
_("Connection failed"),
1746
_("Activation of network connection failed"),
1748
this._source.notify(notification);
1755
this._notifyForDevice(device, 'network-error',
1756
_("Connection failed"),
1757
_("Activation of network connection failed"),
1758
MessageTray.Urgency.HIGH);
1750
1760
wrapper._deviceStateChangedId = wrapper.connect('state-changed', Lang.bind(this, function(dev) {
1751
1761
this._syncSectionTitle(dev.category);
1753
1763
wrapper._destroyId = wrapper.connect('destroy', function(wrapper) {
1754
//wrapper.disconnect(wrapper._networkLostId);
1755
//wrapper.disconnect(wrapper._activationFailedId);
1764
wrapper.disconnect(wrapper._networkLostId);
1765
wrapper.disconnect(wrapper._activationFailedId);
1756
1766
wrapper.disconnect(wrapper._deviceStateChangedId);
1767
wrapper.disconnect(wrapper._destroyId);
1758
1769
let section = this._devices[wrapper.category].section;
1759
1770
let devices = this._devices[wrapper.category].devices;
1820
1828
if (!a._inited) {
1821
1829
a._notifyDefaultId = a.connect('notify::default', Lang.bind(this, this._updateIcon));
1822
1830
a._notifyDefault6Id = a.connect('notify::default6', Lang.bind(this, this._updateIcon));
1823
if (a.state == NetworkManager.ActiveConnectionState.ACTIVATING) // prepare to notify to the user
1824
a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._notifyActiveConnection));
1826
// notify as soon as possible
1827
Mainloop.idle_add(Lang.bind(this, function() {
1828
this._notifyActiveConnection(a);
1831
a._notifyStateId = a.connect('notify::state', Lang.bind(this, this._updateIcon));
1832
1833
a._inited = true;
1877
1878
this._mainConnection = activating || default_ip4 || default_ip6 || this._activeConnections[0] || null;
1880
_notifyActiveConnection: function(active) {
1881
// FIXME: duplicate notifications when nm-applet is running
1882
// This code will come back when nm-applet is killed
1883
this._syncNMState();
1886
if (active.state == NetworkManager.ActiveConnectionState.ACTIVATED) {
1888
// notify only connections that are visible
1889
if (active._connection) {
1890
this._ensureSource();
1894
switch (active._section) {
1895
case NMConnectionCategory.WWAN:
1896
icon = 'network-cellular-signal-excellent';
1897
banner = _("You're now connected to mobile broadband connection '%s'").format(active._connection._name);
1899
case NMConnectionCategory.WIRELESS:
1900
icon = 'network-wireless-signal-excellent';
1901
banner = _("You're now connected to wireless network '%s'").format(active._connection._name);
1903
case NMConnectionCategory.WIRED:
1904
icon = 'network-wired';
1905
banner = _("You're now connected to wired network '%s'").format(active._connection._name);
1907
case NMConnectionCategory.VPN:
1908
icon = 'network-vpn';
1909
banner = _("You're now connected to VPN network '%s'").format(active._connection._name);
1912
// a fallback for a generic 'connected' icon
1913
icon = 'network-transmit-receive';
1914
banner = _("You're now connected to '%s'").format(active._connection._name);
1917
let iconActor = new St.Icon({ icon_name: icon,
1918
icon_type: St.IconType.SYMBOLIC,
1919
icon_size: this._source.ICON_SIZE
1921
let notification = new MessageTray.Notification(this._source,
1922
_("Connection established"),
1924
{ icon: iconActor });
1925
this._source.notify(notification);
1928
if (active._stateChangeId) {
1929
active.disconnect(active._stateChangeId);
1930
active._stateChangeId = 0;
1934
this._syncNMState();
1937
1881
_readConnections: function() {
1938
1882
let connections = this._settings.list_connections();
1939
1883
for (let i = 0; i < connections.length; i++) {