0

Programatically running : getRuntime.exec("screencap", "-p /sdcard/image.png") does not do anything except exiting with code=1.

But when USB debugging, running that same command from pc in cmd: adb shell screencap -p /sdcard/dddd.png works.

From previous stackoverflow posts, It seems that programatcially running that command doesn't work because the app does not have permission, and this requires rooting the phone to give su access to the app.

Why does running these commands from the pc doesn't require privileged access ?

EEAH
  • 715
  • 4
  • 17

1 Answers1

2

Difference is that adbd (adb daemon) runs with shell uid, while doing that from the app you're still with your app's uid. So it's different contexts.

There is an SELinux rule that allows adb to invoke the screencap( defined in system/sepolicy/private/adbd.te ):

# Perform binder IPC to surfaceflinger (screencap)
# XXX Run screencap in a separate domain?
binder_use(adbd)
binder_call(adbd, surfaceflinger)
binder_call(adbd, gpuservice)
# b/13188914
allow adbd gpu_device:chr_file rw_file_perms;
allow adbd ion_device:chr_file rw_file_perms;
r_dir_file(adbd, system_file)
Rick Sanchez
  • 4,528
  • 2
  • 27
  • 53
  • same permissions as su UID ? – EEAH Nov 15 '20 at 10:45
  • No. To have same root permissions from adb you'd need to run adb root ( not enable in production builds of OS) – Rick Sanchez Nov 15 '20 at 10:48
  • 1
    @EEAH looked a bit more into AOSP code and updated my answer to add some more details :) – Rick Sanchez Nov 15 '20 at 10:59
  • Thank you. Is It possible to give the app the permission by working with the `shell` uid ? If not, (if permission must be granted by a `su` UID) Is It possible to do this in 3 steps like in this question: https://stackoverflow.com/q/64843656/13695921 ? – EEAH Nov 15 '20 at 11:08
  • You can use media projection api instead. Here's a library https://github.com/bolteu/screenshotty – Rick Sanchez Nov 15 '20 at 17:13
  • The problem with mediaprojection is latency. The real command is "screenrecord", "screencap" is just for testing running adb commands programatically. The app must start a process which recorda the screen, and send the output of that process into a stream. Mediaprojection inteoduce latency – EEAH Nov 15 '20 at 17:19
  • Well, there is no other API to get screen for normal phones. Even WebRTC (which is made by Google) uses that for screenshare. If you want to target root only phones, then sure you can run your screenrecord command with su. I don't see other options. – Rick Sanchez Nov 15 '20 at 18:44