How to execute shell commands from Ruby in their own shell? - android

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.

Related

how to enable Multi display feature on Android O

Did anyone tried Android multiple display feature which is new in Android O
Following steps which is not working for me
1.connect hdmi cable to mobile(not sure can use USB as well)
2.make device in root and give following command (expect app is installed)
and not seen that app is launching on secondary(Multiple display feature
) it's just reflecting mobile display as it is because connected hdmi cable
adb shell am start com.Chrome.Canary --display 1
Please suggest any other way or any command to make it work?
Android in general do mirroring when two displays are connected. Right now google has not enabled support for touch and display mapping on the two displays. But if you want to launch any activity on any of the two displays then the command adb shell am start "your_activity" --display display_id will launch your activity on that particular display id. If the above command doesn't launch your activity then you can use adb shell am stack start display_id "your activity". This will also work. But regarding touch, it will be mapped to the primary display (display id 0). As per google you can enable the mapping of touch in EventHub.cpp of Android source code but till now I haven't found it useful. Hope my answer helps you.
Ran using below procedure passed with dell monitor:
ADB shell can be used to call Activity Manager(am) for starting any system actions (or an activity).
The syntax:
adb shell am start [-n (component)] [-a (action)] [-t (mime type)] [-d (data_URL)]
examples:
1. For starting ‘Settings app’:
adb shell am start -n com.android.settings/.Settings
In the above-mentioned command, we set component(-n) to be settings in a specific format.
For starting ‘Gallery app’:
adb shell am start -t image/* -a android.intent.action.VIEW
In the above-mentioned command, we are setting action(-a) for opening the default app for gallery with mime type(-t) to be image/*
In general, for external display the ‘display_id’ starts from ‘1’ in an increasing order, final command to do multi display operation is
adb shell am start -n com.android.settings/.Settings --display 1
The above command will display ‘Settings’ app only in external display with display_id = 1. The primary display will be in the same mode as before executing the command.

running adb with python: executing a program and ending it

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.

how can i reduce the time lag to execute an adb shell command to perform swipe input on my android device

I want to input swipe commands back to back using a c program and adb shell to my android device .
But the lag between the commands is preventing me from achieving my goal.
Is there anyway to reduce this lag??
You can record some input and repeat it directly.
For example:
Record:
cat /dev/input/event0 > inputdata
Replay:
cat inputdata > /dev/input/event0
To find the correct event number you can use the getevent -p command.
There is no "lag between the commands". The input command is a java application and it takes about a second (depending on your device) to launch it. So you can not inject 2 events back to back faster than that.
You could either write your own input command which would accept multiple sets of coordinates in one take thus eliminating the need to run the command multiple times. Or you could use series of sendevent commands for emulating your gesture instead.

How to make a double tap to expand the video screen using android adb commands

I am trying to analyze a streaming video in my Android device. I want everything automated by scripts, because the device has to repeat the test a lot of times and I want to do it remotely (it is LAN connected). For that, I am using a special app, which starts to stream the video on a small-sized screen (it is special for that, I must expand the screen and I must use only this android app). A double-tap should be made to expand the screen (there is no button to expand, I can do it only double-tapping manually).
Due to my automation, I am trying to expand the video screen from a batch file when the video is streaming executing the following:
adb shell input tap x1 y1
adb shell input tap x1 y1
But it does not work. I've tried also with input touchscreen, input swipe x1 y1 x1 y1, I put every combination in a infinite loop, and it never expands. Maybe because the double tap it is too slow.... or maybe because that event needs to send a tap-release event.
Anybody encountered this problem already? How could I do a double tap to expand the screen remotely?
Thank you for your time!
Finally I got it. First I've recorded the double-tap event and stored it into a binary file:
adb shell
cd /sdcard/
cat /dev/input/event_X > doubletap
Do the doubletap wherever you want it, and then, end the recording with CTRL+C
The event_X is the event called sec_touchscreen.
It can be got from:
adb shell getevent -p
Then, you can replay the doubletap with:
adb shell "cat /sdcard/doubletap > /dev/input/event_X"
In my case, it was tricky because it did not work executing once the replay, but two, like:
adb shell "cat /mnt/sdcard/doubletap > /dev/input/event_X"
adb shell "cat /mnt/sdcard/doubletap > /dev/input/event_X"

What does 'adb shell start/stop' do?

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.

Categories

Resources