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.
Related
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 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?
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 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