I am transfering files to an android device using adb push. I am able to push the files to the SD card, and the commandline tells me the transfer rate, file size, and time elapsed, e.g:
C:\Users\some_guy\Pictures>adb -d push wilford.jpg /sdcard/wilford.jpg
2558 KB/s (13104 bytes in 0.005s)
I'm looking to create an app or service that can subscribe to events through a broadcast receiver to get updates on when the adb push starts, finishes, and includes the current file transfer rate while the transfer is in progress. So, as the file gets written from adb, it would notify my applicatoin of its current % complete and transfer rate. Is this possible? What permissions are required and how would the application subscribe to the updates? I've looked around at the list of permissions and other resources and can't figure out a way to do this.
Another possibility would be to simply monitor the SD card file system for incoming files, but I'm not sure what that would give me beyond monitoring when new files are written fully.
I had a very similar issue a while back, and I believe I exhausted all options to no avail. There's no broadcast as part of the adb push process. However, you can create your own broadcasts before and after each push using adb shell am broadcast ... and even send extras (such as filename or transfer rate).
This will be easier if you use bash or python to script your adb transfers, rather than windows batch files -- I wound up using the jython implementation for MonkeyRunner included with the SDK tools, and only had to drop out to the shell to do the actual file push, as MonkeyRunner doesn't provide that.
You can detect at least the creation of new files using the Linux kernel inotify mechanism on the target directory.
Android exposes this functionality through the FileObserver class:
Monitors files (using inotify) to fire an event after files are accessed or changed by by any process on the device (including this one). FileObserver is an abstract class; subclasses must implement the event handler onEvent(int, String).
Each FileObserver instance monitors a single file or directory. If a directory is monitored, events will be triggered for all files and subdirectories inside the monitored directory.
see http://developer.android.com/reference/android/os/FileObserver.html
Note that the mechanism is not recursive in that monitoring a directory monitors only entires in that directory, not entries in its subdirectories. This question discusses some recursive possibilities.
Related
Using the legacy sysfs GPIO under Android and Linux the first step in the process is toe export the particular GPIO pins you want to use. And when you are done with the GPIO pin to unexport it.
I've been looking for an explanation of what the export command actually does however everything I've found is about the builtin bash command which has nothing to do with GPIO.
Then I realized the actual command from the command line was echo 938 > /sys/class/gpio/export and /sys/class/gpio/export is a special device file in folder /sys/class/gpio.
The only comment that I have found indicates that writing the GPIO pin number to /sys/class/gpio/export causes the GPIO special file associated with that GPIO pin to be "exported to user space" which then allows a user application to use the specified GPIO pin with file I/O to the special device file.
GPIO Sysfs Interface for Userspace
“export” …
Userspace may ask the kernel to export control of a GPIO to userspace
by writing its number to this file.
Example: “echo 19 > export” will create a “gpio19” node for GPIO #19,
if that’s not requested by kernel code.
“unexport” …
Reverses the effect of exporting to userspace.
Example: “echo 19 > unexport” will remove a “gpio19” node exported
using the “export” file.
So if I specify echo 938 > /sys/class/gpio/export then a special device file folder /sys/class/gpio/gpio938 with special device files /sys/class/gpio/gpio938/value and /sys/class/gpio/gpio938/direction are created. And when I do an echo 938 > /sys/class/gpio/unexport then those special device files are removed?
In researching about using GPIO pins with a DragonBoard 410C under Android 5.1 an online course about this device I am taking said to add the following lines to the boot initialization script.
set -A pins 938 915 1017 926 937 930 914 971 901 936 935
for i in 0 1 2 3 4 5 6 7 8 9 10
do
echo ${pins[i]} > /sys/class/gpio/export;
chmod 777 /sys/class/gpio/gpio${pins[i]};
chmod 777 /sys/class/gpio/gpio${pins[i]}/value;
chmod 777 /sys/class/gpio/gpio${pins[i]}/direction;
done
My understanding is that these commands create the special device files for GPIO pins 938, 915, 1017, 926, 937, 914, 901, 936, 935 so that an application can read and write to these GPIO pins to do something such as turning an LED on and off by writing values to, for instance /sys/class/gpio/gpio938/value.
My understanding about this boot initialization script is that this removes the need for a user to use the sudo command with each of the shell command lines in order to perform these commands by a user before running an application that accesses the GPIO pins using sysfs. Is that true?
My Questions
What are these special device files /sys/class/gpio/export and /sys/class/gpio/unexport and how are they connected to some kind of functionality in the Linux kernel which creates and destroys special device files in the /sys/class/gpio folder?
With the suggested change to the boot initialization script are the special device files representing the GPIO pins created with access by anyone so an application program can just use the pins and not bother with export or unexport? A user application can just perform read/write to the special device without having to use sudo echo 938 > /sys/class/gpio/export first?
What is the access and sharing permissions for these special files created by the boot initialization script and can multiple applications be manipulating the same GPIO pins simultaneously?
The pseudo-files in /sys/class/gpio are fairly thin wrappers around function calls in the kernel interface. There's a clue in the kernel documentation [1] about the purpose of the import/export functionality:
After a kernel driver requests a GPIO, it may only be made available
in the sysfs interface by gpiod_export(). The driver can control
whether the signal direction may change. This helps drivers prevent
userspace code from accidentally clobbering important system state.
This explicit exporting can help with debugging (by making some kinds
of experiments easier), or can provide an always-there interface
that’s suitable for documenting as part of a board support package.
So, essentially, this functionality exists to prevent user-space applications carelessly trampling on the state of I/O devices. How useful it is in practice, I don't know.
[1] https://www.kernel.org/doc/html/latest/admin-guide/gpio/sysfs.html
There are several directory structures within the Linux file system that are not actual disk file directories. Instead these directory structures and the "files" within them are pseudo files or Linux operating system services and data that are presented as files and can be accessed using file operations but are not actual files stored on a persistent store such as a hard disk or solid state disk.
A Study of Modern Linux API Usage and Compatibility: What to Support When You’re Supporting
In addition to the main system call table, Linux exports many
additional APIs through pseudo-file systems, such as /proc, /dev, and
/sys. These are called pseudo-file systems because they are not backed
by disk, but rather export the contents of kernel data structures to
an application or administrator as if they were stored in a file.
These pseudofile systems are a convenient location to export tuning
parameters, statistics, and other subsystem-specific or device
specific APIs. Although many of these pseudo-files are used on the
command line or in scripts by an administrator, a few are routinely
used by applications. In order to fully understand usage patterns of
the Linux kernel, pseudo-files must also be considered.
An analogy for pseudo files
A way to think about these pseudo files from a user perspective is they are a kind of Remote Procedure Call interface to the Linux kernel that uses file system semantics to request that some operation be done. The file system semantics map to the following generic actions and behavior:
open the pseudo file means to open a connection between the user application and some functionality within the Linux kernel
read the pseudo file means to read a block of data provided by some functionality within the Linux kernel through the connection
write the pseudo file means to send a request message to some functionality within the Linux kernel through the connection (the message may be a command with data, a command only, or data only)
close the pseudo file means to close a connection between the user application and some functionality within the Linux kernel
Different pseudo files expose different Linux kernel data and services which means that the interface specification as to how the file operations map to the Linux kernel functionality exposed through the pseudo file will vary depending not only on the Linux kernel functionality or handler for the pseudo file but also the Linux kernel version.
This StackOverFlow posting, Create sysfs entry from kernel module , contains a simple example of a handler for a pseudo file in /sys showing the basics of providing the function interfaces the Linux kernel needs to hook the handler for the new pseudo file into the Linux kernel.
This StackOverFlow posting, How to create proc entry under /proc/driver? , contains a simple example of a handler for a pseudo file in /proc.
Both of these simple examples have a similar structure to the source code. However these specific examples may be using deprecated Linux kernel interfaces so I provide these links only to illustrate the underlying functionality of a pseudo file handler.
export and unexport
Normally the GPIO pins of the underlying hardware on which Linux is running are not exposed to user applications. The pins are used by the Linux kernel using device drivers to interact with devices.
The purpose of export is to expose selected GPIO pins to user space as pseudo files allowing a user application to perform their own interactions with some hardware. Not all available or possible GPIO pins may be exposed. What pins can be exposed using export will depend on what /sys handlers have been inserted into the Linux kernel and what those handlers allow.
What pseudo files are actually exposed and how those pseudo files are used will depend on the function of the GPIO pin, e.g. a digital pin versus an analog pin versus a pin that supports PWM or has pullup or pulldown resistors. What files are exposed will also depend on what functionality the handler for /sys/class/gpio/ provides. A GPIO pin may have a pullup or pulldown resistor that could be used but the handler may not provide an interface to manipulate it.
A request to the export pseudo file will create a pseudo file directory representing the requested GPIO pin. This is done by writing a request to the export pseudo file with a message containing the data the export command needs in order to properly identify the GPIO pin requested. This message is then processed by the GPIO export sysfs handler in the Linux kernel to create the pseudo file folder representing the GPIO pin along with the pseudo files that provide the interface between the user application and the sysfs handler for the specified GPIO pin. The handler provides the layer between the physical GPIO pin and pin device driver and the pseudo file representation or interface.
The unexport pseudo file removes the GPIO pin pseudo file so that interacting with the represented GPIO pin from a user application is no longer available.
Note concerning PWM sysfs support: Just as there is support for GPIO pins through the sysfs interface and /sys there is also support for PWM pins. The root folder is /sys/class/pwm and the functionality is similar in architecture to that for GPIO pins. There is a similar export and unexport functionality to make the PWM pins available and using the exported PWM pseudo files are through standard file operations on a set of files associated with a pseudo file folder representing the PWM pin. See Using PMIC PWM on Dragonboard410c which describes the basics of "PWM is exposed via MPP_4 pin, which is pin 28 on the Low Speed Expansion Connector."
The boot script changes
The boot script changes use the /sys/class/gpio/export to create the requested GPIO pseudo file. However the created pseudo file has a set of default access permissions that are set when the pseudo file is created. Since the creation is during initialization with root privileges, the chmod command is used to allow any user application to interact with the created pseudo files and not just the user, root, which created them.
Since the export is being done during boot up and initialization, the intent is to create GPIO pin pseudo files which will stay in place while the device is powered up and to stay in place as long as the device is in use.
Each GPIO pins on the low power connector of the DragonBoard 410C are represented by several pseudo files, value which is used to communicate the value of the pin (whether it is high or low) and direction which is used to communicate the direction of the pin (whether it is an input pin or an output pin). So we need to do a chmod on each of these pseudo files we want the user application to access including the pseudo file folder in which these pseudo files are located, for example /sys/class/gpio/gpio938 which contains /sys/class/gpio/gpio938/value and /sys/class/gpio/gpio938/direction.
I have 285 different networks between the different campus apartments for which I am trying to add network profile information to a series of Lenovo Tab4 10 TB-X304F so they may connect without having our Apartment Managers carry around a list of wifi passwords.
So far, I have created a custom wpa_supplicant.conf file with all of the network blocks for each of the networks across the campus. I have rooted the device. I have pushed this custom file to /sdcard/TWRP. I then copied the file from /sdcard/TWRP to /data/misc/wifi.
Now we run into my issue, it appears that this file is stored in at least 3 locations which I have currently found, /etc/wifi, /system/etc/wifi and /data/misc/wifi. The other part of the problem is that these files appear to be rewritten/overwritten on boot.
Which of these file locations should I be updating with my custom wpa_supplicant.conf file? How do I stop the file from being rebuilt on boot? Or, how do I make the process, which builds the file on boot, build it with the networks I want added?
Am I missing any other steps?
I have also tried running " wpa_supplicant -iwlan0 -c/sdcard/TWRP/wpa_supplicant.conf -B " as a command in the adb shell with super user permissions and didn't receive any output or confirmation. What am I misunderstanding about the wpa_supplicant command?
Just in case here are the settings currently in /data/misc/wifi/wpa_supplicant.conf which I have copied into my custom file:
ctrl_interface=/data/misc/wifi/sockets
disable_scan_offload=1
driver_param=use_p2p_group_interface=1
update_config=1
device_name=LenovoTB-X304F
manufacturer=LENOVO
model_name=Lenovo TB-X304F
model_number=Lenovo TB-X304F
serial_number=<SerialNumber>
device_type=10-0050F204-5
config_methods=physical_display virtual_push_button
p2p_disabled=1
pmf=1
external_sim=1
tdls_external_control=1
I do not really know much, but I can successfully edit/replace
/data/misc/wifi/wpa_supplicant.conf
provided that (1) I have the device in Aeroplane Mode and (2) I make sure that the file belongs to user "system" and group "wifi", and has permissions 660. If I forget (1) or (2), somehow the file reverts later to the one before editing/replacing or is reinitialized to virtually empty (I am not sure when either happened exactly, but I noticed both cases). I believe your use of TWRP is effectively equivalent to my use of Aeroplane Mode--but I am not aware that you can "chown" a file in TWRP. I never had to touch any of the other locations where the file can apparently be found.
For reference, the commands to get the right ownership and permissions should be
chmod 660 /data/misc/wifi/wpa_supplicant.conf
chown system:wifi /data/misc/wifi/wpa_supplicant.conf
Of course, all this needs one to be root.
I'm porting AOSP to a custom board, and I need /dev/ttymxc4 to be owned by u-blox so that the GPS driver can use it. (Nothing else needs to use it.)
Ideally, I would like this to be specified in the build process, rather than as I run-time hack.
Where is the best place to manage the ownership of device nodes in /dev?
I assume when you say GPS driver you are actually perhaps referring to a user space daemon which needs to communicate with a Linux kernel driver?
Traditional Linux DAC permissions are normally established in Android at boot by the init process, usually in a file such as init.common.rc in the appropriate device directory of AOSP. This is also where the daemon (aka init service) is defined. Typically you would reuse the system group for your daemon and then chown the device files to system with standard perms such as 0660 or 0440.
Remember that SELinux MAC permissions must be established as well in all recent versions of Android. Establishing SELinux permissions is fairly complex but generally when you must do the following when setting up a new daemon that needs to communicate with a kernel driver:
Update file_contexts to assign a label to the file created by the kernel driver
Add a new TE file which: establishes a new domain for the daemon, defines the domain transition during init process, includes rules for the new domain to access necessary labels
See:
https://source.android.com/security/selinux/customize
https://source.android.com/security/selinux/implement
https://source.android.com/security/selinux/images/SELinux_Treble.pdf
Examples:
https://android.googlesource.com/device/google/marlin/+/oreo-mr1-release/init.common.rc
https://android.googlesource.com/device/google/marlin/+/oreo-mr1-release/sepolicy/init_radio.te
The best way is to use ueventd file. Here:
https://github.com/android/platform_system_core/blob/master/rootdir/ueventd.rc
Or your board specific ueventd..rc (should be in your device tree)
I have a file on the sdcard which is being written to by an app constantly, I need to pull the file from the device as it is being written to by the app, onto my windows host machine for further analysis.
adb pull is no good as it pulls the whole file then stops, but of course the file is still being written too. And anyway the file gets very big so i don't want to copy the whole file each time, just the parts that have been written to since i last read it.
adb shell dd might be an option but i can only get it to copy from one file on the sdcard to another file on the sdcard, i.e. not my windows machine:
e.g. adb shell dd if=/sdcard/input.pcm of=/sdcard/output.pcm then use skip and seek dd options.
if i used dd and a pipe:: adb shell dd if=/sdcard/input.pcm > output.pcm the output file has some corruption: 0x0D, 0x0D is added randomly to the pcm data. Same as if I just do adb shell cat input.pcm.
I also thought about writing the data to logcat and parsing it, but this is rather clunky and messy and there is a ton of data.
Another option might be splitting the file up in to lots of small files as they are being written and then using adb pull.
None of these are ideal. Ideally i'd like a program on the host that can pull the data at my control, e.g fopen, fread, etc. But I am not sure if this is possible.
Can anyone suggest how I might be able to fulfill my requirements:
Read all the file that's available to windows host
Read the parts of the file that have been updated since i last did a read (e.g every 100ms)
Many thanks in advance.
I think it is your specific requirement, so it doesn't matter to modify the source code of Android.
Why don't you implement another adb command? Then you can record the last read position and use adb newcommand filename to incrementally pull out the file.
The implementation of adb can be divided into two parts: host side, and adbd.
In host side, when you type a command, it goes to adb_commandline() in commandline.c.
if(!strcmp(argv[0], "pull")) {
if (argc == 2) {
return do_sync_pull(argv[1], ".");
} else if (argc == 3) {
return do_sync_pull(argv[1], argv[2]);
} else {
return usage();
}
}
Then the do_sync_pull continously communicate with the adbd. The adbd(adb.c) listens to the request sent from the host side.
A simple approach is to add another argument to the do_sync_pull, and let the adbd continously seek the file and send back the file content.
I would like to know high level idea of how Android Modem code will call/pass message to Android application layer. Say we take SMS for example. If network sends SMS and Modem (say Qualcomm C code parses it) how is it transmitted to Android Application layer?
Is there always a JNI call happening? as interface between modem and Android? Can you please share the information with us. Thanks
In almost all android source base as found in the AOSP/CAF/CM source (Android Open Source Project, CodeAurora Forum, Cyanogenmod respectively), will have C code called the rild, (Radio Interface Layer Daemon). This is commonly found within the /hardware/ril of the source tree.
This daemon runs from the moment Android boots up, and creates a socket called /dev/socket/rild and /dev/socket/rild-debug. There will be a proprietary library coming from Qualcomm, HTC, that gets dynamically loaded at run time upon boot. It is that proprietary library that in turn, communicates to the radio firmware. And the rild's hooks for the call-backs into the proprietary library is established there and then.
At the rild layer, via the aforementioned socket, is how the Android layer (found in the source tree, frameworks/base/telephony/com/android/internal/telephony/RIL.java) communicates.
On the Java side, it opens the socket for reading/writing, along with establishing intents and setting up delegates for broadcasting/receiving events via this socket.
For example, an incoming call, the proprietary library, invokes a callback hook as set up by rild. The rild writes standard generic AT Hayes modem commands to the socket, on the Java side, it reads and interprets the modem commands, and from there, the PhoneManager broadcasts CALL_STATE_RINGING, in which Phone application (found in the source packages/apps/Phone) has registered a receiver and kickstarts the User interface, and that is how you get to answer the call.
Another example, making an outgoing call, you dial a number on Android, the intent gets created and which in turn the PhoneManager (This is the root of it all, here, cannot remember top of my head, think its in frameworks/base/core/java somewhere in the source tree) receives the intent, convert it into either a sequence of AT Hayes modem commands, write it out to the socket, the rild then invokes a callback to the proprietary library, the proprietary library in turn delegates to the radio firmware.
Final example, sending text messages, from the Messaging (found in packages/apps/Mms source tree) application, the text you type, gets shoved into an intent, the PhoneManager receives the intent, converts the text into GSM-encoded using 7-bit GSM letters (IIRC), gets written out to the socket, the rild in turn invokes a callback to the proprietary library, the proprietary library in turn delegates to the radio firmware and the text has now left the domain of the handset and is in the airwaves somewhere... :) Along with sending a broadcast message within Android itself, provided that READ_PHONE_STATE permission is used and specified in the AndroidManifest.xml.
Likewise conversely, when receiving a text message, it is in the reverse, radio firmware receives some bytes, the proprietary library invokes the callback to the rild, and thus writes out the bytes to the socket. On the Java side, it reads from it, and decodes the sequence of bytes, converts it to text as we know of, fires a broadcast with a message received notification. The Messaging application in turn, has registered receivers for the said broadcast, and sends an intent to the notification bar to say something like "New message received from +xxxxxx"
The intents are found in frameworks/base/telephony/java/com/android/internal/telephony/TelephonyIntents.java
That is the gist of how the telephony system works, the real beauty is, that it uses generic AT Hayes modem commands thusly simplifying and hiding the real proprietary mechanisms.
As for the likes of Qualcomm, HTC, forget about it in thinking they'd ever open source the library in question because the radio telephony layer is embedded within the S-o-C (System on a Chip) circuitry!
Which is also, as a side note, why its risky to flash radio firmware, some handsets provide the capability to do it, flash the wrong firmware (such as an incompatible or not suitable for handset), kiss the handset good-bye and use that as a door stopper or paper-weight! :)
It should be noted, that there is zero JNI mechanisms involved.
This is from my understanding of how it works, from what I can tell is this, the radio firmware is loaded into a memory address somewhere where the linux kernel has reserved the address space and does not touch it, something like back in the old PC days when DOS booted up, there was reserved addresses used by the BIOS, I think, its similar here, the addresses marked as reserved are occupied by the firmware, in which the proprietary radio library talks to it - and since the library is running in the address space owned by the kernel, a lá owned by root with root privileges, it can "talk" to it, if you think of using the old BASIC dialect of peek and poke, I'd guess you would not be far off the mark there, by writing a certain sequence of bytes to that address, the radio firmware acts on it, almost like having a interrupt vector table... this am guessing here how it works exactly. :)
Continuing from the explanation by t0mm13b, When we talk about a smartphone, think of 3 layer operations wrt to SMS/Calls.
RIL (User level) <-> AP <-> CP
AP : Application Processor(Where your Android OS runs. Think of games, songs, videos, camera etc running on this processor)
CP : Cellular Processor (Which actually deals with Air-interface for incoming/outgoing calls/sms, interacts with Network Tower etc ..)
Now let say some data is received at CP side (It could be internet data/sms/call). Now there are certain logical channels between AP and CP. So CP will push the data received to a corresponding channel based on type of data. This data will be received by AP. AP will send this data back to RIL/App. RIL will decode this data (specially call/sms data). Based on that gives notification to User about SMS/Call.