最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

安卓車機(jī)系統(tǒng)adb shell cmd 源碼原理分析

2023-01-19 11:27 作者:千里馬學(xué)框架  | 我要投稿

hi,粉絲朋友們大家好!

? ? ? 上一次視頻分享了input專題課中input命令在android 12的更新,因?yàn)樵瓉碚n程是基于android 10? (可以加我扣:2102309716 優(yōu)惠購買)

? ? ? [https://ke.qq.com/course/package/77595?tuin=7d4eb354](https://ke.qq.com/course/package/77595?tuin=7d4eb354)

? ? ? [https://www.bilibili.com/video/BV1aK41117mw/](https://www.bilibili.com/video/BV1aK41117mw/)

? ? ? 具體input命令的更新大家看以上視頻既可以,順便補(bǔ)充一下視頻中流程圖:

? ? ??


本文主要來補(bǔ)充一下視頻中沒有詳細(xì)講解的cmd命令

一般cmd命令使用格式一般是:

adb shell cmd xxxx

這里xxx其實(shí)一般是我們的系統(tǒng)服務(wù)名字,其[跨進(jìn)程課](https://ke.qq.com/course/package/77595?tuin=7d4eb354)中servicemanager列表中保存的所有服務(wù)名字


然后他就會(huì)觸發(fā)對(duì)應(yīng)服務(wù)的onShellCommand方法,這個(gè)時(shí)候相當(dāng)于和dumpsys命令非常類似,dumpsys命令是會(huì)觸發(fā)到對(duì)應(yīng)的服務(wù)的dump方法

[https://blog.csdn.net/learnframework/article/details/122596598](https://blog.csdn.net/learnframework/article/details/122596598)

那么下面來源碼級(jí)別分析一下cmd命令,因?yàn)樯厦娑际谴蟾诺闹v解,沒有拿出源碼來證明。


代碼路徑:

frameworks/native/cmds/cmd/main.cpp


```cpp

#include <unistd.h>


#include "cmd.h"


int main(int argc, char* const argv[]) {

? ? signal(SIGPIPE, SIG_IGN);


? ? std::vector<std::string_view> arguments;

? ? arguments.reserve(argc - 1);

? ? // 0th argument is a program name, skipping.

? ? for (int i = 1; i < argc; ++i) {

? ? ? ? arguments.emplace_back(argv[i]);

? ? }


? ? return cmdMain(arguments, android::aout, android::aerr, STDIN_FILENO, STDOUT_FILENO,

? ? ? ? ? ? ? ? ? ?STDERR_FILENO, RunMode::kStandalone);

}


```

這里可以看出主要執(zhí)行的是cmdMain方法


```cpp

int cmdMain(const std::vector<std::string_view>& argv, TextOutput& outputLog, TextOutput& errorLog,

? ? ? ? ? ? int in, int out, int err, RunMode runMode) {

? ? sp<ProcessState> proc = ProcessState::self();

? ? proc->startThreadPool();


#if DEBUG

? ? ALOGD("cmd: starting");

#endif

? ? sp<IServiceManager> sm = defaultServiceManager();

? ? //ignoe

? ? if ((argc == 1) && (argv[0] == "-l")) {

? ? ? ? Vector<String16> services = sm->listServices();

? ? ? ? services.sort(sort_func);

? ? ? ? outputLog << "Currently running services:" << endl;


? ? ? ? for (size_t i=0; i<services.size(); i++) {

? ? ? ? ? ? sp<IBinder> service = sm->checkService(services[i]);

? ? ? ? ? ? if (service != nullptr) {

? ? ? ? ? ? ? ? outputLog << "? " << services[i] << endl;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return 0;

? ? }


? ? bool waitForService = ((argc > 1) && (argv[0] == "-w"));

? ? int serviceIdx = (waitForService) ? 1 : 0;

? ? const auto cmd = argv[serviceIdx];


? ? Vector<String16> args;

? ? String16 serviceName = String16(cmd.data(), cmd.size());

? ? for (int i = serviceIdx + 1; i < argc; i++) {

? ? ? ? args.add(String16(argv[i].data(), argv[i].size()));

? ? }

? ? sp<IBinder> service;

? ? if(waitForService) {

? ? ? ? service = sm->waitForService(serviceName);

? ? } else {

? ? ? ? service = sm->checkService(serviceName);

? ? }


? ? //ignoe

? ? sp<MyShellCallback> cb = new MyShellCallback(errorLog);

? ? sp<MyResultReceiver> result = new MyResultReceiver();

? ? // TODO: block until a result is returned to MyResultReceiver.

? ? status_t error = IBinder::shellCommand(service, in, out, err, args, cb, result);

? ? ?//ignoe

? ? cb->mActive = false;

? ? status_t res = result->waitForResult();

#if DEBUG

? ? ALOGD("result=%d", (int)res);

#endif

? ? return res;

}


```

cmdMain的代碼其實(shí)也簡單,主要做了以下幾步工作:

1、解析出cmd命令后面的服務(wù)字符,根據(jù)這個(gè)服務(wù)字符去servicemanager尋找對(duì)應(yīng)service,返回對(duì)應(yīng)的BpBinder

2、獲取了BpBinder后調(diào)用IBinder::shellCommand方法,這個(gè)方法是最為關(guān)鍵,它會(huì)調(diào)用到服務(wù)端的onShellCommand方法

3、等帶服務(wù)返回結(jié)果


這里繼續(xù)看看IBinder::shellCommand怎么調(diào)用的到服務(wù)端的:


```cpp

status_t IBinder::shellCommand(const sp<IBinder>& target, int in, int out, int err,

? ? Vector<String16>& args, const sp<IShellCallback>& callback,

? ? const sp<IResultReceiver>& resultReceiver)

{

? ? Parcel send;

? ? Parcel reply;

? ? send.writeFileDescriptor(in);

? ? send.writeFileDescriptor(out);

? ? send.writeFileDescriptor(err);

? ? const size_t numArgs = args.size();

? ? send.writeInt32(numArgs);

? ? for (size_t i = 0; i < numArgs; i++) {

? ? ? ? send.writeString16(args[i]);

? ? }

? ? send.writeStrongBinder(callback != nullptr ? IInterface::asBinder(callback) : nullptr);

? ? send.writeStrongBinder(resultReceiver != nullptr ? IInterface::asBinder(resultReceiver) : nullptr);

? ? return target->transact(SHELL_COMMAND_TRANSACTION, send, &reply);

}

```

這里大家如果學(xué)習(xí)過跨進(jìn)程專題應(yīng)該非常熟悉這個(gè),可以看到最后其實(shí)是構(gòu)造了一個(gè)Parcel調(diào)用了transact方法進(jìn)行傳遞,當(dāng)transact調(diào)用完成后就會(huì)到服務(wù)端的transact再調(diào)用到onShellCommand


安卓車機(jī)系統(tǒng)adb shell cmd 源碼原理分析的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
星子县| 盐城市| 南昌县| 萝北县| 江源县| 株洲县| 临澧县| 松阳县| 旺苍县| 黎川县| 沽源县| 澜沧| 合江县| 兖州市| 朝阳市| 建瓯市| 新河县| 格尔木市| 河池市| 昆山市| 工布江达县| 宜都市| 孙吴县| 同仁县| 肇东市| 宜兴市| 筠连县| 井陉县| 丹棱县| 临沂市| 资阳市| 安溪县| 鹤庆县| 漠河县| 兴文县| 剑阁县| 阳西县| 阿拉尔市| 绩溪县| 柞水县| 安溪县|