blob: 301328a6af479a1f33aa1bedfc6b86df7a009539 [file] [log] [blame]
Jiyong Parka7266ac2021-05-17 21:57:24 +09001/*
2 * Copyright (C) 2021 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 */
Inseob Kim06a64d62021-09-07 21:21:45 +090016#include <aidl/android/system/virtualmachineservice/IVirtualMachineService.h>
17#include <aidl/com/android/microdroid/testservice/BnTestService.h>
Inseob Kimdb319702022-01-20 13:12:43 +090018#include <android-base/file.h>
Inseob Kim691df6a2022-01-20 12:54:30 +090019#include <android-base/properties.h>
Andrew Scull11cf0902021-06-22 12:08:10 +000020#include <android-base/result.h>
Andrew Scull66616612021-06-17 16:41:03 +000021#include <android/binder_auto_utils.h>
22#include <android/binder_manager.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090023#include <fcntl.h>
Inseob Kimdb319702022-01-20 13:12:43 +090024#include <fsverity_digests.pb.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090025#include <linux/vm_sockets.h>
26#include <stdint.h>
Jiyong Parka7266ac2021-05-17 21:57:24 +090027#include <stdio.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090028#include <sys/ioctl.h>
Jiyong Park23934392021-06-16 01:59:10 +090029#include <sys/system_properties.h>
Inseob Kim06a64d62021-09-07 21:21:45 +090030#include <unistd.h>
31
32#include <binder_rpc_unstable.hpp>
Inseob Kim691df6a2022-01-20 12:54:30 +090033#include <string>
Jiyong Parka7266ac2021-05-17 21:57:24 +090034
Inseob Kim06a64d62021-09-07 21:21:45 +090035using aidl::android::system::virtualmachineservice::IVirtualMachineService;
36
37using android::base::ErrnoError;
Andrew Scull11cf0902021-06-22 12:08:10 +000038using android::base::Error;
39using android::base::Result;
Andrew Scull66616612021-06-17 16:41:03 +000040
Jiyong Parkfe5b28e2021-06-24 00:19:02 +090041extern void testlib_sub();
42
Andrew Scull66616612021-06-17 16:41:03 +000043namespace {
44
Andrew Scull11cf0902021-06-22 12:08:10 +000045template <typename T>
Andrew Sculledbe75e2021-07-06 10:44:31 +000046Result<T> report_test(std::string name, Result<T> result) {
Andrew Scull11cf0902021-06-22 12:08:10 +000047 auto property = "debug.microdroid.test." + name;
48 std::stringstream outcome;
49 if (result.ok()) {
50 outcome << "PASS";
51 } else {
52 outcome << "FAIL: " << result.error();
Inseob Kimdb319702022-01-20 13:12:43 +090053 // Pollute stderr with the error in case the property is truncated.
54 std::cerr << "[" << name << "] test failed: " << result.error() << "\n";
Andrew Scull11cf0902021-06-22 12:08:10 +000055 }
56 __system_property_set(property.c_str(), outcome.str().c_str());
Andrew Sculledbe75e2021-07-06 10:44:31 +000057 return result;
Andrew Scull66616612021-06-17 16:41:03 +000058}
59
Inseob Kim06a64d62021-09-07 21:21:45 +090060Result<void> start_test_service() {
61 class TestService : public aidl::com::android::microdroid::testservice::BnTestService {
62 ndk::ScopedAStatus addInteger(int32_t a, int32_t b, int32_t* out) override {
63 *out = a + b;
64 return ndk::ScopedAStatus::ok();
65 }
Inseob Kim691df6a2022-01-20 12:54:30 +090066
67 ndk::ScopedAStatus readProperty(const std::string& prop, std::string* out) override {
68 *out = android::base::GetProperty(prop, "");
69 if (out->empty()) {
70 std::string msg = "cannot find property " + prop;
71 return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_SERVICE_SPECIFIC,
72 msg.c_str());
73 }
74
75 return ndk::ScopedAStatus::ok();
76 }
Inseob Kim06a64d62021-09-07 21:21:45 +090077 };
78 auto testService = ndk::SharedRefBase::make<TestService>();
79
80 auto callback = []([[maybe_unused]] void* param) {
81 // Tell microdroid_manager that we're ready.
82 // Failing to notify is not a fatal error; the payload can continue.
83 ndk::SpAIBinder binder(
84 RpcClient(VMADDR_CID_HOST, IVirtualMachineService::VM_BINDER_SERVICE_PORT));
85 auto virtualMachineService = IVirtualMachineService::fromBinder(binder);
86 if (virtualMachineService == nullptr) {
87 std::cerr << "failed to connect VirtualMachineService";
88 return;
89 }
Inseob Kimc7d28c72021-10-25 14:28:10 +000090 if (!virtualMachineService->notifyPayloadReady().isOk()) {
Inseob Kim06a64d62021-09-07 21:21:45 +090091 std::cerr << "failed to notify payload ready to virtualizationservice";
92 }
93 };
94
95 if (!RunRpcServerCallback(testService->asBinder().get(), testService->SERVICE_PORT, callback,
96 nullptr)) {
97 return Error() << "RPC Server failed to run";
98 }
99
100 return {};
101}
102
Inseob Kimdb319702022-01-20 13:12:43 +0900103Result<void> verify_apk() {
104 const char* path = "/mnt/extra-apk/0/assets/build_manifest.pb";
105
106 std::string str;
107 if (!android::base::ReadFileToString(path, &str)) {
108 return ErrnoError() << "failed to read build_manifest.pb";
109 }
110
111 if (!android::security::fsverity::FSVerityDigests().ParseFromString(str)) {
112 return Error() << "invalid build_manifest.pb";
113 }
114
115 return {};
116}
117
Andrew Scull66616612021-06-17 16:41:03 +0000118} // Anonymous namespace
119
Jiyong Park40699612021-05-24 16:55:06 +0900120extern "C" int android_native_main(int argc, char* argv[]) {
Inseob Kim06a64d62021-09-07 21:21:45 +0900121 // disable buffering to communicate seamlessly
122 setvbuf(stdin, nullptr, _IONBF, 0);
123 setvbuf(stdout, nullptr, _IONBF, 0);
124 setvbuf(stderr, nullptr, _IONBF, 0);
125
Jiyong Park40699612021-05-24 16:55:06 +0900126 printf("Hello Microdroid ");
127 for (int i = 0; i < argc; i++) {
128 printf("%s", argv[i]);
129 bool last = i == (argc - 1);
130 if (!last) {
131 printf(" ");
132 }
133 }
Jiyong Parkfe5b28e2021-06-24 00:19:02 +0900134 testlib_sub();
Jiyong Park40699612021-05-24 16:55:06 +0900135 printf("\n");
Jiyong Park23934392021-06-16 01:59:10 +0900136
Inseob Kimdb319702022-01-20 13:12:43 +0900137 // Extra apks may be missing; this is not a fatal error
138 report_test("extra_apk", verify_apk());
139
Jiyong Park23934392021-06-16 01:59:10 +0900140 __system_property_set("debug.microdroid.app.run", "true");
Andrew Sculledbe75e2021-07-06 10:44:31 +0000141
Inseob Kim06a64d62021-09-07 21:21:45 +0900142 if (auto res = start_test_service(); res.ok()) {
143 return 0;
144 } else {
145 std::cerr << "starting service failed: " << res.error();
146 return 1;
147 }
Jiyong Parka7266ac2021-05-17 21:57:24 +0900148}