1 /* 2 * Copyright (C) 2016 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 <signal.h> 18 #include <sys/types.h> 19 #include <unistd.h> 20 21 #include <binder/Binder.h> 22 #include <binder/IBinder.h> 23 #include <binder/IServiceManager.h> 24 #include <binder/Parcel.h> 25 #include <binder/ProcessState.h> 26 27 #include <gtest/gtest.h> 28 29 #include "Allocator.h" 30 #include "Binder.h" 31 32 namespace android { 33 34 static const String16 service_name("test.libmemunreachable_binder"); 35 36 class BinderService : public BBinder { 37 public: 38 BinderService() = default; 39 virtual ~BinderService() = default; 40 41 virtual status_t onTransact(uint32_t /*code*/, const Parcel& data, Parcel* reply, 42 uint32_t /*flags*/ = 0) { 43 reply->writeStrongBinder(ref); 44 ref = data.readStrongBinder(); 45 return 0; 46 } 47 48 private: 49 sp<IBinder> ref; 50 }; 51 52 class BinderObject : public BBinder { 53 public: 54 BinderObject() = default; 55 ~BinderObject() = default; 56 }; 57 58 class ServiceProcess { 59 public: 60 ServiceProcess() : child_(0) {} 61 ~ServiceProcess() { Stop(); } 62 63 bool Run() { 64 pid_t ret = fork(); 65 if (ret < 0) { 66 return false; 67 } else if (ret == 0) { 68 // child 69 _exit(Service()); 70 } else { 71 // parent 72 child_ = ret; 73 return true; 74 } 75 } 76 77 bool Stop() { 78 if (child_ > 0) { 79 if (kill(child_, SIGTERM)) { 80 return false; 81 } 82 int status = 0; 83 if (TEMP_FAILURE_RETRY(waitpid(child_, &status, 0)) != child_) { 84 return false; 85 } 86 child_ = 0; 87 return WIFEXITED(status) && WEXITSTATUS(status) == 0; 88 } 89 90 return true; 91 } 92 93 int Service() { 94 sp<ProcessState> proc{ProcessState::self()}; 95 sp<IServiceManager> sm = defaultServiceManager(); 96 if (sm == nullptr) { 97 fprintf(stderr, "Failed to get service manager\n"); 98 return 1; 99 } 100 if (sm->addService(service_name, new BinderService()) != OK) { 101 fprintf(stderr, "Failed to add test service\n"); 102 return 1; 103 } 104 proc->startThreadPool(); 105 pause(); 106 return 0; 107 } 108 109 private: 110 pid_t child_; 111 }; 112 113 class BinderTest : public ::testing::Test { 114 protected: 115 ServiceProcess service_process_; 116 }; 117 118 TEST_F(BinderTest, binder) { 119 ServiceProcess service_process; 120 ASSERT_TRUE(service_process.Run()); 121 122 sp<IServiceManager> sm = defaultServiceManager(); 123 ASSERT_TRUE(sm != nullptr); 124 125 // A small sleep allows the service to start, which 126 // prevents a longer sleep in getService. 127 usleep(100000); 128 129 sp<IBinder> service = sm->getService(service_name); 130 ASSERT_TRUE(service != nullptr); 131 132 sp<IBinder> binder{new BinderObject()}; 133 134 Parcel send; 135 Parcel reply; 136 137 send.writeStrongBinder(binder); 138 status_t rv = service->transact(0, send, &reply); 139 ASSERT_EQ(static_cast<status_t>(OK), rv); 140 141 Heap heap; 142 allocator::vector<uintptr_t> refs{heap}; 143 144 ASSERT_TRUE(BinderReferences(refs)); 145 146 bool found_ref = false; 147 for (auto ref : refs) { 148 if (ref == reinterpret_cast<uintptr_t>(binder.get())) { 149 found_ref = true; 150 } 151 } 152 153 ASSERT_TRUE(found_ref); 154 } 155 156 } // namespace android 157