Skip to content

Commit 06adb83

Browse files
committed
Update to MobileShell Alpha r709
- Battery status (charging, normal, saving) - Detects (like w10m): Focus Assist Location usage WiFi (partially broken) Cellular (+ dual sim) -> WIP, expected to be broken Tablet mode or Desktop mode (expected to be broken)
1 parent 008431c commit 06adb83

19 files changed

+1386
-106
lines changed

src/App.xaml.cs

Lines changed: 200 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
using MobileShell.Classes;
22
using System;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.Runtime.InteropServices;
6+
using System.Text;
37
using System.Threading;
8+
using System.Threading.Tasks;
49
using System.Windows;
510
using System.Windows.Forms;
611
using System.Windows.Media;
12+
using Windows.ApplicationModel.Background;
13+
using Windows.ApplicationModel.Calls;
14+
using Windows.ApplicationModel.Calls.Provider;
15+
using Windows.ApplicationModel.CommunicationBlocking;
16+
using Windows.Devices.Radios;
17+
using Windows.Networking.Connectivity;
18+
using Windows.Networking.NetworkOperators;
19+
using Windows.Phone.Notification.Management;
20+
using Windows.System.Power;
721
using static MobileShell.Classes.NativeMethods;
22+
using MessageBox = System.Windows.MessageBox;
823

