I'm developing a standalone kiosk using an android tablet(iBall running on 4.2.2).Its has the chinese MTK in it.
Suppose when there is no power,then eventually the tab's battery will drain out and have no juice left in it.When the power comes back I want the tab to automatically bootup without any manual intervention.I read online that if we modify the code present in the battery animation file we can achieve this.For the same,I replaced the original code of the battery charging animation file called 'ipod' located at '/system/bin' with :
#!/system/bin/sh
/system/bin/reboot
However,when my tab was shutdown and docked it didnt boot-up,instead it was just stuck at the charging logo.When I replaced the above code with:
/system/bin/reboot
my tab did boot-up when it was shutdown and docked.This means my code was getting stuck at '#!/system/bin/sh' . What could be the reason?
Also,while booting up the tab using the above process I want to boot it up after a delay,for which I used
sleep 20
/system/bin/reboot
but there was no delay in the bootup process(irrespective of the value of sleep that I give)
How do I create this delay ?
PS: I gave 777 permission to the file; owner-root; group-shell.
Kindly assist.Many thanks !
Found the reason my commands were not executing.
The reason was because,I was editing on my notepad++ on windows,until I came across this answer on SO -
" Make sure your text editor is not putting a /r /n and only a /n for every new line. This is typical if you are writing the script on windows.Use notepad++ (windows) and go to edit|EOL convention|UNIX then save it. "
So I changed my convention as per the above answer and ran my code and got the desired result.
I also had the need to make a device (alcatel9002x) autoboot on charger plugged, and come up with a solution replacing the ipod file. It runs the original ipod binary and at the same time, simulate pressing on the power button.
I see the charging animation, but after, it does a "normal" power up.
You probably can do this with a script but I did with with a .c binary.
Solution:
move /sbin/ipod to /sbin/ipod.backup
And use this code as the new binary /sbin/ipod
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <unistd.h>
void run_cmd(char *s)
{
FILE *handle;
char buf[64];
size_t readn;
handle = popen(s, "r");
if (handle == NULL) {
return;
}
while ((readn = fread(buf, 1, sizeof(buf), handle)) > 0) {
fwrite(buf, 1, readn, stdout);
}
pclose(handle);
}
int main(void)
{
FILE *handle;
char buf[64];
size_t readn;
pid_t pid = fork();
if (pid == 0)
{
for(int i=0;i<10;i++)
{
run_cmd("/system/bin/sendevent /dev/input/event0 0001 116 1");
run_cmd("/system/bin/sendevent /dev/input/event0 0000 0000 00000000");
run_cmd("/system/bin/sleep 2");
run_cmd("/system/bin/sendevent /dev/input/event0 0001 116 00000000");
run_cmd("/system/bin/sendevent /dev/input/event0 0000 0000 00000000");
sleep(1);
}
}
else
{
run_cmd("/system/bin/sleep 2");
run_cmd("/system/bin/ipod.backup");
}
return 0;
}
I've compiled it with arm-linux-androideabi-gcc.
As I said, you probably can do this in a bash script, but this is how it worked for me.
Don't forget to chmod 667 and chown root:shell the binaries.
In Sony Xperia GO, the file name is "chargemon" and only by renaming it, the task is done (smartphone will be restart after plug in). (maybe other Sony brand smartphones be the same or similar)
Related
I want to share data between two (ndk-)processes. For this I use ashmem using this source.
One process is continuously reading (read_mem) and one process is writing one time (write_mem).
The problem is that the read process is not getting the values of the writer.
AND
By watching the maps of the reader I found that android deletes the shared memory file right after ashmem_create_region.
read_mem.c
// read_mem.c
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>
#include "ashmem.h"
#define SHM_NAME "test_mem"
int main(int argc, char **argv) {
int shID = ashmem_create_region(SHM_NAME, 2);
if (shID < 0)
{
perror("ashmem_create_region failed\n");
return 1;
}
// right here /dev/ashmem/test_mem is deleted
printf("ashmem_create_region: %d\n", shID);
char *sh_buffer = (char*)mmap(NULL, 2, PROT_READ | PROT_WRITE, MAP_SHARED, shID, 0);
if (sh_buffer == (char*)-1)
{
perror("mmap failed");
return 1;
}
printf("PID=%d", getpid());
do
{
printf("VALUE = 0x%x\n", sh_buffer[0]);
}
while (getchar());
return 0;
}
write_mem.c
// write_mem.c
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>
#include "ashmem.h"
#define SHM_NAME "test_mem"
int main(int argc, char **argv) {
int shID = ashmem_create_region(SHM_NAME, 2);
if (shID < 0)
{
perror("ashmem_create_region failed\n");
return 1;
}
printf("ashmem_create_region: %d\n", shID);
char *sh_buffer = (char*)mmap(NULL, 2, PROT_READ | PROT_WRITE, MAP_SHARED, shID, 0);
if (sh_buffer == (char*)-1)
{
perror("mmap failed");
return 1;
}
printf("PID=%d\n", getpid());
int ch = getchar();
sh_buffer[0] = ch;
printf("Written 0x%x\n", ch);
munmap(sh_buffer, 2);
close(shID);
return 0;
}
This is the output:
Reading
130|shell#mako:/data/local/tmp $ ./read_mem
ashmem_create_region: 3
PID=29655
VALUE = 0x0
Writing
shell#mako:/data/local/tmp $ ./write_mem
ashmem_create_region: 3
PID=29691
A
Written 0x41
Reading again VALUE = 0x0 (by pressing return)
Watching the maps of the reader:
shell#mako:/ $ cat /proc/29655/maps | grep test_mem
b6ef5000-b6ef6000 rw-s 00000000 00:04 116213 /dev/ashmem/test_mem (deleted)
as you can see test_mem is deleted WHILE read_mem is still alive.
Other Information
Both files are compiled as executable using the android ndk-buildcommand
Device: LG Nexus 4 (AOSP Lollypop)
I checked /dev/ashmem it exists.
ashmem taken from here
Ashmem doesn't work like regular shared memory on Linux, and there is a good reason for it.
First, let's try to explain the "(deleted)" part, this is an implementation detail of how ashmem is implemented in the kernel. What it really means is that a file entry was created in the /dev/ashmem/ directory, then later removed, but that the corresponding i-node still exists because there is at least one open file-descriptor for it.
You could actually create several ashmem regions with the same name, and they would all appear as "/dev/ashmem/<name> (deleted)", but each one of them would correspond to a different i-node, and thus a different memory region. And if you look under /dev/ashmem/ you would see that the directory is still empty.
That's why the name of an ashmem region is really only used for debugging. There is no way to 'open' an existing region by name.
An ashmem i-node, and corresponding memory, is automatically reclaimed when the last file descriptor to it is closed. This is useful because it means that if your process dies due to a crash, the memory will be reclaimed by the kernel automatically. This is not the case with regular SysV shared memory (a crashing process just leaks the memory! Something unacceptable on an embedded system like Android).
Your test programs create two distinct ashmem regions with the same name, that's why they dont work as you think they should. What you need instead is:
1) Create a single ashmem region in one of the process.
2) Pass a new file descriptor to the region from the first process to the second one.
One way to do that is to fork the first process to create the second (this will automatically duplicate the file descriptors), but this is generally not a good idea under Android.
A better alternative is to use sendmsg() and recvmsg() to send the file descriptor through a Unix-domain socket between the two processes. This is generally tricky, but as an example, have a look at the SendFd() and ReceiveFd() functions in the following source file was written for the NDK:
https://android.googlesource.com/platform/ndk/+/android-5.0.0_r7/sources/android/crazy_linker/tests/test_util.h
Voila, hope this helps
I want to share data between two (ndk-)processes. For this I use ashmem using this source.
One process is continuously reading (read_mem) and one process is writing one time (write_mem).
The problem is that the read process is not getting the values of the writer.
AND
By watching the maps of the reader I found that android deletes the shared memory file right after ashmem_create_region.
read_mem.c
// read_mem.c
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>
#include "ashmem.h"
#define SHM_NAME "test_mem"
int main(int argc, char **argv) {
int shID = ashmem_create_region(SHM_NAME, 2);
if (shID < 0)
{
perror("ashmem_create_region failed\n");
return 1;
}
// right here /dev/ashmem/test_mem is deleted
printf("ashmem_create_region: %d\n", shID);
char *sh_buffer = (char*)mmap(NULL, 2, PROT_READ | PROT_WRITE, MAP_SHARED, shID, 0);
if (sh_buffer == (char*)-1)
{
perror("mmap failed");
return 1;
}
printf("PID=%d", getpid());
do
{
printf("VALUE = 0x%x\n", sh_buffer[0]);
}
while (getchar());
return 0;
}
write_mem.c
// write_mem.c
#include <stdio.h>
#include <errno.h>
#include <sys/mman.h>
#include "ashmem.h"
#define SHM_NAME "test_mem"
int main(int argc, char **argv) {
int shID = ashmem_create_region(SHM_NAME, 2);
if (shID < 0)
{
perror("ashmem_create_region failed\n");
return 1;
}
printf("ashmem_create_region: %d\n", shID);
char *sh_buffer = (char*)mmap(NULL, 2, PROT_READ | PROT_WRITE, MAP_SHARED, shID, 0);
if (sh_buffer == (char*)-1)
{
perror("mmap failed");
return 1;
}
printf("PID=%d\n", getpid());
int ch = getchar();
sh_buffer[0] = ch;
printf("Written 0x%x\n", ch);
munmap(sh_buffer, 2);
close(shID);
return 0;
}
This is the output:
Reading
130|shell#mako:/data/local/tmp $ ./read_mem
ashmem_create_region: 3
PID=29655
VALUE = 0x0
Writing
shell#mako:/data/local/tmp $ ./write_mem
ashmem_create_region: 3
PID=29691
A
Written 0x41
Reading again VALUE = 0x0 (by pressing return)
Watching the maps of the reader:
shell#mako:/ $ cat /proc/29655/maps | grep test_mem
b6ef5000-b6ef6000 rw-s 00000000 00:04 116213 /dev/ashmem/test_mem (deleted)
as you can see test_mem is deleted WHILE read_mem is still alive.
Other Information
Both files are compiled as executable using the android ndk-buildcommand
Device: LG Nexus 4 (AOSP Lollypop)
I checked /dev/ashmem it exists.
ashmem taken from here
Ashmem doesn't work like regular shared memory on Linux, and there is a good reason for it.
First, let's try to explain the "(deleted)" part, this is an implementation detail of how ashmem is implemented in the kernel. What it really means is that a file entry was created in the /dev/ashmem/ directory, then later removed, but that the corresponding i-node still exists because there is at least one open file-descriptor for it.
You could actually create several ashmem regions with the same name, and they would all appear as "/dev/ashmem/<name> (deleted)", but each one of them would correspond to a different i-node, and thus a different memory region. And if you look under /dev/ashmem/ you would see that the directory is still empty.
That's why the name of an ashmem region is really only used for debugging. There is no way to 'open' an existing region by name.
An ashmem i-node, and corresponding memory, is automatically reclaimed when the last file descriptor to it is closed. This is useful because it means that if your process dies due to a crash, the memory will be reclaimed by the kernel automatically. This is not the case with regular SysV shared memory (a crashing process just leaks the memory! Something unacceptable on an embedded system like Android).
Your test programs create two distinct ashmem regions with the same name, that's why they dont work as you think they should. What you need instead is:
1) Create a single ashmem region in one of the process.
2) Pass a new file descriptor to the region from the first process to the second one.
One way to do that is to fork the first process to create the second (this will automatically duplicate the file descriptors), but this is generally not a good idea under Android.
A better alternative is to use sendmsg() and recvmsg() to send the file descriptor through a Unix-domain socket between the two processes. This is generally tricky, but as an example, have a look at the SendFd() and ReceiveFd() functions in the following source file was written for the NDK:
https://android.googlesource.com/platform/ndk/+/android-5.0.0_r7/sources/android/crazy_linker/tests/test_util.h
Voila, hope this helps
I'm trying to write a wireshark dissector for logcat logs in various text formats.
To do it I need to detect which type of logcat I'm reading, and then get the respectable parts extracted. I thought that using a regular expression would do the trick, but apparently it doesn't.
Here is my regular expression:
[IVDWE]/.*\(\s*[0-9]*\):\s.*
As it should be Perl compatibile I tried it with Perl from command line and it seems to work. Yet when loading a line, ex.
I/bdAddrLoader( 184): option : f=/persist/bluetooth/.bdaddr
with g_regex_match_simple, the expression does not match from opening round brace. I tried escaping it with 1-4 \, but it didn't work.
Edit:
Turns out that I've tried \,'\`,and \\\\ versions, but missed somehow \\...
It works for me with two backslashes:
#include <glib.h>
int
main(int argc, char *argv[]) {
gboolean res = g_regex_match_simple ("[IVDWE]/.*\\(\\s*[0-9]*\\):\\s.*",
"I/bdAddrLoader( 184): option : f=/persist/bluetooth/.bdaddr",
0, 0);
g_message ("%s", res ? "true" : "false");
return 0;
}
I am working on Android platform, and I wonder if it is possible to start an Android app from the kernel source code. For example, at certain point along the linux kernel resume path, I want to start a specific app, say my custom lock screen app. Is that possible?
Edit:
the call_usermodehelper does not work with the "am" utility.
I have code like this in a kernel module:
int result = 0;
char *argv[] = { "/system/bin/am", "start", "-n", "com.twitter.android/com.twitter.applib.HomeTabActivity", NULL};
char *argv[] = {"/system/bin/ls", NULL};
static char *envp[] = {"HOME=/", "PATH=/sbin:/system/sbin:/system/bin:/system/xbin", NULL };
result = call_usermodehelper(argv[0], argv, envp, 1);
but when I insmod, the nothing happens, and result = -8
anyone can help?
I can't speak for certain about Android, but in vanilla Linux, there's a bunch of API's in kmod.h which can do what you want. See this article for details.
I build Android project where I use Android NDK with LibXTract to extract audio features. LibXTract use fftw3 library. Project is consisted of button which runs simple example form libxtract:
JNIEXPORT void JNICALL Java_com_androidnative1_NativeClass_showText(JNIEnv *env, jclass clazz)
{
float mean = 0, vector[] = {.1, .2, .3, .4, -.5, -.4, -.3, -.2, -.1}, spectrum[10];
int n, N = 9;
float argf[4];
argf[0] = 8000.f;
argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
argf[2] = 0.f;
argf[3] = 0.f;
xtract[XTRACT_MEAN]((void *)&vector, N, 0, (void *)&mean);
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "com_androidnative1_NativeClass.c before");
xtract_init_fft(N, XTRACT_SPECTRUM);
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "com_androidnative1_NativeClass.c after");
// Comment for test purpose
//xtract_init_bark(1, argf[1], 1);
//xtract[XTRACT_SPECTRUM]((void *)&vector, N, &argf[0], (void *)&spectrum[0]);
}
Libxtract function xtract_init_fft locate in jni/libxtract/jni/src/init.c execute fftw3 function fftwf_plan_r2r_1d located at jni/fftw3/jni/api/plan-r2r-1d.c
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "libxtract/src/init.c before");
fft_plans.spectrum_plan = fftwf_plan_r2r_1d(N, input, output, FFTW_R2HC, optimisation);
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "libxtract/src/init.c after");
Application hang inside fftwf_paln_r2r_1d without crash or any outher error I must force it to stop working.
fftwf_paln_r2r_1d looks like:
X(plan) X(plan_r2r_1d)(int n, R *in, R *out, X(r2r_kind) kind, unsigned flags)
{
__android_log_print(ANDROID_LOG_DEBUG, "AndNat", "fftw3/api/plan-r2r-1d.c");
return X(plan_r2r)(1, &n, in, out, &kind, flags);
}
From CatLog I can see:
07-16 18:50:09.615: D/AndNat(7313): com_androidnative1_NativeClass.c before
07-16 18:50:09.615: D/AndNat(7313): libxtract/src/init.c before
07-16 18:50:09.615: D/AndNat(7313): fftw3/api/plan-r2r-1d.c
I genereate config.h for fftw3 and libxtract with gen.sh scripts locate in source folder with success. Both librearies are build as static and linked with shared libary libcom_androidnative1_NativeClass.so
Command
nm -Ca libcom_androidnative1_NativeClass.so
shows that used function is included.
Application is built and deploys to device without any problems.
I build fftw3 with flags --disable-alloca, --enable-float and LibXTract with flags --enable-fft and --disable-dependency-tracking
Only ingerention in library source code was added dbgprint and remove define XTRACT_FFT form LibXtract beacouse it can't detect fftw library.
If somebody have any idea about this strange for me behavior please help.
Here I put entire project in github so maybe someone can help me handle this.
https://github.com/bl0ndynek/AndroidNative1
Thanks for FFTW3 maintainer problem is solved.
Solution was to change optimization level from FFTW_MEASURE to FFTW_ESTIMATE (from 1 to 0) in FFTW3,
FFTW's planner (in xtract_init_fft) actually executes and times different possible FFT algorithms in order to pick the fastest plan for a given n. In order to do this in as short a time as possible, however, the timer must have a very high resolution, and to accomplish this FFTW3 employ the hardware cycle counters that are available on most CPUs but not on Android default ARM configuration.
So this algorithm use gettimeofday() witch have low resolution and on ARM took forever on xtract_init_fft.
It looks to me like you are missing some terminating condition in your recursive function X() which would put you in an infinite loop.