1 /*
2  * Copyright 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 #define DEBUG false
18 #include "Log.h"
19 
20 #include <binder/IServiceManager.h>
21 #include <com/android/internal/car/ICarStatsService.h>
22 
23 #include "CarStatsPuller.h"
24 #include "logd/LogEvent.h"
25 #include "stats_log_util.h"
26 
27 using android::binder::Status;
28 using com::android::internal::car::ICarStatsService;
29 
30 namespace android {
31 namespace os {
32 namespace statsd {
33 
34 static std::mutex gCarStatsMutex;
35 static sp<ICarStatsService> gCarStats = nullptr;
36 
37 class CarStatsDeathRecipient : public android::IBinder::DeathRecipient {
38  public:
39      CarStatsDeathRecipient() = default;
40      ~CarStatsDeathRecipient() override = default;
41 
42   // android::IBinder::DeathRecipient override:
binderDied(const android::wp<android::IBinder> &)43   void binderDied(const android::wp<android::IBinder>& /* who */) override {
44       ALOGE("Car service has died");
45       std::lock_guard<std::mutex> lock(gCarStatsMutex);
46       if (gCarStats) {
47           sp<IBinder> binder = IInterface::asBinder(gCarStats);
48           binder->unlinkToDeath(this);
49           gCarStats = nullptr;
50       }
51   }
52 };
53 
54 static sp<CarStatsDeathRecipient> gDeathRecipient = new CarStatsDeathRecipient();
55 
getCarService()56 static sp<ICarStatsService> getCarService() {
57     std::lock_guard<std::mutex> lock(gCarStatsMutex);
58     if (!gCarStats) {
59         const sp<IBinder> binder = defaultServiceManager()->checkService(String16("car_stats"));
60         if (!binder) {
61             ALOGW("Car service is unavailable");
62             return nullptr;
63         }
64         gCarStats = interface_cast<ICarStatsService>(binder);
65         binder->linkToDeath(gDeathRecipient);
66     }
67     return gCarStats;
68 }
69 
CarStatsPuller(const int tagId)70 CarStatsPuller::CarStatsPuller(const int tagId) : StatsPuller(tagId) {
71 }
72 
PullInternal(std::vector<std::shared_ptr<LogEvent>> * data)73 bool CarStatsPuller::PullInternal(std::vector<std::shared_ptr<LogEvent>>* data) {
74     const sp<ICarStatsService> carService = getCarService();
75     if (!carService) {
76         return false;
77     }
78 
79     vector<StatsLogEventWrapper> returned_value;
80     Status status = carService->pullData(mTagId, &returned_value);
81     if (!status.isOk()) {
82         ALOGW("CarStatsPuller::pull failed for %d", mTagId);
83         return false;
84     }
85 
86     data->clear();
87     for (const StatsLogEventWrapper& it : returned_value) {
88         LogEvent::createLogEvents(it, *data);
89     }
90     VLOG("CarStatsPuller::pull succeeded for %d", mTagId);
91     return true;
92 }
93 
94 }  // namespace statsd
95 }  // namespace os
96 }  // namespace android
97