Implement service on Firefox OS - firefox

I'm quite new to Firefox OS. At the moment I'm struggling with implementing some kind of service that listens for geolocation updates in the background.
If there are lots of apps running at the same time mine seems to be killed. While debugging with App Manager it disconnects silently.
I tried requestWakeLock('cpu') and the use of a Worker (as proposed in this thread) but without success.
Background services API isn't implemented, yet and will be available for certified apps only.
I know that there are non-certified apps like ConnectA2 that stay alive all the time so there has to be a way.
Could anybody give me a hint?

Firefox OS doesn't provide a way for you to run a service in the background intentionally, since the classes of the devices that we target (for example, the 128MB device) won't be able to support running apps constantly in the background.
There are alternate ways of implementing these kinds of services though. For example you can use the mozAlarm API in order to wake up your application at specific intervals, or you can use the SimplePush API which allows you to notify your app when a remote server initiates an event.

You can use Alarm API to prevent your app to be killed in the background.
Alarms wakes up the app at fixed intervals.
var alarmId = 0;
function setAlarm() {
function onAlarmAdded() {
alarmId = request.result;
}
var alarmDate = new Date(Date.now() + (60 * 1000)); // 60 seconds later
var request = navigator.mozAlarms.add(alarmDate, "ignoreTimezone");
request.onsuccess = onAlarmAdded;
}
function setHandler() {
function onAlarm(mozAlarm) {
// set next alarm
setAlarm();
}
navigator.mozSetMessageHandler("alarm", onAlarm);
}
function startAlarm() {
setHandler();
setAlarm();
}
function stopAlarm() {
navigator.mozAlarms.remove(alarmId);
}

Related

Android Beacon Library - didEnterRegion not firing when app in background or stopped for pre-Android 8

First some background:
My setup uses a Service, which implements BeaconConsumer and binds to the BeaconManager. I have additional handling so when my app leaves the foreground, I move my Service to run in foreground, and when my app enters the foreground, I move my Service to run in background. That way, the persistent notification should display if and only if the app isn't displaying. In accordance, I am using the pattern here to tell BeaconManager I'm running this Service in the foreground, to allow for more frequent scanning. The link above isn't quite clear about this, but I believe this pattern should work without alterations needed on both pre-Android 8 as well as Android 8+. It shouldn't be strictly necessary on pre-Android 8, since the OS is more lenient. However, using this setup across all versions has the collateral benefit of ensuring that the OS does not kill the Service. If the app is in the foreground, the Service is background but has priority by virtue of the app, and if the app is not in the foreground, the Service is, and therefore has priority.
Now the problem: On pre-Android 8 devices, my Service is not seeing didEnterRegion called when the app is not in the foreground (but the Service is). It works fine on Android 8+.
some code snippets:
In my Service, set up the BeaconManager, set scan intervals
_beaconManager = BeaconManager.getInstanceForApplication(this);
_beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(IBEACON_PATTERN_1));
_beaconManager.setEnableScheduledScanJobs(false);
_beaconManager.setBackgroundBetweenScanPeriod(0);
_beaconManager.setBackgroundScanPeriod(1100);
Function in my Service I invoke to send the service to the foreground, and background:
private void sendServiceToForeground() {
this.startForeground(NOTIFICATION_ID, _notification);
if (_beaconManager != null) {
if (_beaconManager.isBound(this)) {
_beaconManager.unbind(this);
}
_beaconManager.enableForegroundServiceScanning(_notification, NOTIFICATION_ID);
_beaconManager.bind(this);
}
}
private void sendServiceToBackground() {
if (_beaconManager != null) {
if (_beaconManager.isBound(this)) {
_beaconManager.unbind(this);
}
_beaconManager.disableForegroundServiceScanning();
_beaconManager.bind(this);
}
this.stopForeground(true);
}
I can provide more code as requested. Not sure what all is relevant.
Calls to unbind() and bind() are asynchronous, so calling them one after another will be a problem unless you first wait for the unbind() operation to complete. This is tricky, because the library's BeaconManager does not provide a callback to tell you when unbind is complete (indeed, this is because the underlying Android service APIs also do not provide such a callback. You essentially don't know when the library's scanning service has stopped so you can safely restart it again in a different mode.)
It's a bit of a hack, but you might try adding a delay between unbind() and bind() to see if that makes a difference.

SignalR Hub method is not called

