<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns="http://tizen.org/ns/packages" api-version="5" package="org.tizen.example.Oobe" version="1.0.0">
+<manifest package="org.tizen.example.Oobe" version="1.0.0" api-version="5" xmlns="http://tizen.org/ns/packages">
<profile name="common" />
- <ui-application appid="org.tizen.example.Oobe"
- exec="Oobe.dll"
- type="dotnet"
- multiple="false"
- taskmanage="true"
- nodisplay="false"
- launch_mode="single">
+ <ui-application appid="org.tizen.example.Oobe" exec="Oobe.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
<label>Oobe</label>
<icon>Oobe.png</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
+ <splash-screens />
</ui-application>
+ <shortcut-list />
<privileges>
<privilege>http://tizen.org/privilege/systemsettings.admin</privilege>
+ <privilege>http://tizen.org/privilege/network.get</privilege>
+ <privilege>http://tizen.org/privilege/network.set</privilege>
+ <privilege>http://tizen.org/privilege/network.profile</privilege>
</privileges>
+ <dependencies />
+ <provides-appdefined-privileges />
</manifest>
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
+using System.Threading;
using System.Threading.Tasks;
using Tizen.Network.WiFi;
using Tizen.NUI;
{
public class ApManager : IDisposable
{
- private Func<WiFiAP, View> viewFactory;
private Action<WiFiAP> onTapped;
- //detectors have to be kept separately because of GC, there is no link by ref between View and Detector
- private Dictionary<int, TapGestureDetector> detectors = new Dictionary<int, TapGestureDetector>();
+ private Dictionary<WiFiAP, ApView> apToViewMap = new Dictionary<WiFiAP, ApView>();
+ private CancellationTokenSource updatingCancellation = new CancellationTokenSource();
+
public ObservableCollection<View> Views { get; private set; } = new ObservableCollection<View>();
- public ApManager(Func<WiFiAP, View> viewFactory, Action<WiFiAP> onTapped)
+ public ApManager(Action<WiFiAP> onTapped)
{
- this.viewFactory = viewFactory;
this.onTapped = onTapped;
WiFiManager.ConnectionStateChanged += OnConnectionStateChanged;
- //run rssi updating thread
+ RunUpdatingAps();
}
private void OnConnectionStateChanged(object sender, ConnectionStateChangedEventArgs e)
{
- //find view by ap & recreate it? (wrap view from factory by another view?)
+ if(apToViewMap.TryGetValue(e.AP, out ApView view))
+ {
+ view.Update(e.AP);
+ }
}
- public void UpdateTo(IEnumerable<Tizen.Network.WiFi.WiFiAP> aps)
+ public void UpdateTo(IEnumerable<WiFiAP> aps)
{
UpdateToNaive(aps);
}
- public void UpdateToNaive(IEnumerable<Tizen.Network.WiFi.WiFiAP> aps)
+ public void UpdateToNaive(IEnumerable<WiFiAP> aps)
{
- foreach(var detectorKV in detectors)
+ foreach (var ap in apToViewMap.Keys)
{
- detectorKV.Value.Dispose();
+ ap.Dispose();
}
- detectors.Clear();
-
+ apToViewMap.Clear();
Views.Clear();
+
int idx = 0;
foreach(var ap in aps)
{
- var view = viewFactory(ap);
- Views.Insert(idx, view);
-
- var tap = new TapGestureDetector();
- detectors.Add(idx, tap);
- tap.Attach(view);
+ var view = new ApView();
+ if (apToViewMap.TryAdd(ap, view))
+ {
+ view.Update(ap);
+ view.Detector = new TapGestureDetector();
+ view.Detector.Detected += (s, e) => onTapped(ap);
+ view.Detector.Attach(view);
+ Views.Insert(idx, view);
- tap.Detected += (s, e) => onTapped(ap);
-
- idx++;
+ idx++;
+ }
+ else
+ {
+ Tizen.Log.Error("oobe", $"another AP with the same hash code {ap.NetworkInformation.Essid} {ap.GetHashCode()}");
+ }
}
}
public void Dispose()
{
WiFiManager.ConnectionStateChanged -= OnConnectionStateChanged;
- //stop rssi updating thread
+ updatingCancellation.Cancel();
+ foreach (var ap in apToViewMap.Keys)
+ {
+ ap.Dispose();
+ }
+ }
+
+ private async void RunUpdatingAps()
+ {
+ while (await Delay())
+ {
+ foreach(var (ap,view) in apToViewMap.ToList())
+ {
+ try
+ {
+ ap.Refresh();
+ view.Update(ap);
+ }
+ catch (Exception ex)
+ {
+ Tizen.Log.Error("oobe", $"failed to refresh ap {ap.NetworkInformation.Essid} {ex.ToString()}");
+
+ Views.Remove(view);
+ apToViewMap.Remove(ap);
+ ap.Dispose();
+ }
+ }
+ }
+ }
+
+ private async Task<bool> Delay()
+ {
+ try
+ {
+ await Task.Delay(10_000, updatingCancellation.Token);
+ }
+ catch (Exception)
+ {
+ }
+ return updatingCancellation.IsCancellationRequested == false;
}
}
}
--- /dev/null
+using Oobe.Common.Styles;
+using System;
+using Tizen.Network.WiFi;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+
+namespace Oobe.Wifi.Controls.Wifi
+{
+ public class ApView : View
+ {
+ private TextLabel detail = null;
+ private View range = null;
+
+ //detectors have to be kept separately because of GC, there is no link by ref between View and Detector
+ public TapGestureDetector Detector { get; set; }
+
+ public ApView()
+ {
+ Size = new Size(WifiView.ListItemWidth, WifiView.ListItemHeight);
+ Layout = new AbsoluteLayout();
+ }
+
+ public void Update(WiFiAP wifiAp)
+ {
+ if (range == null)
+ {
+ range = new View()
+ {
+ Position = new Position(39, 32),
+ BackgroundImage = GetRangeImage(wifiAp),
+ };
+ this.Add(range);
+
+ this.Add(new TextLabel(wifiAp.NetworkInformation.Essid)
+ {
+ Position = new Position(78, 28),
+ PixelSize = 20f,
+ TextColor = new Color(0, 0x0C / 255f, 0x2B / 255f, 1.0f),
+ FontFamily = "BreezeSans",
+ FontStyle = FontsStyles.Light(),
+ });
+
+ detail = new TextLabel(GetDetailInfo(wifiAp))
+ {
+ Size = new Size(200, 17), //200 - long enough
+ Position = new Position(79, 56),
+ PixelSize = 14f,
+ TextColor = new Color(0, 0x0C / 255f, 0x2B / 255f, 1.0f),
+ FontFamily = "BreezeSans",
+ FontStyle = FontsStyles.Regular(),
+ };
+ this.Add(detail);
+ }
+ else
+ {
+ range.BackgroundImage = GetRangeImage(wifiAp);
+ detail.Text = GetDetailInfo(wifiAp);
+ }
+ }
+
+ private static string GetDetailInfo(WiFiAP wifiAp)
+ {
+ return wifiAp.NetworkInformation.ConnectionState == WiFiConnectionState.Connected
+ ? "Connected"
+ : "Secured";
+ }
+
+ private static string GetRangeImage(WiFiAP wifiAp)
+ {
+ return System.IO.Path.Combine(NUIApplication.Current.DirectoryInfo.Resource
+ , $"12_icon_wifi{(int)wifiAp.NetworkInformation.RssiLevel}.png");
+ }
+ }
+}
public event Action OnTurnedOff;
public event Action OnScanStarted;
public event Action OnScanFinished;
- public bool IsTurnedOn { get; private set; } = true;
- private int counter = 1; //for verify
- public void TurnWifi()
+ public bool IsTurnedOn => Tizen.Network.WiFi.WiFiManager.IsActive;
+
+ public async Task TurnWifi()
{
if (IsTurnedOn)
{
- //turn off wifi
- IsTurnedOn = false;
- OnTurnedOff?.Invoke();
-
+ await Tizen.Network.WiFi.WiFiManager.DeactivateAsync();
+ if (IsTurnedOn == false)
+ {
+ OnTurnedOff?.Invoke();
+ }
}
else
{
- //for verify
- counter++;
- if (counter % 3 == 0)
+ await Tizen.Network.WiFi.WiFiManager.ActivateAsync();
+ if (IsTurnedOn == false)
{
OnTurningOnFailed?.Invoke();
- return;
}
- //turn on wifi
- //if succesful
- IsTurnedOn = true;
- OnTurnedOn?.Invoke();
+ else
+ {
+ OnTurnedOn?.Invoke();
+ }
}
}
using Oobe.Common.Styles;
using System;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using System.Threading.Tasks;
using Tizen.NUI;
using Tizen.NUI.BaseComponents;
using Tizen.NUI.Components;
public class WifiView : IDisposable
{
private View view = null;
- private int counter = 0;
- private const int listItemWidth = 460;
- private const int listItemHeight = 89;
+ public const int ListItemWidth = 460;
+ public const int ListItemHeight = 89;
private WifiState State { get; set; } = new WifiState();
- private ApManager ApManager { get; set; } = new ApManager(CreateApView, OnApTapped);
+ private ApManager ApManager { get; set; } = new ApManager(OnApTapped);
public View View
{
{
var manualWifi = new View()
{
- Size = new Size(listItemWidth, listItemHeight),
+ Size = new Size(ListItemWidth, ListItemHeight),
Layout = new AbsoluteLayout(),
};
return manualWifi;
}
- private static View CreateApView(Tizen.Network.WiFi.WiFiAP wifiAp)
- {
- var wifi = new View()
- {
- Size = new Size(listItemWidth, listItemHeight),
- Layout = new AbsoluteLayout(),
- };
-
- wifi.Add(new View()
- {
- //Size = new Size(21, 15),
- Position = new Position(39, 32),
- BackgroundImage = System.IO.Path.Combine(NUIApplication.Current.DirectoryInfo.Resource, "12_icon_wifi.svg"),
- });
-
- wifi.Add(new TextLabel(wifiAp.NetworkInformation.Essid)
- {
- Position = new Position(78, 28),
- PixelSize = 20f,
- TextColor = new Color(0, 0x0C / 255f, 0x2B / 255f, 1.0f),
- FontFamily = "BreezeSans",
- FontStyle = FontsStyles.Light(),
- });
-
- var detail = wifiAp.NetworkInformation.ConnectionState == Tizen.Network.WiFi.WiFiConnectionState.Connected
- ? "Connected"
- : "Secured";
- wifi.Add(new TextLabel(detail)
- {
- Position = new Position(79, 56),
- PixelSize = 14f,
- TextColor = new Color(0, 0x0C / 255f, 0x2B / 255f, 1.0f),
- FontFamily = "BreezeSans",
- FontStyle = FontsStyles.Regular(),
- });
- return wifi;
- }
-
private static async void OnApTapped(Tizen.Network.WiFi.WiFiAP wifiAp)
{
Tizen.Log.Debug("oobe", $"connect to wifi {wifiAp.NetworkInformation.Essid}");
scan.ClickEvent += async (s, e) =>
{
scan.IsEnabled = false;
+ ApManager.Views.Clear();
ApManager.UpdateTo(await State.Scan());
ApManager.Views.Add(CreateManualWifiView()); //should be built in listView
scan.IsEnabled = State.IsTurnedOn;
State.OnTurnedOn += () =>
button.Style.BackgroundImage = NUIApplication.Current.DirectoryInfo.Resource + "12_icon_wifion.png";
- button.ClickEvent += (s, e) => State.TurnWifi();
+ button.ClickEvent += async (s, e) => await State.TurnWifi();
return button;
}