• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "chre_host/wifi_ext_hal_handler.h"
18 
19 namespace android {
20 namespace chre {
21 
~WifiExtHalHandler()22 WifiExtHalHandler::~WifiExtHalHandler() {
23   notifyThreadToExit();
24   mThread.join();
25 }
26 
WifiExtHalHandler(const std::function<void (bool)> & statusChangeCallback)27 WifiExtHalHandler::WifiExtHalHandler(
28     const std::function<void(bool)> &statusChangeCallback) {
29   mEnableConfig.reset();
30   mThread = std::thread(&WifiExtHalHandler::wifiExtHandlerThreadEntry, this);
31   auto cb = [&]() { onWifiExtHalServiceDeath(); };
32   mDeathRecipient = new WifiExtHalDeathRecipient(cb);
33   mCallback = new WifiExtCallback(statusChangeCallback);
34 }
35 
handleConfigurationRequest(bool enable)36 void WifiExtHalHandler::handleConfigurationRequest(bool enable) {
37   std::lock_guard<std::mutex> lock(mMutex);
38   mEnableConfig = enable;
39   mCondVar.notify_one();
40 }
41 
dispatchConfigurationRequest(bool enable)42 void WifiExtHalHandler::dispatchConfigurationRequest(bool enable) {
43   auto hidlCb = [this, enable](const WifiStatus &status) {
44     bool success = (status.code == WifiStatusCode::SUCCESS) ? true : false;
45     if (!success) {
46       LOGE("wifi ext hal config request for %s failed with code: %d (%s)",
47            (enable == true) ? "Enable" : "Disable", status.code,
48            status.description.c_str());
49     }
50     mCallback->onStatusChanged(success);
51   };
52 
53   if (checkWifiExtHalConnected()) {
54     auto result = mService->requestWifiChreNanRtt(enable, hidlCb);
55     if (!result.isOk()) {
56       LOGE("Failed to %s NAN: %s", (enable == true) ? "Enable" : "Disable",
57            result.description().c_str());
58     }
59   }
60 }
61 
checkWifiExtHalConnected()62 bool WifiExtHalHandler::checkWifiExtHalConnected() {
63   bool success = false;
64   if (mService == nullptr) {
65     mService = IWifiExt::getService();
66     if (mService != nullptr) {
67       LOGD("Connected to Wifi Ext HAL service");
68       mService->linkToDeath(mDeathRecipient, 0 /*cookie*/);
69 
70       auto hidlCb = [&success](const WifiStatus &status) {
71         success = (status.code == WifiStatusCode::SUCCESS);
72         if (!success) {
73           LOGE("Failed to register CHRE callback with WifiExt: %s",
74                status.description.c_str());
75         }
76       };
77       auto result = mService->registerChreCallback(mCallback, hidlCb);
78       if (!result.isOk()) {
79         LOGE("Failed to register CHRE callback with WifiEmDeathRecipientxt: %s",
80              result.description().c_str());
81       } else {
82         success = true;
83       }
84     } else {
85       LOGE("Failed to connect to Wifi Ext HAL service");
86     }
87   }
88   return success;
89 }
90 
onWifiExtHalServiceDeath()91 void WifiExtHalHandler::onWifiExtHalServiceDeath() {
92   LOGI("WiFi Ext HAL service died");
93   mService = nullptr;
94   // TODO(b/204226580): Figure out if wifi ext HAL is stateful and if it
95   // isn't, notify CHRE of a NAN disabled status change to enable nanoapps
96   // to not expect NAN data until the service is back up, and expect it to
97   // do a re-enable when needed. Or we could store the current status of
98   // enablement, and do a re-enable/disable when the service is back up.
99 }
100 
wifiExtHandlerThreadEntry()101 void WifiExtHalHandler::wifiExtHandlerThreadEntry() {
102   while (mThreadRunning) {
103     std::unique_lock<std::mutex> lock(mMutex);
104     mCondVar.wait(
105         lock, [this] { return mEnableConfig.has_value() || !mThreadRunning; });
106 
107     if (mThreadRunning) {
108       dispatchConfigurationRequest(mEnableConfig.value());
109       mEnableConfig.reset();
110     }
111   }
112 }
113 
notifyThreadToExit()114 void WifiExtHalHandler::notifyThreadToExit() {
115   std::lock_guard<std::mutex> lock(mMutex);
116   mThreadRunning = false;
117   mCondVar.notify_one();
118 }
119 
120 }  // namespace chre
121 }  // namespace android
122