• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 <binder/Binder.h>
18 #include <binder/IServiceManager.h>
19 #include <binder/ProcessState.h>
20 #include <binder/IPCThreadState.h>
21 #include <binderdebug/BinderDebug.h>
22 #include <gtest/gtest.h>
23 #include <semaphore.h>
24 #include <thread>
25 
26 #include <android/binderdebug/test/BnControl.h>
27 #include <android/binderdebug/test/IControl.h>
28 
29 namespace android {
30 namespace binderdebug {
31 namespace test {
32 
33 class Control : public BnControl {
34 public:
Control()35     Control() {sem_init(&s, 1, 0);};
36     ::android::binder::Status Continue() override;
37     sem_t s;
38 };
39 
Continue()40 ::android::binder::Status Control::Continue() {
41     IPCThreadState::self()->flushCommands();
42     sem_post(&s);
43     return binder::Status::ok();
44 }
45 
TEST(BinderDebugTests,BinderPid)46 TEST(BinderDebugTests, BinderPid) {
47     BinderPidInfo pidInfo;
48     const auto& status = getBinderPidInfo(BinderDebugContext::BINDER, getpid(), &pidInfo);
49     ASSERT_EQ(status, OK);
50     // There should be one referenced PID for servicemanager
51     EXPECT_TRUE(!pidInfo.refPids.empty());
52 }
53 
TEST(BinderDebugTests,BinderThreads)54 TEST(BinderDebugTests, BinderThreads) {
55     BinderPidInfo pidInfo;
56     const auto& status = getBinderPidInfo(BinderDebugContext::BINDER, getpid(), &pidInfo);
57     ASSERT_EQ(status, OK);
58     EXPECT_TRUE(pidInfo.threadUsage <= pidInfo.threadCount);
59     // The second looper thread can sometimes take longer to spawn.
60     EXPECT_GE(pidInfo.threadCount, 1);
61 }
62 
63 extern "C" {
main(int argc,char ** argv)64 int main(int argc, char** argv) {
65     ::testing::InitGoogleTest(&argc, argv);
66 
67     // Create a child/client process to call into the main process so we can ensure
68     // looper thread has been registered before attempting to get the BinderPidInfo
69     pid_t pid = fork();
70     if (pid == 0) {
71         sp<IBinder> binder = android::defaultServiceManager()->getService(String16("binderdebug"));
72         sp<IControl> service;
73         if (binder != nullptr) {
74             service = android::interface_cast<IControl>(binder);
75         }
76         service->Continue();
77         exit(0);
78     }
79     sp<Control> iface = new Control;
80     android::defaultServiceManager()->addService(String16("binderdebug"), iface);
81     android::ProcessState::self()->setThreadPoolMaxThreadCount(8);
82     ProcessState::self()->startThreadPool();
83     sem_wait(&iface->s);
84 
85     return RUN_ALL_TESTS();
86 }
87 } // extern "C"
88 } // namespace  test
89 } // namespace  binderdebug
90 } // namespace  android
91