How does Device File Explorer on Android Studio works
Problem Statement
Problem Statement
When I tried to upload file to the package’s data dir, I tried to use adb push
command to push the file on /sdcard
directory, then use run-as
command copy file to the app’s directory, but when I use run-as
command, it can’t access the /sdcard
directory, but when I tried to use Device File Explorer
on the Android Studio, it can upload file, it was amazing, so I tried to find out why the Device File Explorer
can upload files to the application’s data dir, I want to find the source code for Device File Explorer
, but I didn’t find it. Then I think about the logs of the Android Studio, I mentioned the log directory for Android Studio on my previous article.
The log folder for Android Studio is ~/Library/Logs/Google/AndroidStudio<version>
, when I monitor the logs on the idea.log
and find that the Device File Explorer print the commands it used when operating, this article is what I found when I operate with it for both Emulator and Physical Device.
What can Device File Explorer do
When we open the Device File Explorer
, we can choose the devices that was connected to the computer, both Simulator and Physical Devices. When we select a device, it will list the directory on the device as a directory tree, and we can navigate on the directory tree. We can also upload and download files from the device to local machine.
How does Device File Explorer do?
From the log we can see that the Device File Explorer run the different commands for Emulator and Physical Device, so I will explain both of them, from the log, we can see that the Device File Explorer use the adb
command-line tool to list, upload and download files.
For emulators, because when we connect with adb
, we can switch to super user, so on the emulator, it will use the super user to do the job, but for physical devices, because we can’t switch to super user, so it will use run-as
command to do the jobs.
List devices
To list the devices, we can use adb devices -l
, but on the log, I didn’t see that the Device File Explorer
use this command, but on the Android Studio, it can list all the connected devices, so I think it just use the devices that Android Studio has got.
Run command with adb
From idea.log
we can see some logs that Device File Explorer printed like below:su 0 sh -c 'id' || echo ERR-ERR-ERR-ERR
To execute the command above, we can run with adb shell
like following:adb -s <$ANDROID_SERIAL> shell "su 0 sh -c 'id' || echo ERR-ERR-ERR-ERR"Example:
$ adb -s emulator-5554 shell "su 0 sh -c 'id' || echo ERR-ERR-ERR-ERR"
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:su:s0
List packages
The applications data dir is under /data/data/<package>
, the Device File Explorer will list the package list when we navigate to /data/data
dir, to list packages under /data/data
dir, it’s different for emulator and physical device
Emulator
For emulator, it just use root user to list the content under /data/data
folder.
Physical Device
For physical device, it just show three folders under /data
dir, which are: app
, data
and local
. When we open folders under /data
dir, it will run the following commands:# List /data/data dir
pm list packages || echo ERR-ERR-ERR-ERR# List /data/app dir
pm list packages -f || echo ERR-ERR-ERR-ERR# List /data/local dir, just show a dir named tmp
List content of a package
Emulator
For emulator, it still use root user to list the content under the package’s data dir.
Physical Device
For physical device, it will use run-as
command to list the content of a package’s data dir, the command below is to show the content of the package named com.swanwish.logviewer
.run-as com.swanwish.logviewer sh -c 'ls -al /data/data/com.swanwish.logviewer/' || echo ERR-ERR-ERR-ERR
We can test this command with adb shell
like below:$ adb -s adb-816d824e-2lp6Pe._adb-tls-connect._tcp. shell "run-as com.swanwish.logviewer sh -c 'ls -al /data/data/com.swanwish.logviewer/' || echo ERR-ERR-ERR-ERR"
total 52
drwx------ 5 u0_a499 u0_a499 3488 2022-06-15 22:28 .
drwxrwx--x 473 system system 53248 2022-06-17 15:00 ..
drwxrws--x 2 u0_a499 u0_a499_cache 3488 2022-06-15 22:28 cache
drwxrws--x 5 u0_a499 u0_a499_cache 3488 2022-06-15 23:13 code_cache
drwxrwx--x 2 u0_a499 u0_a499 3488 2022-06-15 22:28 files
Upload file
Because we can’t upload file directly to the data dir of a package, but the Device File Explorer
can upload file, it’s so amazing, and I find the answer from the log file, it’s a little different between emulator and physical device.
The following command is I upload a file named crash.gif
to my test app which has package name com.swanwish.logviewer
.
Emulator
For emulator, it will crate a temp file under /data/local/tmp
folder, and push file to that temp file, and copy file to the package’s data fir, and delete the temp file at last, the following is part of the commands that Device File Explorer
used.# Create a temp file
su 0 sh -c 'touch /data/local/tmp/temp37c98352-e6c3-4d5d-8ff9-302cc22060ff' || echo ERR-ERR-ERR-ERR# Push file to the temp file
Push file took 24.45 ms to execute: "/Users/Stephen/Downloads/crash.gif" -> "/data/local/tmp/temp37c98352-e6c3-4d5d-8ff9-302cc22060ff"# copy file from temp file to dest file
su 0 sh -c 'cp /data/local/tmp/temp37c98352-e6c3-4d5d-8ff9-302cc22060ff /data/data/com.swanwish.logviewer/crash.gif' || echo ERR-ERR-ERR-ERR# Delete the temp file
su 0 sh -c 'rm -f /data/local/tmp/temp37c98352-e6c3-4d5d-8ff9-302cc22060ff' || echo ERR-ERR-ERR-ERR
Physical Device
For physical device, it will use run-as
to finish the job, the following is some of the commands it used.# Create a temp file
touch /data/local/tmp/temp5e011b37-0ef8-4643-9272-2fb9d07774f6 || echo ERR-ERR-ERR-ERR# Upload file the temp file
Push file took 393.0 ms to execute: "/Users/Stephen/Downloads/crash.gif" -> "/data/local/tmp/temp5e011b37-0ef8-4643-9272-2fb9d07774f6"# Copy temp file to dest file
run-as com.swanwish.logviewer sh -c 'cp /data/local/tmp/temp5e011b37-0ef8-4643-9272-2fb9d07774f6 /data/data/com.swanwish.logviewer/crash.gif' || echo ERR-ERR-ERR-ERR# Delete the temp file
rm -f /data/local/tmp/temp5e011b37-0ef8-4643-9272-2fb9d07774f6 || echo ERR-ERR-ERR-ERR
Download file
Download file is similar with upload file, it just copy from package’s data dir to a temp file under /data/local/tmp
folder, then download file from /data/local/tmp
to local directory.
Delete file
Delete file also different between Emulator and Physical Devices, for Emulator, it will use the root user to delete the file, and for Physical Device, it will use the run-as
command to do the job.
Emulatorsu 0 sh -c 'rm -f /data/data/com.swanwish.logviewer/crash.gif' || echo ERR-ERR-ERR-ERR
Physical Devicerun-as com.swanwish.logviewer sh -c 'rm -f /data/data/com.swanwish.logviewer/crash.gif' || echo ERR-ERR-ERR-ERR
Conclusion
From Device File Explorer
, I learned that the /data/local/tmp
directory is a magic dir, we can use it to upload and download files from package’s data dir. I hope if you also want to do that like me.
Thanks for your reading!