924
namespace MobileShell
1025
{
@@ -14,13 +29,17 @@ namespace MobileShell
1429
public partial class App : System.Windows.Application
1530
{
1631
public static float DPI { get; private set; } = 1F;
32+
public static bool IsTabletMode { get; set; }
1733
public static HookEngine Kbh { get; set; }
1834

35+
//We don't wanna GC to collect this, right? *yells*
36+
private WnfQueries.WnfUserCallback wnfCallback;
37+
1938
#region Main instances of Window(s)
2039

21-
private StatusBarWindow stBar;
22-
private TaskbarWindow tkBar;
23-
private VolumeAudioFlyout vlFly;
40+
private static StatusBarWindow stBar;
41+
private static TaskbarWindow tkBar;
42+
private static VolumeAudioFlyout vlFly;
2443

2544
#endregion
2645

@@ -32,31 +51,125 @@ private void Application_Startup(object sender, StartupEventArgs e)
3251

3352
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
3453

35-
Kbh = new HookEngine();
36-
Kbh.OnKeyPressed += kbh_OnKeyPressed;
37-
Kbh.OnKeyUnpressed += kbh_OnKeyUnpressed;
38-
Kbh.HookKeyboard();
54+
//Kbh = new HookEngine();
55+
//Kbh.OnKeyPressed += kbh_OnKeyPressed;
56+
//Kbh.OnKeyUnpressed += kbh_OnKeyUnpressed;
57+
//Kbh.HookKeyboard();
58+
59+
ShutdownMode = ShutdownMode.OnExplicitShutdown;
3960

40-
4161
stBar = new StatusBarWindow();
4262
tkBar = new TaskbarWindow();
43-
vlFly = new VolumeAudioFlyout();
44-
45-
DPI = (float)VisualTreeHelper.GetDpi(stBar).DpiScaleX;
63+
//vlFly = new VolumeAudioFlyout();
4664

4765
stBar.Show();
4866
tkBar.Show();
4967

50-
Configure();
68+
69+
//TODO: REMOVE
70+
//stBar.SetVisibility(Visibility.Visible);
71+
//tkBar.SetVisibility(Visibility.Visible);
72+
////stBar.UpdateAppBar(); //STACK OVERFLOW EXCEPTION !!!!111!!!11!
73+
//stBar.SetupAppBar();
74+
////tkBar.UpdateAppBar();
75+
//tkBar.SetupAppBar();
76+
//HideExplorerTaskbar();
77+
////END TODO.
78+
79+
80+
DPI = (float)VisualTreeHelper.GetDpi(stBar).DpiScaleX;
81+
82+
PowerManager.BatteryStatusChanged += (_, __) => stBar?.UpdateBatteryIconAndPercentage();
83+
PowerManager.EnergySaverStatusChanged += (_, __) => stBar?.UpdateBatteryIconAndPercentage();
84+
PowerManager.RemainingChargePercentChanged += (_, __) => stBar?.UpdateBatteryIconAndPercentage();
85+
NetworkInformation.NetworkStatusChanged += (_) => stBar?.UpdateNetworkState();
86+
87+
//RadioAsync();
88+
89+
//It will hang if we await it.
90+
NotifAsync();
91+
92+
wnfCallback = WnfStateUpdates;
93+
94+
WnfQueries.SubscribeWnf(WnfQueries.WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED, wnfCallback);
95+
WnfQueries.SubscribeWnf(WnfQueries.WNF_SHEL_NOTIFICATIONS, wnfCallback);
96+
WnfQueries.SubscribeWnf(WnfQueries.WNF_LFS_STATE, wnfCallback);
97+
WnfQueries.SubscribeWnf(WnfQueries.WNF_TMCN_ISTABLETMODE, wnfCallback);
98+
WnfQueries.SubscribeWnf(WnfQueries.WNF_CELL_SIGNAL_STRENGTH_BARS_CAN0, wnfCallback);
99+
WnfQueries.SubscribeWnf(WnfQueries.WNF_CELL_SIGNAL_STRENGTH_BARS_CAN1, wnfCallback);
51100
}
52101

53-
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
102+
private async Task NotifAsync()
54103
{
104+
var phoneLines = await GetPhoneLinesAsync();
105+
var isDualSim = phoneLines.Count > 1;
106+
107+
//PhoneCallManager.CallStateChanged += PhoneCallManager_CallStateChanged;
108+
109+
foreach (var phoneLine in phoneLines)
110+
{
111+
stBar.AddPhoneLine(phoneLine, isDualSim);
112+
//phoneLine.LineChanged += PhoneLine_LineChanged;
113+
}
114+
}
115+
116+
private void PhoneCallManager_CallStateChanged(object sender, object e)
117+
{
118+
//throw new NotImplementedException();
55119

56120
}
121+
122+
private void PhoneLine_LineChanged(PhoneLine sender, object args)
123+
{
124+
125+
}
126+
127+
private async Task<List<PhoneLine>> GetPhoneLinesAsync()
128+
{
129+
PhoneCallStore store = await PhoneCallManager.RequestStoreAsync();
130+
var watcher = store.RequestLineWatcher();
131+
var phoneLines = new List<PhoneLine>();
132+
var lineEnumerationCompletion = new TaskCompletionSource<bool>();
133+
134+
watcher.LineAdded += async (o, args) => { var line = await PhoneLine.FromIdAsync(args.LineId); phoneLines.Add(line); };
135+
watcher.Stopped += (o, args) => lineEnumerationCompletion.TrySetResult(false);
136+
watcher.EnumerationCompleted += (o, args) => lineEnumerationCompletion.TrySetResult(true);
137+
138+
watcher.Start();
139+
140+
if (!await lineEnumerationCompletion.Task)
141+
throw new Exception("Phone Line Enumeration failed");
142+
143+
watcher.Stop();
144+
145+
List<PhoneLine> returnedLines = new List<PhoneLine>();
146+
147+
foreach (PhoneLine phoneLine in phoneLines)
148+
if (phoneLine != null && phoneLine.Transport == PhoneLineTransport.Cellular)
149+
returnedLines.Add(phoneLine);
150+
151+
return returnedLines;
152+
}
153+
154+
public static void ResetWorkArea()
155+
{
156+
RECT oldWorkArea;
157+
oldWorkArea.Left = Screen.PrimaryScreen.Bounds.Left;
158+
oldWorkArea.Top = Screen.PrimaryScreen.Bounds.Top;
159+
oldWorkArea.Right = Screen.PrimaryScreen.Bounds.Width;
160+
oldWorkArea.Bottom = Screen.PrimaryScreen.Bounds.Height;
161+
162+
SystemParametersInfo(SPI_SETWORKAREA, 0, ref oldWorkArea, 1 | 2);
163+
}
164+
165+
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
166+
{
167+
MessageBox.Show("RIP: \n" + e.Exception.Message);
168+
}
169+
57170
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
58171
{
59-
System.Windows.MessageBox.Show("RIP");
172+
MessageBox.Show("RIP: \n" + e.ExceptionObject);
60173
}
61174

62175
private void kbh_OnKeyUnpressed(object sender, VirtualKeyShort e)
@@ -69,11 +182,79 @@ private void kbh_OnKeyPressed(object sender, VirtualKeyShort e)
69182

70183
}
71184

72-
public static void Configure()
185+
public static void ResetScreenCache()
73186
{
74-
//Useless?
187+
// use reflection to empty screens cache
188+
typeof(Screen).GetField("screens", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).SetValue(null, null);
189+
}
75190

