| Steven Moreland | 5981dcb | 2019-07-16 18:06:55 -0700 | [diff] [blame] | 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 <android/os/IServiceManager.h> | 
|  | 18 | #include <binder/Binder.h> | 
|  | 19 | #include <binder/IBinder.h> | 
|  | 20 | #include <binder/IPCThreadState.h> | 
|  | 21 | #include <binder/IServiceManager.h> | 
|  | 22 | #include <binder/Parcel.h> | 
|  | 23 | #include <binder/Stability.h> | 
|  | 24 | #include <gtest/gtest.h> | 
|  | 25 |  | 
|  | 26 | #include <sys/prctl.h> | 
|  | 27 |  | 
|  | 28 | #include "BnBinderStabilityTest.h" | 
|  | 29 | #include "BpBinderStabilityTest.h" | 
|  | 30 |  | 
|  | 31 | using namespace android; | 
|  | 32 | using android::binder::Status; | 
|  | 33 | using android::os::IServiceManager; | 
|  | 34 |  | 
|  | 35 | const String16 kNoStabilityServer = String16("binder_stability_test_service_low"); | 
|  | 36 | const String16 kCompilationUnitServer = String16("binder_stability_test_service_compl"); | 
|  | 37 | const String16 kVintfServer = String16("binder_stability_test_service_vintf"); | 
|  | 38 |  | 
|  | 39 | sp<IBinder> getCompilationUnitStability() { | 
|  | 40 | sp<IBinder> binder = new BBinder(); | 
|  | 41 | // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS? | 
|  | 42 | // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS | 
|  | 43 | internal::Stability::markCompilationUnit(binder.get()); // <- BAD, NO! DO NOT COPY | 
|  | 44 | return binder; | 
|  | 45 | } | 
|  | 46 |  | 
|  | 47 | sp<IBinder> getVintfStability() { | 
|  | 48 | sp<IBinder> binder = new BBinder(); | 
|  | 49 | // NO! NO! NO! NO! DO NOT EVERY DO SOMETHING LIKE THIS? | 
|  | 50 | // WHAT ARE YOU CRAZY? IT'S VERY DANGEROUS | 
|  | 51 | internal::Stability::markVintf(binder.get()); // <- BAD, NO! DO NOT COPY | 
|  | 52 | return binder; | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | // NO! NO! NO! Do not even think of doing something like this! | 
|  | 56 | // This is for testing! If a class like this was actually used in production, | 
|  | 57 | // it would ruin everything! | 
|  | 58 | class BadStabilityTester : public BnBinderStabilityTest { | 
|  | 59 | public: | 
|  | 60 | Status sendBinder(const sp<IBinder>& /*binder*/) override { | 
|  | 61 | return Status::ok(); | 
|  | 62 | } | 
|  | 63 | Status returnNoStabilityBinder(sp<IBinder>* _aidl_return) override { | 
|  | 64 | *_aidl_return = new BBinder(); | 
|  | 65 | return Status::ok(); | 
|  | 66 | } | 
|  | 67 | Status returnLocalStabilityBinder(sp<IBinder>* _aidl_return) override { | 
|  | 68 | *_aidl_return = getCompilationUnitStability(); | 
|  | 69 | return Status::ok(); | 
|  | 70 | } | 
|  | 71 | Status returnVintfStabilityBinder(sp<IBinder>* _aidl_return) override { | 
|  | 72 | *_aidl_return = getVintfStability(); | 
|  | 73 | return Status::ok(); | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 | static sp<IBinderStabilityTest> getNoStabilityServer() { | 
|  | 77 | sp<IBinder> remote = new BadStabilityTester; | 
|  | 78 | return new BpBinderStabilityTest(remote); | 
|  | 79 | } | 
|  | 80 | static sp<IBinderStabilityTest> getCompilationUnitStabilityServer() { | 
|  | 81 | sp<IBinder> remote = new BadStabilityTester; | 
|  | 82 | internal::Stability::markCompilationUnit(remote.get()); | 
|  | 83 | return new BpBinderStabilityTest(remote); | 
|  | 84 | } | 
|  | 85 | static sp<IBinderStabilityTest> getVintfStabilityServer() { | 
|  | 86 | sp<IBinder> remote = new BadStabilityTester; | 
|  | 87 | internal::Stability::markVintf(remote.get()); // <- BAD, NO! DO NOT COPY | 
|  | 88 | return new BpBinderStabilityTest(remote); | 
|  | 89 | } | 
|  | 90 | }; | 
|  | 91 |  | 
|  | 92 | void checkNoStabilityServer(const sp<IBinderStabilityTest>& unkemptServer) { | 
|  | 93 | EXPECT_TRUE(unkemptServer->sendBinder(new BBinder()).isOk()); | 
|  | 94 | EXPECT_TRUE(unkemptServer->sendBinder(getCompilationUnitStability()).isOk()); | 
|  | 95 | EXPECT_TRUE(unkemptServer->sendBinder(getVintfStability()).isOk()); | 
|  | 96 |  | 
|  | 97 | sp<IBinder> out; | 
|  | 98 | EXPECT_TRUE(unkemptServer->returnNoStabilityBinder(&out).isOk()); | 
|  | 99 | EXPECT_NE(nullptr, out.get()); | 
|  | 100 |  | 
|  | 101 | EXPECT_TRUE(unkemptServer->returnLocalStabilityBinder(&out).isOk()); | 
|  | 102 | EXPECT_NE(nullptr, out.get()); | 
|  | 103 |  | 
|  | 104 | EXPECT_TRUE(unkemptServer->returnVintfStabilityBinder(&out).isOk()); | 
|  | 105 | EXPECT_NE(nullptr, out.get()); | 
|  | 106 | } | 
|  | 107 |  | 
|  | 108 | void checkLowStabilityServer(const sp<IBinderStabilityTest>& complServer) { | 
|  | 109 | EXPECT_FALSE(complServer->sendBinder(new BBinder()).isOk()); | 
|  | 110 | EXPECT_TRUE(complServer->sendBinder(getCompilationUnitStability()).isOk()); | 
|  | 111 | EXPECT_TRUE(complServer->sendBinder(getVintfStability()).isOk()); | 
|  | 112 |  | 
|  | 113 | sp<IBinder> out; | 
|  | 114 | EXPECT_FALSE(complServer->returnNoStabilityBinder(&out).isOk()); | 
|  | 115 | EXPECT_EQ(nullptr, out.get()); | 
|  | 116 |  | 
|  | 117 | EXPECT_TRUE(complServer->returnLocalStabilityBinder(&out).isOk()); | 
|  | 118 | EXPECT_NE(nullptr, out.get()); | 
|  | 119 |  | 
|  | 120 | EXPECT_TRUE(complServer->returnVintfStabilityBinder(&out).isOk()); | 
|  | 121 | EXPECT_NE(nullptr, out.get()); | 
|  | 122 | } | 
|  | 123 |  | 
|  | 124 | void checkHighStabilityServer(const sp<IBinderStabilityTest>& highStability) { | 
|  | 125 | EXPECT_FALSE(highStability->sendBinder(new BBinder()).isOk()); | 
|  | 126 | EXPECT_FALSE(highStability->sendBinder(getCompilationUnitStability()).isOk()); | 
|  | 127 | EXPECT_TRUE(highStability->sendBinder(getVintfStability()).isOk()); | 
|  | 128 |  | 
|  | 129 | sp<IBinder> out; | 
|  | 130 | EXPECT_FALSE(highStability->returnNoStabilityBinder(&out).isOk()); | 
|  | 131 | EXPECT_EQ(nullptr, out.get()); | 
|  | 132 |  | 
|  | 133 | EXPECT_FALSE(highStability->returnLocalStabilityBinder(&out).isOk()); | 
|  | 134 | EXPECT_EQ(nullptr, out.get()); | 
|  | 135 |  | 
|  | 136 | EXPECT_TRUE(highStability->returnVintfStabilityBinder(&out).isOk()); | 
|  | 137 | EXPECT_NE(nullptr, out.get()); | 
|  | 138 | } | 
|  | 139 |  | 
|  | 140 | TEST(BinderStability, LocalNoStabilityServer) { | 
|  | 141 | // in practice, a low stability server is probably one that hasn't been rebuilt | 
|  | 142 | // or was written by hand. | 
|  | 143 | auto server = BadStabilityTester::getNoStabilityServer(); | 
|  | 144 | ASSERT_NE(nullptr, IInterface::asBinder(server)->localBinder()); | 
|  | 145 | checkNoStabilityServer(server); | 
|  | 146 | } | 
|  | 147 |  | 
|  | 148 | TEST(BinderStability, LocalLowStabilityServer) { | 
|  | 149 | auto server = BadStabilityTester::getCompilationUnitStabilityServer(); | 
|  | 150 | ASSERT_NE(nullptr, IInterface::asBinder(server)->localBinder()); | 
|  | 151 | checkLowStabilityServer(server); | 
|  | 152 | } | 
|  | 153 |  | 
|  | 154 | TEST(BinderStability, LocalHighStabilityServer) { | 
|  | 155 | auto server = BadStabilityTester::getVintfStabilityServer(); | 
|  | 156 | ASSERT_NE(nullptr, IInterface::asBinder(server)->localBinder()); | 
|  | 157 | checkHighStabilityServer(server); | 
|  | 158 | } | 
|  | 159 |  | 
|  | 160 | TEST(BinderStability, RemoteNoStabilityServer) { | 
|  | 161 | sp<IBinder> remoteBinder = android::defaultServiceManager()->getService(kNoStabilityServer); | 
|  | 162 | auto remoteServer = interface_cast<IBinderStabilityTest>(remoteBinder); | 
|  | 163 |  | 
|  | 164 | ASSERT_NE(nullptr, remoteServer.get()); | 
|  | 165 | ASSERT_NE(nullptr, IInterface::asBinder(remoteServer)->remoteBinder()); | 
|  | 166 |  | 
|  | 167 | checkNoStabilityServer(remoteServer); | 
|  | 168 | } | 
|  | 169 |  | 
|  | 170 | TEST(BinderStability, RemoteLowStabilityServer) { | 
|  | 171 | sp<IBinder> remoteBinder = android::defaultServiceManager()->getService(kCompilationUnitServer); | 
|  | 172 | auto remoteServer = interface_cast<IBinderStabilityTest>(remoteBinder); | 
|  | 173 |  | 
|  | 174 | ASSERT_NE(nullptr, remoteServer.get()); | 
|  | 175 | ASSERT_NE(nullptr, IInterface::asBinder(remoteServer)->remoteBinder()); | 
|  | 176 |  | 
|  | 177 | checkLowStabilityServer(remoteServer); | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | TEST(BinderStability, RemoteVintfServer) { | 
|  | 181 | sp<IBinder> remoteBinder = android::defaultServiceManager()->getService(kVintfServer); | 
|  | 182 | auto remoteServer = interface_cast<IBinderStabilityTest>(remoteBinder); | 
|  | 183 |  | 
|  | 184 | ASSERT_NE(nullptr, remoteServer.get()); | 
|  | 185 | ASSERT_NE(nullptr, IInterface::asBinder(remoteServer)->remoteBinder()); | 
|  | 186 |  | 
|  | 187 | checkHighStabilityServer(remoteServer); | 
|  | 188 | } | 
|  | 189 |  | 
|  | 190 | class MarksStabilityInConstructor : public BBinder { | 
|  | 191 | public: | 
|  | 192 | static bool gDestructed; | 
|  | 193 |  | 
|  | 194 | MarksStabilityInConstructor() { | 
|  | 195 | internal::Stability::markCompilationUnit(this); | 
|  | 196 | } | 
|  | 197 | ~MarksStabilityInConstructor() { | 
|  | 198 | gDestructed = true; | 
|  | 199 | } | 
|  | 200 | }; | 
|  | 201 | bool MarksStabilityInConstructor::gDestructed = false; | 
|  | 202 |  | 
|  | 203 | TEST(BinderStability, MarkingObjectNoDestructTest) { | 
|  | 204 | ASSERT_FALSE(MarksStabilityInConstructor::gDestructed); | 
|  | 205 |  | 
|  | 206 | // best practice is to put this directly in an sp, but for this test, we | 
|  | 207 | // want to explicitly check what happens before that happens | 
|  | 208 | MarksStabilityInConstructor* binder = new MarksStabilityInConstructor(); | 
|  | 209 | ASSERT_FALSE(MarksStabilityInConstructor::gDestructed); | 
|  | 210 |  | 
|  | 211 | sp<MarksStabilityInConstructor> binderSp = binder; | 
|  | 212 | ASSERT_FALSE(MarksStabilityInConstructor::gDestructed); | 
|  | 213 |  | 
|  | 214 | binderSp = nullptr; | 
|  | 215 | ASSERT_TRUE(MarksStabilityInConstructor::gDestructed); | 
|  | 216 | } | 
|  | 217 |  | 
|  | 218 | int main(int argc, char** argv) { | 
|  | 219 | ::testing::InitGoogleTest(&argc, argv); | 
|  | 220 |  | 
|  | 221 | if (fork() == 0) { | 
|  | 222 | // child process | 
|  | 223 | prctl(PR_SET_PDEATHSIG, SIGHUP); | 
|  | 224 |  | 
|  | 225 | sp<IBinder> noStability = new BadStabilityTester; | 
|  | 226 | android::defaultServiceManager()->addService(kNoStabilityServer, noStability); | 
|  | 227 |  | 
|  | 228 | sp<IBinder> compil = new BadStabilityTester; | 
|  | 229 | internal::Stability::markCompilationUnit(compil.get()); | 
|  | 230 | android::defaultServiceManager()->addService(kCompilationUnitServer, compil); | 
|  | 231 |  | 
|  | 232 | sp<IBinder> vintf = new BadStabilityTester; | 
|  | 233 | internal::Stability::markVintf(vintf.get()); | 
|  | 234 | android::defaultServiceManager()->addService(kVintfServer, vintf); | 
|  | 235 |  | 
|  | 236 | IPCThreadState::self()->joinThreadPool(true); | 
|  | 237 | exit(1);  // should not reach | 
|  | 238 | } | 
|  | 239 |  | 
|  | 240 | // This is not racey. Just giving these services some time to register before we call | 
|  | 241 | // getService which sleeps for much longer... | 
|  | 242 | usleep(10000); | 
|  | 243 |  | 
|  | 244 | return RUN_ALL_TESTS(); | 
|  | 245 | } |