五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(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)遵守國家法律
岳西县| 克拉玛依市| 台湾省| 故城县| 天门市| 台东县| 宿州市| 庆城县| 宜丰县| 洪泽县| 邹城市| 来安县| 平泉县| 晋中市| 灵台县| 稻城县| 兴安县| 大英县| 长岛县| 遂宁市| 洛川县| 浦北县| 峨眉山市| 禄丰县| 大埔县| 德昌县| 华蓥市| 哈尔滨市| 广德县| 紫阳县| 长乐市| 双柏县| 儋州市| 息烽县| 台州市| 霸州市| 台东市| 五寨县| 永川市| 赣州市| 肥乡县|