76-
HideExplorerTaskbar();
191+
//ToDo clean code.
192+
public IntPtr WnfStateUpdates(ulong stateName, uint changeStamp, IntPtr typeId, IntPtr callbackContext, IntPtr bufferPtr, uint bufferSize)
193+
{
194+
byte[] buffer = new byte[bufferSize];
195+
Marshal.Copy(bufferPtr, buffer, 0, buffer.Length);
196+
197+
if (stateName == WnfQueries.WNF_SHEL_QUIETHOURS_ACTIVE_PROFILE_CHANGED)
198+
{
199+
var focusAssistStatus = WnfQueries.ToFocusAssistStatus(buffer);
200+
stBar.UpdateFocusAssist(focusAssistStatus);
201+
}
202+
else if (stateName == WnfQueries.WNF_LFS_STATE)
203+
{
204+
//LOCATION
205+
var locationInUse = WnfQueries.ToBool(buffer);
206+
stBar.UpdateLocation(locationInUse);
207+
}
208+
else if (stateName == WnfQueries.WNF_SHEL_NOTIFICATIONS)
209+
{
210+
//NOTIFICATION
211+
var notificationsCount = WnfQueries.ToInt32(buffer);
212+
stBar.UpdateNotification(notificationsCount);
213+
}
214+
else if (stateName == WnfQueries.WNF_TMCN_ISTABLETMODE)
215+
{
216+
//TABLET MODE
217+
var isTabletMode = WnfQueries.ToBool(buffer);
218+
IsTabletMode = isTabletMode;
219+
ChangeMobileShellBehaviour(isTabletMode);
220+
}
221+
else if (stateName == WnfQueries.WNF_CELL_SIGNAL_STRENGTH_BARS_CAN0)
222+
{
223+
var signalStrength = WnfQueries.ToInt32(buffer);
224+
stBar.UpdateSignalStrength(signalStrength, 0);
225+
}
226+
else if (stateName == WnfQueries.WNF_CELL_SIGNAL_STRENGTH_BARS_CAN1)
227+
{
228+
var signalStrength = WnfQueries.ToInt32(buffer);
229+
stBar.UpdateSignalStrength(signalStrength, 0);
230+
}
231+
return IntPtr.Zero;
232+
}
233+
234+
public static void ChangeMobileShellBehaviour(bool visible)
235+
{
236+
//return;
237+
if (visible)
238+
{
239+
stBar.SetVisibility(Visibility.Visible);
240+
tkBar.SetVisibility(Visibility.Visible);
241+
//stBar.UpdateAppBar(); //STACK OVERFLOW EXCEPTION !!!!111!!!11!
242+
stBar.SetupAppBar();
243+
//tkBar.UpdateAppBar();
244+
tkBar.SetupAppBar();
245+
HideExplorerTaskbar();
246+
}
247+
else
248+
{
249+
stBar.SetVisibility(Visibility.Collapsed);
250+
tkBar.SetVisibility(Visibility.Collapsed);
251+
//stBar.UpdateAppBar();
252+
stBar.UnSetupAppBar();
253+
//tkBar.UpdateAppBar();
254+
tkBar.UnSetupAppBar();
255+
ResetWorkArea();
256+
ShowExplorerTaskbar();
257+
}
77258
}
78259

79260
public static void HideExplorerTaskbar()
@@ -82,7 +263,7 @@ public static void HideExplorerTaskbar()
82263
AppBar.SetWinTaskbarState(AppBar.WinTaskbarState.AutoHide);
83264

84265
//puff, disappear.
85-
AppBar.SetWinTaskbarPos((int)NativeMethods.SetWindowPosFlags.SWP_HIDEWINDOW);
266+
AppBar.SetWinTaskbarPos((int)SetWindowPosFlags.SWP_HIDEWINDOW);
86267
}
87268

88269
public static void ShowExplorerTaskbar()
@@ -91,18 +272,7 @@ public static void ShowExplorerTaskbar()
91272
AppBar.SetWinTaskbarState(AppBar.WinTaskbarState.OnTop);
92273

93274
//Reset.
94-
AppBar.SetWinTaskbarPos((int)NativeMethods.SetWindowPosFlags.SWP_SHOWWINDOW);
95-
}
96-
97-
public static void SetWorkArea(Screen screen)
98-
{
99-
RECT rect;
100-
rect.Left = screen.Bounds.Left;
101-
rect.Right = screen.Bounds.Right;
102-
rect.Top = (int)Math.Floor(screen.Bounds.Top + (24F * DPI));
103-
rect.Bottom = (int)Math.Floor(screen.Bounds.Bottom - (42F * DPI));
104-
105-
SystemParametersInfo(SPI_SETWORKAREA, 0, ref rect, 0);
275+
AppBar.SetWinTaskbarPos((int)SetWindowPosFlags.SWP_SHOWWINDOW);
106276
}
107277
}
108278
}

src/Classes/NativeMethods.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public static partial class NativeMethods
1818
public const int WM_SYSKEYUP = 0x105;
1919
public const int WM_MOUSEACTIVATE = 0x0021;
2020
public const int MA_NOACTIVATE = 0x0003;
21+
public const int WM_SETTINGCHANGE = 0x001A;
2122
public const int INPUT_KEYBOARD = 1;
2223

2324
public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

src/Classes/WPFHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ namespace MobileShell.Classes
99
{
1010
public static class WPFHelper
1111
{
12-
private const int MAX_LENGTH = 15;
13-
private const int MAX_TIME_MILLISECONDS = 250;
12+
private const int MAX_LENGTH = 30;
13+
private const int MAX_TIME_MILLISECONDS = 750; //Or 500?
1414

1515
public static bool IsDoubleTap(this TouchEventArgs e, IInputElement inputReference, ref Point? lastTapLocation, Stopwatch doubleTapStopwatch)
1616
{

0 commit comments

Comments
 (0)