1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <chrono>
18 #include <iostream>
19 #include <mutex>
20 #include <thread>
21
22 #include "adbconnection/client.h"
23 #include "adbconnection/common.h"
24 #include "adbconnection/server.h"
25
26 #include <gtest/gtest.h>
27
28 // How this test works. Normally, the client lives in ART process and the server live in adbd.
29 // They communicate over UDS "@jdwp-control", each using a poll system (we don't have here).
30 //
31 // We spawn the client and the server in the same process. They still use the same UDS to
32 // communicate. The fdevent from adbd system is mocked with a single loop (server_callback). The
33 // conditional variable is used to pace the test (send then assert).
34
35 ProcessInfo info = {};
36
37 // The client synchronize with the server with mx and cv
38 std::mutex mx;
39 std::condition_variable cv;
onUpdateReceived()40 void onUpdateReceived() {
41 std::lock_guard<std::mutex> lock(mx);
42 cv.notify_one();
43 }
waitForUpdateReceived()44 void waitForUpdateReceived() {
45 std::unique_lock<std::mutex> lock(mx);
46 cv.wait(lock);
47 }
48
server_callback(int fd,ProcessInfo process)49 void server_callback(int fd, ProcessInfo process) {
50 info = process;
51 onUpdateReceived();
52 // After the first processinfo update is received, jdwp_service in adbd takes over reading
53 // from the fd leveraging fdevent system. We emulate it by reading on a regular basis.
54 while (true) {
55 auto optional = readProcessInfoFromSocket(fd);
56 if (optional) {
57 info = *optional;
58 onUpdateReceived();
59 }
60 std::this_thread::sleep_for(std::chrono::milliseconds(10));
61 }
62 }
63
64 // This test mimics an app starting up and sending data as zygote is specializing
TEST(LibAdbConnectionTest,TestComm)65 TEST(LibAdbConnectionTest, TestComm) {
66 // Start a fake server
67 std::thread([]() { adbconnection_listen(server_callback); }).detach();
68 // Let the server start
69 sleep(1);
70
71 const char* isa = "arch_foo";
72 const AdbConnectionClientInfo infos[] = {
73 {.type = AdbConnectionClientInfoType::pid, .data.pid = 666},
74 {.type = AdbConnectionClientInfoType::debuggable, .data.debuggable = true},
75 {.type = AdbConnectionClientInfoType::profileable, .data.profileable = true},
76 {.type = AdbConnectionClientInfoType::architecture,
77 .data.architecture.name = isa,
78 .data.architecture.size = strlen(isa)},
79 };
80
81 // Send the first batch of data (mimic the app starting up)
82 const AdbConnectionClientInfo* info_ptrs[] = {&infos[0], &infos[1], &infos[2], &infos[3]};
83 auto ctx = adbconnection_client_new(info_ptrs, std::size(infos));
84 EXPECT_TRUE(ctx != nullptr);
85 EXPECT_FALSE(adbconnection_client_has_pending_update());
86
87 waitForUpdateReceived();
88 EXPECT_EQ(info.pid, infos[0].data.pid);
89 EXPECT_TRUE(info.debuggable);
90 EXPECT_TRUE(info.profileable);
91 EXPECT_EQ(info.architecture, isa);
92 EXPECT_FALSE(adbconnection_client_has_pending_update());
93
94 adbconnection_client_set_current_process_name("my_process_name");
95 adbconnection_client_add_application("my_package_name");
96 adbconnection_client_add_application("my_package_name2");
97 adbconnection_client_remove_application("my_package_name2");
98 adbconnection_client_set_user_id(888);
99 adbconnection_client_set_waiting_for_debugger(true);
100
101 EXPECT_TRUE(adbconnection_client_has_pending_update());
102
103 // Send an update
104 adbconnection_client_send_update(ctx);
105 EXPECT_FALSE(adbconnection_client_has_pending_update());
106
107 waitForUpdateReceived();
108 EXPECT_EQ(info.package_names.size(), 1);
109 EXPECT_EQ(info.package_names.count("my_package_name"), 1);
110 EXPECT_EQ(info.process_name, "my_process_name");
111 EXPECT_EQ(info.user_id, 888);
112 EXPECT_TRUE(info.waiting_for_debugger);
113 }