I have a SignalR hub and two clients (Windows and PCL for Android and iOS). Neither of the clients is able to call some methods on the server. This behaviour is quite odd, since the methods look very similar. Moreover, a colleague of mine is able to call methods I cannot call, and vice versa, does not invoke methods that I invoke with no problems.
Here is an example of a method, which works for me and does not work for my colleague:
public override async Task<bool> RefreshArray(User user, int waitMilis)
{
var cts = new CancellationTokenSource();
try
{
cts.CancelAfter(waitMilis);
await Proxy.Invoke("RefreshArray", user);
return true;
}
catch (Exception ex)
{
OnExceptionOccured(ex);
return false;
}
}
And a method which does not work for me, but works for my colleague:
public override async Task<bool> RequestInformation(User user, Product product, int waitMilis)
{
var cts = new CancellationTokenSource();
try
{
cts.CancelAfter(waitMilis);
await Proxy.Invoke("RequestInformation", user, product);
return true;
}
catch (Exception ex)
{
OnExceptionOccured(ex);
return false;
}
}
Yes, me and my colleague have exactly the same code. And no, there are no typos or different arguments. I have tried to get as much data from the client connection as possible, by setting _connection.TraceLevel = TraceLevels.All; However, I did not get any information on the invoked methods, just on the replies from the hub. When calling RefreshArray, I got exactly the data I requested. When calling RequestInformation, the debugger never even hit the breakpoint in the hub method and the _connection.Trace displayed only this: 11:22:45.6169660 - 7bc57897-489b-49a2-8459-3fcdb8fcf974 - SSE: OnMessage(Data: {})
Has anybody solved a similar issue? Is there a solution?
UPDATE 1
I just realized that I have encountered almost the same issue about a year ago (Possible SignalR bug in Xamarin Android). StackOverflow has also pointed me to a question with almost the same issue (SignalR on Xamarin.iOS - randomly not able to call Hub method), just related to iOS and Azure. However, I got the same proble even outside Xamarin, on Windows Phone 8.1 and and Windows 10 Universal App. Moreover, I am running the server just locally, so it is not an issue od Azure. Is it really possible, that a 2 years old bug has no solution?
UPDATE 2
I have just created a simple console application with SignalR.Client. In the console application every method worked just fine. Amazingly, also the Windows 10 Universal Application started to behave as expected - every hub method was invoked correctly. Windows Phone 8.1 also improved its behaviour (all hub methods invoked). However, every now and then the connection tried to reconnect periodically (for no apparent reason), leading to Connection started reconnecting before invocation result was received. error. The Android application still behaved as before.
So I tried to replicate my previous steps and created another console application, but this time with SignalR.Client.Portable library. To my dissapointment, there was no change in the Android application behaviour.
Next week we will start to test our application on iOS, so I really wonder what new oddities will we encounter.
I have managed to solve the problem (at least so it seems). As it turned out, there is some weird stuff going around, when an application receives an answer from SignalR hub. It seems as if the HubProxy was blocked for a certain period of time on Android, while it drops the connection and starts to reconnect periodically on Windows Phone, not waiting for an asnwer from the hub.
The implementation of RefreshArray on the hub was something like this:
public async Task RefreshArray(User user)
{
await Clients.Caller.SendArray(_globalArray);
await Clients.Caller.SendMoreInformation(_additionalInfo);
}
Because the method sent two methods as an answer, the client Proxy got stuck and each platform handled it in its own unexpected way. The reason why some methods were called on my computer and not on colleagues was, simply, because we had different position of breakpoints, which enabled the application to resolve at least some requests and responses.
The ultimate solution was to add some synchronization into the invokation of methods. Now my hub calls only await Clients.Caller.SendArray(_globalArray);. This is then handled on the client with a ArraySent(string[] array) event, which then subsequently invokes the SendMoreInformation() method on the hub.

Communicating over XPC with an app and launch daemon running as root

