android adb读写权限单独控制

本文详细介绍了如何在Android设备端单独控制adb的读写权限,通过分析adb源码,特别是system/core/adb/daemon下的file_sync_service.cpp文件,找到处理adb push和pull命令的逻辑,并提出了通过添加prop判断条件来实现权限控制的方法。
摘要由CSDN通过智能技术生成

android 读写权限单独控制

前言

最近有一个需求,需要从手机端这边单独控制手机的读写权限,也就是adb 的pull 和push 权限,MTP 文件管理的copy delet 等操作。

禁止或允许adb 和MTP 的方法我知道。从插上usb 线弹出的那个选择框的源码入手,就可以看到。设置个参数就可以了。方法如下:

    private final static int ADB_DISABLE_ALL = 0;
    private final static int ADB_ENABLE_ADB = 1;
    private final static int ADB_ENABLE_MTP = 2;
 Settings.Global.putInt(getContext().getContentResolver(), "usb_per_settings", ADB_DISABLE_ALL);

但是分别控制,那肯定就得改这两个实现的源码了。首先来看下ADB

分析

要对adb 的push 和pull 命令来客制化。那肯定是要找他们实现的地方了。因为这块代码我也没接触过。但是我手里有系统源码。

就和解决大多数问题一样,通过log 来搜索具体代码实现。我敲adb 命令时,命令端会回复,那么我就尝试搜回复的字段来确定adb 的源码。如下,当我在"PC"端输入adb 时,会刷出如下的help 信息,以及我通过adb push,pull 时,也会一些提示信息。

PS C:\Users\xxx> adb
Android Debug Bridge version 1.0.41
Version 30.0.3-6597393
Installed as E:\android-sdk_r24.4.1-windows\android-sdk-windows\platform-tools\adb.exe

global options:
 -a         listen on all network interfaces, not just localhost
 -d         use USB device (error if multiple devices connected)
 -e         use TCP/IP device (error if multiple TCP/IP devices available)
 -s SERIAL  use device with given serial (overrides $ANDROID_SERIAL)
 -t ID      use device with given transport id
 -H         name of adb server host [default=localhost]
 -P         port of adb server [default=5037]
 -L SOCKET  listen on given socket for adb server [default=tcp:localhost:5037]

general commands:
 devices [-l]             list connected devices (-l for long output)
 help                     show this help message
 version                  show version num

networking:
 connect HOST[:PORT]      connect to a device via TCP/IP [default port=5555]
 disconnect [HOST[:PORT]]
     disconnect from given TCP/IP device [default port=5555], or all
 pair HOST[:PORT] [PAIRING CODE]
     pair with a device for secure TCP/IP communication
 forward --list           list all forward socket connections
 forward [--no-rebind] LOCAL REMOTE
     forward socket connection using:
       tcp:<port> (<local> may be "tcp:0" to pick any open port)
       localabstract:<unix domain socket name>
       localreserved:<unix domain socket name>
       localfilesystem:<unix domain socket name>
       dev:<character device name>
       jdwp:<process pid> (remote only)
       acceptfd:<fd> (listen only)
 forward --remove LOCAL   remove specific forward socket connection
 forward --remove-all     remove all forward socket connections
 ppp TTY [PARAMETER...]   run PPP over USB
 reverse --list           list all reverse socket connections from device
 reverse [--no-rebind] REMOTE LOCAL
     reverse socket connection using:
       tcp:<port> (<remote> may be "tcp:0" to pick any open port)
       localabstract:<unix domain socket name>
       localreserved:<unix domain socket name>
       localfilesystem:<unix domain socket name>
 reverse --remove REMOTE  remove specific reverse socket connection
 reverse --remove-all     remove all reverse socket connections from device
 mdns check               check if mdns discovery is available
 mdns services            list all discovered services

