Remotely debug system framework - android

I would like to debug a system framework running on an Android device.
In particular, GpsLocationProvider sometimes stops for a while, and I would like to know what it is doing. I found the class contains a android.os.Handler that gets messages posted to it, to communicate between threads. Sometimes it takes minutes between a message is sent, and Handler.handleMessage is called. I interpret that the thread belonging to the Handler's Looper is busy.
I would like to attach a debugger, pause that thread, and see what's currently executing. Alternatively, somehow get a traceback of that thread. Is there any way to do that?
I tried creating an Android Studio project from the source tree with development/tools/idegen/idegen.sh, but I'm not sure how to proceed from there. In case it matters, the (legacy) device is running Android 6.
I've also just discovered debuggerd. I call logcat -s GpsLocationProvider to find the corresponding PID, and feed it to debuggerd, both with and without -b argument. However, this only gives be a backtrace into native code. I don't see any java code there.

If I'm not mistaken, if you have the respective Android API version in your AndroidStudio (installed through SDK Manager), you can install debug variant of your app on the device and then put breakpoints inside Android's code.
This way you can pause the execution of the component's code and see what it's doing.

Related

Detox Test device.disableSynchronization() works on iOS but not android

My test suite runs fine on iOS, the app has many background processes running that prevent large portions of the tests from working in synchronized mode. The desynced commands run properly on the iOS simulator, but when I run them on the android emulator it is as if I never called await device.disableSynchronization().
The tests still hang and the console logs:
The app is busy, due to:
- Enqueued timers
- Animations running on screen
Any ideas about how to fix this?
Further review shows the error message:
The app has not responded to the network requests below:
The odd thing is the listed network request has been completed. The request upon which the app purportedly has not responded is a button push that navigates to a new screen which incurs a somewhat lengthy network request. After the network request completes other processes continually run necessitating the disabled synchronization. Since Detox is still waiting on some response from the app about the button tap, it does not move on to the next, desynchronized, actions. Is there any way to ensure that Detox receives the response of this .tap()?
A deeper investigation reveals that this is likely caused by a lingering animation that, for whatever reason device.disablesynchronization() ignores on Android builds. I am now working on mocking this file based on the out-of-date documentation provided by wix.

Can i use flutter isolate for backround processes without touching Java/Kotlin?

I'm trying to create an app that manages a BLE connection in the background (receives notifications, reconnects and subscribes to a characteristic when connection is lost and the phone is moved near the BLE device again).
Right now I have the app somewhat built - everything that I need works relatively well but only when the app is open. Although the code isn't up to standard as this is my first app and I don't have any previous experience with Java/Kotlin/Dart (this is also why I'd rather not touch anything outside of flutter).
I need the app to send me local push notifications when tabbed out of the app or when screen lock is on and as far as I understand one could do this with isolates. I've searched a lot but found one guide which is kind of hard to understand as a beginner and also uses Kotlin.
Can I get away with only dart code for background code execution (described above) and is it suitable for a beginner?
Also, let me know if you have any alternative solutions since all I need is to get a notification on my phone whenever it receives a notification from a BLE device (and also auto connecting). I've already tried this with kivy since I'm more familiar with python but with no luck.
Talking about BLE there's this plugin by the way: https://pub.dev/packages/flutter_reactive_ble
As for the isolates, they are not ideal for this even though they do run separately, they'll get killed eventually. There's also a little helper package that makes working with isolates very straightforward if you want to try it: https://pub.dev/packages/computer
And so actually for the task at hand (background execution) I would suggest researching/using this one: https://pub.dev/packages/background_fetch
I would not encourage you to use any timer-based solution that tries to wake up your phone every 15 minutes or so, since that uses unnecessary CPU time.
Now I'm not that much into Flutter, but at least on Android, the "correct" way to have an ongoing connection (auto-connect) is to have a Foreground Service in the process running, so the process does not get killed. Then subscribe to characteristic notifications as usual, and handle the values as they arrive, either in Java or Flutter (by using some Java <-> Dart bridge).

AVD process gets killed as soon as I end debugging

My Setup is:
Server: Asp.Net and SignalR-Server
App: SignalR-Client
My App uses "Invoke" to invoke a function on my Server which should return a MyObject-Object. But the response isn't arriving at my client and the app 'hangs' in the async void in which the Invoke is located.
As soon as I end the debugging of the app the whole
AVD-Process gets killed with no error message shown in the Emulator or Visual Studio.
I think this happens of a Exception which is 'silently' thrown.
How could the AVD get killed with an Exception of my app?
As for many inconsistencies I needed to let Visual Studio clean the whole project.
I think it is an underlying process which does some caching of files or values and then the application itself cannot use the cached data as I changed the usage of this data.
This is really annoying because now I always let Visual Studio clean the code after each edit on the code. And with this procedure I am getting less 'error-less' errors which aren't real errors...
Thanks anyway :)