Is it possible to communicate with a launch daemon running as root and an application over XPC? When my daemon is running as my user I can communicate with it fine, when run as root it stops receiving my messages. Is this intended security inside Mac OS X?
I need to use low level xpc (for running on Lion as well). I know I can create a priviliged and signed helper tool that is running as root for my app. Will I be able to communicate with it with another process as well over XPC or sockets?
Thanks!
Small extract from my daemon code:
int main()
{
Logger::Start(Poco::Path::expand("/Users/Shared/Me/Service.log"));
Logger::LogInfo("Starting xpc_main...");
void* observer = nullptr;
CFStringRef observedObject = CFSTR("com.me.service.close");
CFNotificationCenterRef center = CFNotificationCenterGetDistributedCenter();
CFNotificationCenterAddObserver(center, observer, notificationCallback, CFSTR("ClientClosing"), observedObject, CFNotificationSuspensionBehaviorDeliverImmediately);
xpc_connection_t listener = xpc_connection_create_mach_service("com.me.service", NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
xpc_connection_set_event_handler(listener, ^(xpc_object_t event)
{
// New connections arrive here. You may safely cast to
// xpc_connection_t. You will never receive messages here.
// The semantics of this handler are similar to those of
// of the one given to xpc_main().
Logger::LogInfo("Event Handler on listener is called");
eventHandler((xpc_connection_t)event);
});
Logger::LogInfo("call xpc_connection_resume...");
xpc_connection_resume(listener);
CFRunLoopRun();
Logger::LogInfo("Main Program is Exiting...");
return 0;
}
The problem is that CFNotificationCenterGetDistributedCenter works only on the same user, root user will not send message to other logged in users..
You'll need to switch to CFNotificationCenterGetDarwinNotifyCenter.
Please note however, that you can't pass any data using this center.

How can I test the background scan and launch the application in background with iBeacon-Android?

I am using the pro library.
But I just found doc for free library
I cannot find any doc for pro version.
Also, I don't know how to implement the background mode even using the pro sample.
Here are the steps:
Build the pro sample project
start the iBeacon source(using iPad) and it can be detected
start the application and then press home button the make it in
background
Turn off the iBeacon source
Turn on the iBeacon source
However, more than 5 minutes, the application does not launch
So, can anyone verify the step I did?
How can I test the background mode more easily?
Also, for the BootstrapNotifier, is it just work only first time when the device reboot?
After that, even I put application in background, the application will not launch when it detect iBeacon?
Your testing method sounds fine. I think the issue is that the reference app for the pro library only auto launches the app on the first detection after boot. After that, it sends a notification instead, and tapping on that notification launches the app.
This is purely for demonstration purposes. You can change it to auto launch on every detection if you wish. Simply alter the haveDetectedIBeaconsSinceBoot logic in this code:
#Override
public void didEnterRegion(Region arg0) {
// In this example, this class sends a notification to the user whenever an iBeacon
// matching a Region (defined above) are first seen.
Log.d(TAG, "did enter region.");
if (!haveDetectedIBeaconsSinceBoot) {
Log.d(TAG, "auto launching MainActivity");
// The very first time since boot that we detect an iBeacon, we launch the
// MainActivity
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Important: make sure to add android:launchMode="singleInstance" in the manifest
// to keep multiple copies of this activity from getting created if the user has
// already manually launched the app.
this.startActivity(intent);
haveDetectedIBeaconsSinceBoot = true;
} else {
// If we have already seen iBeacons and launched the MainActivity before, we simply
// send a notification to the user on subsequent detections.
Log.d(TAG, "Sending notification.");
sendNotification();
}
}
The javadoc link was missing from the main documentation page when you posted this question. That is fixed now.

How do I know when an Amazon EC2 operation is complete?

Besides polling, how can I tell when a long-running Amazon EC2 operation is complete? For example, using the CreateImage API function can take upwards of several minutes.
Right now I'm doing this:
// MAKE THE API CALL
var createRequest = new CreateImageRequest().WithInstanceId("i-123456").WithName("MyNewAMI");
var createResponse = myAmazonEC2Client.CreateImage(createRequest);
var imageId = createResponse.CreateImageResult.ImageId;
// ICKY POLLING CODE
bool isImaging = true;
while (isImaging)
{
var describeRequest = new DescribeImagesRequest().WithImageId(imageId);
var describeResponse = myAmazonEC2Client.DescribeImages(describeRequest);
isImaging = describeResponse.DescribeImagesResult.Image.Single().ImageState == "pending";
Thread.Sleep(10000); // sleep for 10 seconds
}
// CreateImage IS COMPLETE; MOVE ON WITH OUR WORK
I hate this. After calling CreateImage, I'd like to just get notified somehow that it's all done and move on. Is this possible? I'm using the AWS .NET SDK in this example, but I'm not looking specifically for a C# solution.
UPDATE: Cross-posted to the AWS Forums
Some events in amazon can be configured to send notifications to an SNS Topic. For example when using auto scaling you can have notifications when a server is launched and terminated. As far as I know there is no way to trigger these notifications for other services such as CreateImage. I've looked for this type of feature in the past with no luck. I was trying to do it to create a script that would launch servers in a specific order. I wound up just polling their API as I couldn't find any way to register to those events.
James Hunter Ross answered this question over on the AWS Forums as follows:
Polling is it. That said, since you have a C# program started, why not let it spawn a polling process that notifies you as you wish? It seems you are almost done, in some respects.
(Of course, it would be nice if such functionality was built-in at AWS.)
I wasn't able to find a StackOverflow profile for him, but if he shows up I'll edit this to give him credit.

Resources