1 /*
2  * Copyright 2022 NXP
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 #include <aidl/android/vendor/powerstats/BnPixelStateResidencyCallback.h>
17 #include <aidl/android/vendor/powerstats/IPixelStateResidencyProvider.h>
18 #include <android/binder_manager.h>
19 #include <android/binder_process.h>
20 #include <phNxpNciHal_PowerStats.h>
21 
22 #include "NfcProperties.sysprop.h"
23 
24 using namespace vendor::nfc::nxp;
25 using ::aidl::android::hardware::power::stats::StateResidency;
26 using ::aidl::android::vendor::powerstats::BnPixelStateResidencyCallback;
27 using ::aidl::android::vendor::powerstats::IPixelStateResidencyCallback;
28 using ::aidl::android::vendor::powerstats::IPixelStateResidencyProvider;
29 using ::ndk::ScopedAStatus;
30 using ::ndk::SpAIBinder;
31 using std::vector;
32 
33 /******************* Constants *****************************************/
34 const char* kPowerStatsSrvName = "power.stats-vendor";
35 const char* kPowerEntityName = "Nfc";
36 
37 /**
38  * Class implements power state residency callback.
39  *
40  * power.stats-vendor service will invoke getStateResidency callback
41  * periodically for fetching current value of cached power data for each Nfc
42  * state.
43  */
44 class NfcStateResidencyCallback : public BnPixelStateResidencyCallback {
45  public:
NfcStateResidencyCallback()46   NfcStateResidencyCallback() {
47     NXPLOG_NCIHAL_I("%s: descriptor = %s", __func__, descriptor);
48   }
49   /**
50    * Returns current state residency data for all Nfc states.
51    */
getStateResidency(vector<StateResidency> * stateResidency)52   virtual ScopedAStatus getStateResidency(
53       vector<StateResidency>* stateResidency) {
54     if (stateResidency == nullptr) {
55       return ScopedAStatus::fromServiceSpecificErrorWithMessage(
56           NFCSTATUS_INVALID_PARAMETER, "Invalid Param");
57     }
58     stateResidency->resize(MAX_STATES);
59 
60     NXPLOG_NCIHAL_I("%s: Returning state residency data", __func__);
61 
62     // STANDBY
63     (*stateResidency)[STANDBY].id = STANDBY;
64     (*stateResidency)[STANDBY].totalTimeInStateMs =
65         NfcProps::standbyStateTick().value_or(0) * STEP_TIME_MS;
66     (*stateResidency)[STANDBY].totalStateEntryCount =
67         NfcProps::standbyStateEntryCount().value_or(0);
68     (*stateResidency)[STANDBY].lastEntryTimestampMs = 0;
69     // ULPDET
70     (*stateResidency)[ULPDET].id = ULPDET;
71     (*stateResidency)[ULPDET].totalTimeInStateMs =
72         NfcProps::ulpdetStateTick().value_or(0) * STEP_TIME_MS;
73     (*stateResidency)[ULPDET].totalStateEntryCount =
74         NfcProps::ulpdetStateEntryCount().value_or(0);
75     (*stateResidency)[ULPDET].lastEntryTimestampMs = 0;
76     // ACTIVE
77     (*stateResidency)[ACTIVE].id = ACTIVE;
78     (*stateResidency)[ACTIVE].totalTimeInStateMs =
79         NfcProps::activeStateTick().value_or(0) * STEP_TIME_MS;
80     (*stateResidency)[ACTIVE].totalStateEntryCount =
81         NfcProps::activeStateEntryCount().value_or(0);
82     (*stateResidency)[ACTIVE].lastEntryTimestampMs = 0;
83 
84     return ScopedAStatus::ok();
85   }
~NfcStateResidencyCallback()86   ~NfcStateResidencyCallback() {}
87 };
88 
89 /******************* Global variables *********************************/
90 std::shared_ptr<IPixelStateResidencyProvider> gStateResidencyProvider = NULL;
91 std::shared_ptr<IPixelStateResidencyCallback> gStateResidencyCallback =
92     ndk::SharedRefBase::make<NfcStateResidencyCallback>();
93 
94 /*******************************************************************************
95 **
96 ** Function         phNxpNciHal_registerToPowerStats()
97 **
98 ** Description      Function to hook with android powerstats HAL.
99 **                  This abstracts power stats HAL implementation with power
100 **                  tracker feature.
101 ** Parameters       None
102 ** Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
103 *******************************************************************************/
phNxpNciHal_registerToPowerStats()104 NFCSTATUS phNxpNciHal_registerToPowerStats() {
105   // Register with power states HAL.
106   SpAIBinder binder(AServiceManager_checkService(kPowerStatsSrvName));
107   gStateResidencyProvider = IPixelStateResidencyProvider::fromBinder(binder);
108   if (gStateResidencyProvider == nullptr) {
109     NXPLOG_NCIHAL_E("%s: Failed to get PowerStats service", __func__);
110     return NFCSTATUS_FAILED;
111   } else {
112     NXPLOG_NCIHAL_D("%s: Registering with Power Stats service", __func__);
113     gStateResidencyProvider->registerCallback(kPowerEntityName,
114                                               gStateResidencyCallback);
115     NXPLOG_NCIHAL_D(
116         "%s: Starting thread pool for communication with powerstats", __func__);
117     ABinderProcess_setThreadPoolMaxThreadCount(1);
118     ABinderProcess_startThreadPool();
119     NXPLOG_NCIHAL_D("%s: Thread pool started successfully", __func__);
120   }
121   return NFCSTATUS_SUCCESS;
122 }
123 
124 /*******************************************************************************
125 **
126 ** Function         phNxpNciHal_unregisterPowerStats()
127 **
128 ** Description      Function to unhook from android powerstats HAL.
129 **                  This abstracts power stats HAL implementation with power
130 **                  tracker feature.
131 ** Parameters       None
132 ** Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
133 *******************************************************************************/
phNxpNciHal_unregisterPowerStats()134 NFCSTATUS phNxpNciHal_unregisterPowerStats() {
135   // Unregister with PowerStats service
136   if (gStateResidencyProvider != nullptr) {
137     gStateResidencyProvider->unregisterCallback(gStateResidencyCallback);
138     gStateResidencyProvider = nullptr;
139     NXPLOG_NCIHAL_D("%s: Unregistered PowerStats callback successfully",
140                     __func__);
141   }
142   return NFCSTATUS_SUCCESS;
143 }
144