I have a requirement where I need to read an interface (say /sys/module/my_file/parameters/val) and then based on its value write some value on another interface. This has to be done in init.rc of Android filesystem.
flow would be like this
if ( read /sys/module/my_file/parameters/val == "yes") then
write /sys/devices/platform/target_file/val 100
Can anybody help me to do the same?? Is it possible??
You can implement this using an exec stanza:
exec <path> [ <argument> ]*
Fork and execute a program (<path>). This will block until
the program completes execution. It is best to avoid exec
as unlike the builtin commands, it runs the risk of getting
init "stuck".
See https://github.com/android/platform_system_core/blob/master/init/readme.txt for the details.
Example:
Move your code into a script (my_script.sh).
Add this to your init.rc
on boot:
...
exec /path/to/my_script.sh
You can use init’s service concept for running a script. Below is the code sample form init script.rc file.
chmod 0750 /system/bin/myscript.sh
start script
[...]
service script /system/bin/myscript.sh
class main
user root
group root
oneshot
Related
I am developing with raspberry pi3 on Android Things.
I am trying to execute a Script on boot, modifying init.rc file as so:
sys.boot_completed = 1:
on property: sys.boot_completed = 1
bootchart stop
# WLD 201805031702
chmod +x /system/bin/myScript.sh //Added by me
sh /system/bin/myScript.sh //Added by me
I don't know why, but the Script doesn't get execute, i have tried to change "hostname anyName" instead of executing the Script on these lines of init.rc file, and it does pass throw these lines because hostname get changes, but it doesn't execute the Script.
How can i execute a Script on Boot, i don't know what to do.
Best regards
Alvaro
With Android Things, you can set up your application so that it fits within the Android framework.
For example, if you use the HOME intent filter on your main activity in your app, then your activity will launch immediately on boot, allowing you to run some code.
I'm using the RootTools library, and I need to execute two commands. The first one runs a binary, the second sends SIGINT to it, to kill it.
RootTools (as far as I know) can only have one root shell open at a time, so commands can only be executed one by one. This is a problem, because I have no way to stop my binary after I've ran it.
How can I do any of the following things?
Execute two commands at once, so I can run my kill command when the binary is running
Send SIGINT to my native process some other way (e.g. with a RootTools function)
I need to use RootTools because it's the only way for me to read standard output from my program. If there's another way to do that, though, please comment.
Do you think you can concat the commands?
Let's say I want to launch a find command, but if it takes 5 seconds, I want it to stop:
find / & sleep 5 && kill $!
We can get a better suited one liner, too (i.e. ignore standard error, kill only if needed etc.).
You could also just store the PID and kill it later (be careful, if the daemon stopped to run, his PID can be reused by the OS):
run the daemon in a root shell
my-daemon >/dev/null & echo "PID: $!"
parse the output in Java and store the PID (SharedPreferences?)
var pid = outputLine.split(" ")[1]
later on, stop the daemon with a root shell
kill <pid>
In my app, I have an Activity, which is basically a form for the user to enter data which is then inserted into a database table via a ContentResolver. How do I test this Activity?
My first attempt was to use ActivityInstrumentationTestCase2 which gives me full instrumentation to simulate entering data. However, the underlying ContentProvider is not closed and destroyed between each test, which leaves the database in an unknown state at the beginning of subsequent tests.
My second attempt was to use ActivityUnitTestCase and inject a mock context that can clean up the database for each test. However, this doesn't allow me to enter text or click on buttons in the activity as it is never actually drawn on the test device.
Does anyone have any suggestions about what else I can try?
it seems that what you've been using is intended for library development
You should look at the monkey binary here , which works great for me.
If you're not satisfied with it you could use monkeyRunner which provides more control over the tests you're running.
Edit :
As far as the database testing goes , cant you use the sqlite3 binary for a simple query after each test?
Edit2:
I am thinking of a .sh script that does the following :
Runs monkey for a while - you can specify the number of events for the monkey to send
Invoke sqlite3 with a query that would check the database integrity into a log file (sqlite3 command can take sql query as a second parameter, and you can use ">" to write the output into some file)
Repeat.
There are tons of examples for .sh scripting on the net so you shouldn't have problem with that.
I am assuming you're doing all this in adb shell, but if you're not, make sure to set all your environment variables correctly. Particularly ANDROID_ROOT, ANDROID_ASSETS and ANDROID_DATA should be set to "/system","/system/app" and "/data" accordingly . Also don't forget to "chmod" the .sh file to be executable ( chmod 777 file.sh ).
Another suggestion is to generate and keep track of the monkey random seeds so you can repeat certain inputs that are causing you problems. You can specify a seed with -s parameter.
I'm appending init.rc in Android root with:
service logcat /system/bin/logcat -v long -f /mnt/sdcard/logcat.log
This solution doesn't generate any logs. The logcat.log file doesn't exist.
How can i start gathering logcat output through init.rc ?
A couple of things that could be causing problems above:
1. you defined your service to be called logcat. That looks awfully close to what might be a reserved/pre-existing name. I would choose a more distinguished service name.
2. there is no explicit start trigger for the service, hence its entirely dependent on the context in which its defined (i.e. which init phase). Pick the wrong phase (i.e. too early) and /mnt may not even exist.
3. the service will by default be running as root and thus the logcat.log file will be rw only by root. Not good to run processes as root. And not good to force readers to be root in order to read the log file.
Here the approach I've used to achieve what you're looking to do.
Problem: Ordinarily, Android log messages remain in the kernel’s (volatile) memory only and thus doesn’t survive across reboots.
Solution: To retain those log messages across reboots requires them to be written to persistent storage (i.e. the filesystem). The following code defines such a service that is started by Android during init.
Step 1, define a service that the Android init process will spawn to do this activity. This goes in init.rc.
service persistentLogging /system/bin/logcat -r 1024 -n 9 -v threadTime -f /cache/logs/log
user system
group system log
disabled
Notes about the above:
it creates a service called persistentLogging (that will be referred to in the second step below) by the start trigger.
it requests logcat to do a rolling log file (consisting of 10 files / 1Mb each) in directory - /cache/logs (i.e. log, log.1, log.2, … log.9). Adjust to suit your needs.
the service is to run as system user. This means the log file will be read+write only by system. If your app has system privileges then you’ll be able to read the log file. I’ve also defined the service to be in the log group too since that seems appropriate although since the files are not readable by group its a moot point.
the service is initially disabled. It will be started by a trigger defined below
the service is NOT oneshot. Hence, should it die, Android will attempt to restart it.
Step 2, define a trigger for starting the service. This also goes in your init.rc file.
on post-fs
mkdir /cache/logs 0775 system log
start persistentLogging
Notes about the above:
the commands are triggered during the ‘post-fs’ phase so that they occur after filesystem partitions have been mounted and when other system directories are having their permissions changed. Ideally, this service should start as late as possible because its not important or used by any other start-up activity.
the trigger first creates the target directory before starting the service. Remember the mkdir command syntax is defined by the init.rc language. In Android this syntax is not a sh syntax eventhough it looks a lot like it.
eventhough the above logging service doesn’t start until the post-fs phase of init, it will nevertheless dump all logging information since the beginning of kernel's startup as these log messages are already in the kernel buffers and this logging service is merely copying those messages to a file.
although both code fragments above ultimately need to appear in init.rc file, it is more maintainable if those additions are made to the init.${ro.hardware}.rc file defined for the device. e.g. init.freescale.rc which is automatically included by init.rc.
If we need to start the logcat and collect all the log buffers after on post-fs-data/boot completed from init.rc you can use below code in init.rc file.
on property:dev.bootcomplete=1
start logging
on post-fs-data
start logging
service logging /system/bin/logcat -b all -v threadTime -f /data/directory_name/log -r 100000 -n 9
user system
group root system log
disabled
I am using my Android app to launch a native binary. I would like to display the output of that binary in a small window in my application. How would I go about either displaying the output in a TextView or showing the terminal in a small window (preferred)?
Thanks.
The gist of the article that Alex linked to is that Runtime.exec() returns a Process object, which lets you get the process' standard output (and stderr, too) as Java streams via Process.getOutputStream()/getErrorStream(). Get them, read them in a thread (they do properly block - you don't want to block the UI thread), pass the data back to the UI thread. Much, much better. I rescind my previous answer.
The article also recommends wrapping the stream in a BufferedReader so that you can do readLine.
Here's one scheme. NDK is not necessary for this one.
You create a temporary file in your app's data dir. You run the binary, specifying the same file as an output direction in the command line using Runtime.exec(). The command line you'll have to specify would invoke not the binary itself, but sh, and one of the command line parameters would be a redirection: >myfile.txt.
You then start a worker thread that reads the same file. You'll need to carefully implement new data detection - as this is a file, not a pipe, the reading operation will simply terminate once the end of file is reached; it won't block until new data appears.
Then you pass the data from the worker thread using Activity.runOnUiThread() or Handler.post() to the main thread, where it's used to update TextView's content.
A cleaner way would involve creating a pipe pair with mkfifo() and redirecting output in place using dup2() from a pipe handle to the file handle value 1 (stdout). That's how they normally do it in the C/Linux world. There's probably an Android example out there, I've never done that.
Oh, and before you do all that, make sure the binary does not have a more palatable interface. More often than not, Linux binaries are based on a static/dynamic library where all the yummy functionality is, one that can be linked with and called directly.
EDIT: Especially if it's logcat. There are other ways to read a log in Android.