Repeatedly fork Android app process, where child can access System Services via JNI

Context
I am developing an Android app that embeds a Python interpreter. I use JNI to execute C code and the C-Python API to run Python code and also to make Android functionality available in Python via extensions. The Python interpreter needs to:
run in its own process
be able to call itself to start another (many) Python interpreter(s), each in its own process (via Python extension)
be able to call back into Java and do Android things, e.g. request a System Service to use device sensors (via Python extension)
Here is a diagram of my current implementation.
It works pretty well as long as I am in the same process. When I try to fork it gets messy.
Approach 1 - fork in C using fork()
The app starts a background Service (in the app’s process). The Service calls a native method where I use the fork() system call. The child process inits Python and the Python extensions. The extensions are used to start new Python interpreters; and call into Java code (via JNI) to e.g. use System Services.
Forking repeatedly (recursively), running Python code, using C-Python extensions and calling back into Java works.
What does not work is using the Android Application Context from the parent process to use System Services, which leads to segmentation faults. Something that is probably not surprising when one forks and still wants to use stuff from the parent’s address space.
Btw. I get the context from a static function in an Application subclass, where I store it when the app first gets started, which I know is discouraged.
Approach 2 - Let Android fork using android:process
I let Android fork my background Service by adding android:process to the service definition in AndroidManifest.xml. Then I call a native method that inits Python and the extensions. Now, when I use my extensions to call into Java and use System Services I don’t get segmentation faults. Probably because Android has created a new Virtual Machine, with a fresh context and I don’t have to access anything from the parent process’ address space (especially now that the parent of my new process is Zygote and not my original App process).
The problem with this approach is that I can’t start multiple instances of a Service/Process to have multiple Python interpreters.
TL;DR
When I fork a process in an Android native method, how can I avoid segmentation faults when I try to call System Services in that child process?
Is there a way to have my App create new processes (ideally with a new Virtual Machine), without specifying them in the AndroidManifest.xml
Resources (I don't have enough reputations to post the links)
Android Guide - Process and Threads (This somehow tells me, this is do-able, but not how)
Kivy Python for Android (Interpreter does not fork)
Script Layer for Android (Interpreter forks but does not use JNI to call into Java)
Java ProcessBuilder (Forks a new process to execv a native program, which can’t call into Java)

Running a script as a service from init.rc on Android at boot

In order to execute a script on Android (Samsung Note 10.1 (N8010), 4.4.2) at boot I added the following to the end of the init.rc (unpacking/repacking the boot.img) to have it run as a service:
service test /system/bin/test_script.sh
class main
oneshot
The script looks like this:
#!/system/bin/sh
mkdir /sdcard/test_directory
It is eventually supposed to do something else, but for testing I kept it simple. Permissions are 0755.
The problem though is that the directory /sdcard/test_directory is not being created, which leads me to believe that the service is never being started, i.e, the script is never being executed.
I've already tried numerous things mentioned in other threads.
E.g., adding the line user root to the service, rebooting multiple times (since apparently a service is not being started after booting the device right after flashing the boot.img) or putting the script in different folders like /system/etc/ or /data/local/tmp.
Any idea what could be the problem?
Is it possible to somehow monitor whether the service is actually being started (maybe it is, but the problem lies within the script)?
Is there maybe even a better way to executing a script at boot (device does not have init.d support and I don't want to use an app like Unversal Init.d)?
EDIT:
Don't know why, but it works now.
Moved the script around multiple times, ended up putting it under /data and removing the file extension. Also added some more lines to the script like mkdir /data/local/tmp/test_directory. The directory under /sdcard is not being created though (maybe a permission problem?). Probably the reason, why I thought the script had not been executed, if it has been before.
Question remaining: is there a way to monitor whether a service is actually being started?

Categories

Resources