file transfer:
 push [--sync] [-z ALGORITHM] [-Z] LOCAL... REMOTE
     copy local files/directories to device
     --sync: only push files that are newer on the host than the device
     -n: dry run: push files to device without storing to the filesystem
     -z: enable compression with a specified algorithm (any, none, brotli)
     -Z: disable compression
 pull [-a] [-z ALGORITHM] [-Z] REMOTE... LOCAL
     copy files/dirs from device
     -a: preserve file timestamp and mode
     -z: enable compression with a specified algorithm (any, none, brotli)
     -Z: disable compression
 sync [-l] [-z ALGORITHM] [-Z] [all|data|odm|oem|product|system|system_ext|vendor]
     sync a local build from $ANDROID_PRODUCT_OUT to the device (default all)
     -n: dry run: push files to device without storing to the filesystem
     -l: list files that would be copied, but don't copy them
     -z: enable compression with a specified algorithm (any, none, brotli)
     -Z: disable compression

shell:
 shell [-e ESCAPE] [-n] [-Tt] [-x] [COMMAND...]
     run remote shell command (interactive shell if no command given)
     -e: choose escape character, or "none"; default '~'
     -n: don't read from stdin
     -T: disable pty allocation
     -t: allocate a pty if on a tty (-tt: force pty allocation)
     -x: disable remote exit codes and stdout/stderr separation
 emu COMMAND              run emulator console command

app installation (see also `adb shell cmd package help`):
 install [-lrtsdg] [--instant] PACKAGE
     push a single package to the device and install it
 install-multiple [-lrtsdpg] [--instant] PACKAGE...
     push multiple APKs to the device for a single package and install them
 install-multi-package [-lrtsdpg] [--instant] PACKAGE...
     push one or more packages to the device and install them atomically
     -r: replace existing application
     -t: allow test packages
     -d: allow version code downgrade (debuggable packages only)
     -p: partial application install (install-multiple only)
     -g: grant all runtime permissions
     --abi ABI: override platform's default ABI
     --instant: cause the app to be installed as an ephemeral install app
     --no-streaming: always push APK to device and invoke Package Manager as separate steps
     --streaming: force streaming APK directly into Package Manager
     --fastdeploy: use fast deploy
     --no-fastdeploy: prevent use of fast deploy
     --force-agent: force update of deployment agent when using fast deploy
     --date-check-agent: update deployment agent when local version is newer and using fast deploy
     --version-check-agent: update deployment agent when local version has different version code and using fast deploy
     (See also `adb shell pm help` for more options.)
 uninstall [-k] PACKAGE
     remove this app package from the device
     '-k': keep the data and cache directories

debugging:
 bugreport [PATH]
     write bugreport to given PATH [default=bugreport.zip];
     if PATH is a directory, the bug report is saved in that directory.
     devices that don't support zipped bug reports output to stdout.
 jdwp                     list pids of processes hosting a JDWP transport
 logcat                   show device log (logcat --help for more)

security:
 disable-verity           disable dm-verity checking on userdebug builds
 enable-verity            re-enable dm-verity checking on userdebug builds
 keygen FILE
     generate adb public/private key; private key stored in FILE,

scripting:
 wait-for[-TRANSPORT]-STATE...
     wait for device to be in a given state
     STATE: device, recovery, rescue, sideload, bootloader, or disconnect
     TRANSPORT: usb, local, or any [default=any]
 get-state                print offline | bootloader | device
 get-serialno             print <serial-number>
 get-devpath              print <device-path>
 remount [-R]
      remount partitions read-write. if a reboot is required, -R will
      will automatically reboot the device.
 reboot [bootloader|recovery|sideload|sideload-auto-reboot]
     reboot the device; defaults to booting system image but
     supports bootloader and recovery too. sideload reboots
     into recovery and automatically starts sideload mode,
     sideload-auto-reboot is the same but reboots after sideloading.
 sideload OTAPACKAGE      sideload the given full OTA package
 root                     restart adbd with root permissions
 unroot                   restart adbd without root permissions
 usb                      restart adbd listening on USB
 tcpip PORT               restart adbd listening on TCP on PORT

