WinRT/UWP is suspending rising on power off? - button

I am trying to save data before application (WinRT 8.1) close/sleep/minimze (or windows shutdown/restart in tablet with WIN10) using app suspending event.
https://learn.microsoft.com/en-us/windows/uwp/launch-resume/suspend-an-app
However, it os not working on power off / shutdown WinRT/UWP: Is suspending action rising on long power off button holding?

The Suspending lifecycle event will fire in case of a normal OS shutdown - if you do Start -> Shut down.
This is unfortunately not the case with long power off button holding and restart button press, because both these are improper ways of shutting down your PC. Holding power button to shutdown essentially suddenly "cuts-down power" to the PC, which means the OS cannot respond to this and all unsaved data are lost. This method of shutting down a PC should be used only when something really bad happens and everything freezes. That is why the UWP app has no chance to run the suspending event handler in this case.

Is suspending action rising on long power off button holding?
System will shutdown forcibly with long press power off button. And the system could not make sure Current user session is finished. So the suspending event handler could not be invoked correctly.
From Windows 10 universal Windows platform (UWP) app lifecycle:
Current user session is based on Windows logon. As long as the current user hasn't logged off, shut down, or restarted Windows, the current user session persists across events such as lock screen authentication, switch-user, and so on.
So, before shut down, the app still in the Current user session. And Suspended will be invoked on power off(shut down).
Note, you can not test it in debug model within Visual Studio. Because when you shut down the system, Visual Studio will exit degbug model at first. The Suspended event will not be invoked as expect. You could verify with following code.
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var stringBulider = new StringBuilder();
var deferral = e.SuspendingOperation.GetDeferral();
Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
Object value = localSettings.Values["exampleSetting"];
stringBulider.Append(value.ToString() + "/Next");
localSettings.Values["exampleSetting"] = stringBulider.ToString();
deferral.Complete();
}
Each time you shut down, the stringBulider will be append one at a time.

Related

Don't know how to kill app process in KaiOS

I am developing an app that uses ws connection on KaiOS. When I press back and put the app in the background, somehow the app instance is not killed. I can still get message coming in from ws connection even though the app is in background. This makes the phone runs out of battery quickly because exited app remains in the runtime process I suppose.
But, I do need a situation where the app runs in background (not killed).
So, the question is, do we have access to kill an app process, for example when user press something or normally when app is closed and screen back to menu screen from app screen?
I think you can observe the Backspace key and close the window.
Such as:
function handleKeydownEvent(e) {
if (e.key == 'Backspace') {
e.preventDefault();
window.close();
}
}
document.body.addEventListener("keydown", handleKeydownEvent);

How to add support for screen timeout while running a qt5.9 app on linuxfb platform?

I'm using a qt5.9 app on imx6slevk board with yocto bsp,
Before running the app I see a virtual terminal on the display and this screen blanks after 10 minutes as specified in the driver file found at Kernel_source > drivers/tty/vt/vt.c
static int blankinterval = 10*60;
Just as this file is used for virtual terminal the file qlinuxfbscreen.cpp is used by qt applications running on linuxfb.
I didn't find any option of do_screen_blank or do_screen_unblank in this file
All I found was this function:
static void blankScreen(int fd, bool on)
{
ioctl(fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING);
}
on passing on = 1 the screen goes off completely with no display at all
I tried setting Idleaction in systemd/logind.conf
IdleAction=suspend
IdleActionSec=30Sec
after this the app turns off after 30 sec but it does so even if I press keys on the matrix keypad, systemd doesn't seem to register key press as active events and the screen turns off.
Is there any patch that I can apply to enable screen timeout? Or could I at least register key press as active event in systemd?
You'd need to modify your qt app.
The algorithm would be something like
Start timer
If key pressed reset timer to max value
If no key pressed go to suspend mode, you may use:
system("echo mem > /sys/power/state")
Wakeup on power key press.

CefSharp.BrowserSubprocess is left running with high CPU if app crashes

I'm making use of the excellent CefSharp project (version 67) to host a browser in our WPF application.
Making use of CefSharp causes child CefSharp.BrowserSubprocess processes to be started, which is by design.
These processes are stopped if I cleanly exit my application and call Cef.Shutdown() as recommended in the documentation:
// Hook up handler earlier in application
Application.Current.Exit += OnApplicationExit;
...
private void OnApplicationExit(object sender, ExitEventArgs e)
{
if (Dispatcher.CheckAccess() == false)
{
Dispatcher.Invoke(() => OnApplicationExit(sender, e));
return;
}
// Stops CefSharp.BrowserSubprocess processes
Cef.Shutdown();
}
I've noticed that if the application is killed, the CefSharp.BrowserSubprocess responsible for rendering is left running and starts using a lot of CPU and does so indefinitely.
I can add some code to handle this, checking for any orphaned CefSharp.BrowserSubprocess process, and kill them. I'm wondering if there's a better option though?
It would be great if the process itself could perform a period check itself and kill itself, perhaps as a setting.
As answered by #amaitland, the following setting should be set to monitor the parent process:
CefSharpSettings.SubprocessExitIfParentProcessClosed = true;

Android BLE - BT stack alarm errors

