Question
What do adb shell start and adb shell stop actually do?
Description
I think they call /system/bin/start and /system/bin/stop. But these two executables don't give any clue about what they do. When tested on a real device, I found the zygote process is started and stopped. So these two commands seem to control the Android runtime (which corresponds to the yellow and blue parts in the figure below).
But what exact processes/services are started/stopped with these two commands?
Basically, all your Android services are restarted; those that are created and registered in SystemServer.java. This is called within the "Context of Zygote". So yes, Zygote is stopped.
All your services registered with ServiceManager in Android will get removed within ServiceManager. To restart them, do adb shell start.
Also note that SystemServer is started by Zygote, so init.rc tells that if Zygote is stopped, then even SystemServer must be stopped. Even SurfaceFlinger dies, since it's started from SystemServer but natively.
Run this on your device
grep ^service /init*rc
I have been wondering what "stop" does on Android too. Learned from someone that "stop" stops AP being rendered by SurfaceFlinger.
Had a try with the command like below. Execute the command, wait for a few seconds and then execute "stop" on Android. The command keeps printing increased number and creating .txt files. So maybe it only stops the Android part while the Linux part remains active. Just FYI.
busybox sh -c 'i=0;while [ $i -ne 100 ]; do echo $i >> count.txt; sleep 1; i=$(($i + 1)); echo $i; touch "$i.txt"; done;'
adb shell "start --help"
usage: start [SERVICE...]
Starts the given system service, or netd/surfaceflinger/zygotes.
adb shell "stop --help"
usage: stop [SERVICE...]
Stops the given system service, or netd/surfaceflinger/zygotes.
Related
I am trying to perform adb interactions through python code.
I have an endless executable on the android device which i would like to start and after 10 seconds kill it.
right now, i can get the program to start but cannot kill it other the manually pressing ctrl+c.
procID = subprocess.Popen(["adb", "shell"], stdin=subprocess.PIPE,)
procID.communicate('su\n endless_program data/test 5\n')
time.sleep(5)
os.kill(procID, signal.SIGINT)
procID.kill()
i tried killing it with os.kill or procID.kill but both don't seem to work.
I have also trying using pexpect, but for some reason i cant get it to run adb.
You are just killing the adb shell session, which won't kill the running application. If you would like to kill the running Android application, you have to stop the app over the adb shell. For details have a look at this stackoverflow answer.
I am trying to make a small shell script that would pass some adb commands, reboot the device, and once the device reboots, again pass some adb commands.
I was thinking of passing adb devices at regular intervals through out the period the device is rebooting so as to know when the next adb command could be passed(not sure there are any other better methods for doing this). For this purpose I need to check the response of each adb devices command. Is there any method to read this response?
I am a novice in shell scripts. Kindly excuse it the method I am adopting to achieve this task is not correct.
Any help or suggestions would be much appreciated.
You can make an if statement from the response:
device=$(adb devices)
while true
do
sleep 5
if [ "$(adb devices)"="$device" ];
then
echo "device rebooted"
break
fi
done
This would check ten times in an intervall of 5 secs.
I'm writing a small Ruby script that performs some adb shell commands. The problem happens when I attempt to run a screen record on the android device and then send some swipe and touch events.
If I run adb shell screenrecord without an "&" at the end the touch and swipe, events only happen when the screenrecord times out:
adb shell screenrecord --time-limit 10 /sdcard/dumper.mp4
If I run it with an "&" at the end, the screenrecord cuts immediately when a touch or swipe event is carried out despite passing a high --time-limit option to screenrecord.
adb shell screenrecord --time-limit 10 /sdcard/dumper.mp4&
Is there a way I can just create a child process have it run the screenrecord and just dies when the screenrecord is finished and in parallel execute the touches and swipes?
I tried using fork but the parent ends up dying and if I re-exexcute the program the touches and swipes are carried out.
This is the code I used to fork:
def adb(arg)
fork do
exec("adb -s #{ARGV[0]} #{arg}")
exit
end
end
I tried looking at spawn as an alternative but it just wouldn't work:
if line.include? "<record>"
puts "comes here"
duration=line.scan(/\d+/).first.to_i
adb_sep("shell screenrecord --time-limit #{duration} /sdcard/demo.mp4")
It basically parses an XML file with tags to trigger a record process. I'm confident the exec isn't failing because I tried simulating the steps in IRB.
Running
irb>>exec(<adb screenrecord command>)
kills the Ruby shell after it is done as expected however.
irb>>system(<adb screenrecord command>&)
irb>>system(<adb tap or swipe command>)
works like a dream! It does exactly what I want it to do. Pulling the recorded video from the device shows exactly what I want.
I think I've figured out what's going on. Running adb with & sent the adb process to the background and recording stopped. Running adb tap brought it back to the foreground. consequently I'm getting chopped up videos.
I guess I would have to trigger the adb screenrecord in its own shell.
A bash analogy with a human would be to open one terminal, start recording the screeen. Open another terminal, start sending taps and swipes.
As it turns out this was an Android shell screen record problem and not a Ruby problem.
Android is carrying out optimizations of recorded video length that skew my output video. It only records the video from the first UI change to the last UI change.
I need to forward a port on an android emulator, right now I had to type the command every time:
adb forward tcp:23946 tcp:23946
Is there any way to make this automatic? I tried to replace adb with a script but that command won't work until the device is up and running.
Any ideas?
Based on this answer (which I've tested and works, though it wasn't for a scenario like this one), you could simply write a script that waits until the emulator is booted.
Something like (pseudocode, don't know which platform you're on) :)
emulator #emulator-name
while ('adb shell getprop init.svc.bootanim' == "running") sleep(10s)
adb forward tcp:23946 tcp:23946
I want to know whether media player service (registers with media.player when device boots up) is running or not using adb shell. Is it possible?
I tried running ps command but no success.
As mentioned already, adb shell service list will only list system services.
As explained in Android Emulator: How can I get a list of services that are running, you can look for services created by apps by using
// List all services
adb shell dumpsys activity services
// List all services containing "myservice" in its name
adb shell dumpsys activity services myservice
If it returns something, it means the service is installed. To know if the service is currently started or stopped, look for app=ProcessRecord(...) or app=null respectively.
You can also do it Linux style with a simple
ps | grep myservice
while inside of your shell.
Try the command line
adb shell service list
I get a list of service names and their package names as well.
To simply check whether a specific service is running, use:
adb shell service check <service>
For example, adb shell service check media.player gives Service media.player: found if it's running and Service media.player: not found otherwise.
If you need more detail, try dumpsys <service>. For example, adb shell dumpsys media.player returns information about media.player's clients, open files, etc.
Finally, if you really need serious detail for debugging, try adb shell dumpsys activity services which shows what's going on from ActivityManager's point of view. This includes information about intents, create times, last activity time, bindings, etc., etc. You can redirect the output if you want to store it for later viewing/searching. It's typically rather lengthy.
For Android 10, list all currently running services:
adb shell dumpsys activity services | grep "ServiceRecord" | awk '{print $4}' | sed 's/.$//' | sort
To know whether an app process is running or not (background or foreground):
adb shell pidof <package.name>
It'll return empty string if process is not running else its pid.