internal debugging:
 start-server             ensure that there is a server running
 kill-server              kill the server if it is running
 reconnect                kick connection from host side to force reconnect
 reconnect device         kick connection from device side to force reconnect
 reconnect offline        reset offline/unauthorized devices to force reconnect

environment variables:
 $ADB_TRACE
     comma-separated list of debug info to log:
     all,adb,sockets,packets,rwx,usb,sync,sysdeps,transport,jdwp
 $ADB_VENDOR_KEYS         colon-separated list of keys (files or directories)
 $ANDROID_SERIAL          serial number to connect to (see -s)
 $ANDROID_LOG_TAGS        tags to be used by logcat (see logcat --help)
 $ADB_LOCAL_TRANSPORT_MAX_PORT max emulator scan port (default 5585, 16 emus)
 $ADB_MDNS_AUTO_CONNECT   comma-separated list of mdns services to allow auto-connect (default adb-tls-connect)
PS C:\Users\xxx> adb pull
adb.exe: pull requires an argument
PS C:\Users\xxx> adb push
adb.exe: push requires an argument
PS C:\Users\xxx>

这样我搜了之后。然后按照我的思路(通过在上层设置不同的prop 来控制adb 是否push 或者pull)。如下:
在这里插入图片描述

按照正常的逻辑,我加入的打印,应该可以正常的打印出来。可是就是不生效。最后。我才发现,我犯了一个致命的错误。我找到的这个文件,是PC 端的。因为我的需求是要在手机端去控制。我修改了PC 端adb 逻辑,肯定体现不到手机端上去啊。最后我在网上搜了下。

adb 的实现都是在 system/core/adb下。
adb PC 端的实现是在 system/core/adb/client
adb 手机端的实现是在 system/core/adb/daemon

实现

于是在 daemon 下查找手机端的pull 和push 的命令。

/system/core/adb/file_sync_service.cpp

static bool handle_sync_command(int fd, std::vector<char>& buffer) {   // 此方法是处理adb 命令的。
470    D("sync: waiting for request");
471
472    ATRACE_CALL();
473    SyncRequest request;
474    if (!ReadFdExactly(fd, &request, sizeof(request))) {
475        SendSyncFail(fd, "command read failure");
476        return false;
477    }
478    size_t path_length = request.path_length;
479    if (path_length > 1024) {
480        SendSyncFail(fd, "path too long");
481        return false;
482    }
483    char name[1025];
484    if (!ReadFdExactly(fd, name, path_length)) {
485        SendSyncFail(fd, "filename read failure");
486        return false;
487    }
488    name[path_length] = 0;
489
490    std::string id_name = sync_id_to_name(request.id);
491    std::string trace_name = StringPrintf("%s(%s)", id_name.c_str(), name);
492    ATRACE_NAME(trace_name.c_str());
493
494    D("sync: %s('%s')", id_name.c_str(), name);
495    switch (request.id) {
496        case ID_LSTAT_V1:
497            if (!do_lstat_v1(fd, name)) return false;
498            break;
499        case ID_LSTAT_V2:
500        case ID_STAT_V2:
501            if (!do_stat_v2(fd, request.id, name)) return false;
502            break;
503        case ID_LIST:
504            if (!do_list(fd, name)) return false;
505            break;
506        case ID_SEND:
507            if (!do_send(fd, name, buffer)) return false;
508            break;
509        case ID_RECV:
510            if (!do_recv(fd, name, buffer)) return false;
511            break;
512        case ID_QUIT:
513            return false;
514        default:
515            SendSyncFail(fd, StringPrintf("unknown command %08x", request.id));
516            return false;
517    }
518
519    return true;
520}

接下来,在上面case 里面加log 打印:
在这里插入图片描述

最后打印如下:
在这里插入图片描述

此时,则可以知道。adb 的push 和pull 的具体实现逻辑。这时候只要加上prop 的判断条件即可。

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

假装多好123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值