I'm trying to get basic Bluetooth LE connections working in my app, but I'm running into problems. I have a couple of sensors that I can connect to just fine with the iOS version of this app, but I simply cannot connect to them with the Android version. The only thing I seem to be able to connect to is a beacon I've set to configuration mode.
After checking my ADB logs again, I noticed that whenever it fails to connect to a device, there's always four calls to bt_osi_alarm and bta_gattc_conn_cback. I'm wondering how to interpret this.
An unsuccessful connection attempt:
D/BluetoothGatt(17824): connect() - device: 00:17:E9:C0:86:14, auto: false
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
...
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
...
W/bt_btif (14357): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=6 connected=0 conn_id=6 reason=0x0002
D/BtGatt.GattService(14357): onConnected() - clientIf=6, connId=0, address=00:17:E9:C0:86:14
D/BluetoothGatt(17824): onClientConnectionState() - status=133 clientIf=6 device=00:17:E9:C0:86:14
I/mono-stdout(17824): BLEAdapter.OnConnectionStateChange()
I/mono-stdout(17824): Gatt disconnected!
A successful connection attempt to one of those beacons does not have these sets of four bt_osi_alarm and bta_gattc_conn_cback errors. Preferably if someone knows the Android source well, hopefully they can tell me what's going on. It's a long shot I know, but I'm kinda out of options. Thanks.
Some additional information might help the community debug this issue for you. Please add the following to your original question:
Make/Model/Revision of all BLE devices that you've tested and whether or not each one works
Specific android device you have tested with
The error your app gets and at what step it fails
Are you able to get a BluetoothDevice
Does it fail when calling connectGatt()
Is your app written in java/android studio, or is this some kind of universal app that runs on both iOS and Android?
In my experience, alarm expiration too close for posix timers, switching to guns, isn't as serious as its error level suggests. On my nexus 7/marshmallow device, I see this message constantly while connected to a bluetooth device (serial profile, not BLE) so I don't think this is a bug.
I suggest checking up on the BLE device manufacturer to see if there are any firmware upgrades for them too.
More details on alarm expiration too close for posix timers, switching to guns
What's happening is some part of the android bt code is setting a very short timer. So short, that it expires before the app can measure it.
The error, alarm expiration too close for posix timers, switching to guns, was added to android source in a commit 081e4b67b44a5fd397c2d79a5566e11ae52d4aca
The commit message gives us more background on what is happening.
Ensure alarms are called back when they expire in the past
Turns out the posix timers we're dealing with aren't well behaved.
If the timer is TIMER_ABSTIME the following is supposed to be true:
"If the specified time has already passed, the function shall succeed
and the expiration notification shall be made."
But alas, this is not the case. If the expiration time happens to be
in the past (e.g. very short timer which gets hit with a context
switch before the timer can be set) the timer decides to disarm
itself. This means no more callbacks happen, and no more alarms are
processed ever.
sadness.
But thankfully, we can use timer_gettime to check the state of the
timer after timer_settime. If timer_gettime tells us the timer is
disarmed right after we armed it, we want to perform the alarm
callback ourselves.
Put all timer callbacks on the same thread (as would be the case in
the underlying timer implementation already) and used a sempahore to
signal when an alarm expires in the normal posix timer callback and
also in the timer didn't set case.
The code also includes the following comments
If next expiration was in the past (e.g. short timer that got context
switched) then the timer might have diarmed itself. Detect this case
and work around it by manually signalling the |alarm_expired|
semaphore.
It is possible that the timer was actually super short (a few
milliseconds) and the timer expired normally before we called
|timer_gettime|. Worst case, |alarm_expired| is signaled twice for
that alarm. Nothing bad should happen in that case though since the
callback dispatch function checks to make sure the timer at the head
of the list actually expired.

RemotePlaybackClient resume session on Chromecast

I am trying to use the RemotePlaybackClient to resume a Chromecast session created by the same Android app. I'm able to use this RPC vs the full Cast SDK to play, pause, resume, seek, and stop playback on the Chromecast device. My current test is in closing the Android app and using the sessionId from the session to try to reload the app and resume control of the playback. Upon closing the Android app, we are not terminating playback or the session, it keeps going.
Here is the code I'm using:
// attempt resume
mRemotePlaybackClient = new RemotePlaybackClient(getApplicationContext(), ccRoute);
// ccRoute is the selected ChromeCast RouteInfo device - same as previous
System.out.println(mRemotePlaybackClient.isSessionManagementSupported()); // true
System.out.println(mRemotePlaybackClient.hasSession()); // false
mRemotePlaybackClient.setSessionId(saved_sessionId); // saved_sessionId is the sessionId saved from the mRemotePlaybackClient.play command in success reply.
System.out.println(mRemotePlaybackClient.hasSession()); // true
mRemotePlaybackClient.startSession(null, ccStart); // callback returns error 0
mRemotePlaybackClient.setStatusCallback(ccSessionStatus); // callback returns error 0
I've asked some others familiar with the RemotePlaybackClient and the Chromecast, including those within Google but did not get an answer. Also, I seem to be seeing some of the same issues #Commonsware is seeing in that some callbacks don't reply at all. In addition, with images, metadata is not returned and the status callback returns an error whereas video returns ok (position info etc).
Really, I'd just like to resume the session for now vs having to wire up the full Cast SDK.

Resources