libminradio: support deferred rilConnected
Bug: 405183501
Test: boot cf_phone with ngril but without modem connected
Flag: EXEMPT vendor HAL changes only
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:91258e107a01092ed732988dbd7f63fb516f72d3)
Merged-In: I8c4c25748b77666cf93a1895d968f9cd66fe38b2
Change-Id: I8c4c25748b77666cf93a1895d968f9cd66fe38b2
diff --git a/radio/aidl/minradio/libminradio/RadioSlotBase.cpp b/radio/aidl/minradio/libminradio/RadioSlotBase.cpp
index 0f4bd68..07febc7 100644
--- a/radio/aidl/minradio/libminradio/RadioSlotBase.cpp
+++ b/radio/aidl/minradio/libminradio/RadioSlotBase.cpp
@@ -20,4 +20,15 @@
RadioSlotBase::RadioSlotBase(std::shared_ptr<SlotContext> context) : mContext(context) {}
+void RadioSlotBase::setResponseFunctionsBase() {
+ mHasResponseFunctions = true;
+ if (mContext->isConnected()) onUpdatedResponseFunctions();
+}
+
+void RadioSlotBase::onUpdatedResponseFunctions() {}
+
+void RadioSlotBase::onConnected() {
+ if (mHasResponseFunctions) setResponseFunctionsBase();
+}
+
} // namespace android::hardware::radio::minimal
diff --git a/radio/aidl/minradio/libminradio/SlotContext.cpp b/radio/aidl/minradio/libminradio/SlotContext.cpp
index cffc178..58dbc8d 100644
--- a/radio/aidl/minradio/libminradio/SlotContext.cpp
+++ b/radio/aidl/minradio/libminradio/SlotContext.cpp
@@ -16,12 +16,33 @@
#include <libminradio/SlotContext.h>
+#include <android-base/logging.h>
+#include <libminradio/RadioSlotBase.h>
+
namespace android::hardware::radio::minimal {
SlotContext::SlotContext(unsigned slotIndex) : mSlotIndex(slotIndex) {}
+void SlotContext::setConnected() {
+ CHECK(!mIsConnected) << "Can't setConnected twice";
+ mIsConnected = true;
+ for (auto weakHal : mHals) {
+ auto hal = weakHal.lock();
+ if (!hal) continue;
+ hal->onConnected();
+ }
+}
+
+bool SlotContext::isConnected() const {
+ return mIsConnected;
+}
+
unsigned SlotContext::getSlotIndex() const {
return mSlotIndex;
}
+void SlotContext::addHal(std::weak_ptr<RadioSlotBase> hal) {
+ mHals.push_back(hal);
+}
+
} // namespace android::hardware::radio::minimal
diff --git a/radio/aidl/minradio/libminradio/data/RadioData.cpp b/radio/aidl/minradio/libminradio/data/RadioData.cpp
index a096c82..b5d8f66 100644
--- a/radio/aidl/minradio/libminradio/data/RadioData.cpp
+++ b/radio/aidl/minradio/libminradio/data/RadioData.cpp
@@ -137,6 +137,7 @@
CHECK(indication);
respond = response;
indicate = indication;
+ setResponseFunctionsBase();
return ok();
}
diff --git a/radio/aidl/minradio/libminradio/include/libminradio/RadioSlotBase.h b/radio/aidl/minradio/libminradio/include/libminradio/RadioSlotBase.h
index d46357e..06c0fc6 100644
--- a/radio/aidl/minradio/libminradio/include/libminradio/RadioSlotBase.h
+++ b/radio/aidl/minradio/libminradio/include/libminradio/RadioSlotBase.h
@@ -22,11 +22,28 @@
namespace android::hardware::radio::minimal {
class RadioSlotBase {
+ private:
+ bool mHasResponseFunctions = false;
+
protected:
std::shared_ptr<SlotContext> mContext;
+ void setResponseFunctionsBase();
+
+ /**
+ * Called when new response functions are set. This is the place to send initial indications,
+ * such as rilConnected or radioStateChanged.
+ *
+ * This callback is deferred if the RIL is not connected. In such case, it will be called after
+ * getting rilConnected indication.
+ */
+ virtual void onUpdatedResponseFunctions();
+
public:
RadioSlotBase(std::shared_ptr<SlotContext> context);
+ virtual ~RadioSlotBase() = default;
+
+ void onConnected();
};
} // namespace android::hardware::radio::minimal
diff --git a/radio/aidl/minradio/libminradio/include/libminradio/SlotContext.h b/radio/aidl/minradio/libminradio/include/libminradio/SlotContext.h
index bc6f61e..c2dd7a5 100644
--- a/radio/aidl/minradio/libminradio/include/libminradio/SlotContext.h
+++ b/radio/aidl/minradio/libminradio/include/libminradio/SlotContext.h
@@ -15,16 +15,31 @@
*/
#pragma once
+#include <memory>
+#include <vector>
+
namespace android::hardware::radio::minimal {
+class RadioSlotBase;
+
class SlotContext {
public:
SlotContext(unsigned slotIndex);
+ /**
+ * Mark this RIL/modem as connected. This triggers communication with the framework.
+ */
+ void setConnected();
+ bool isConnected() const;
+
unsigned getSlotIndex() const;
+ void addHal(std::weak_ptr<RadioSlotBase> hal);
+
private:
+ bool mIsConnected = false;
unsigned mSlotIndex;
+ std::vector<std::weak_ptr<RadioSlotBase>> mHals;
};
} // namespace android::hardware::radio::minimal
diff --git a/radio/aidl/minradio/libminradio/include/libminradio/modem/RadioModem.h b/radio/aidl/minradio/libminradio/include/libminradio/modem/RadioModem.h
index fda44c8..4d77771 100644
--- a/radio/aidl/minradio/libminradio/include/libminradio/modem/RadioModem.h
+++ b/radio/aidl/minradio/libminradio/include/libminradio/modem/RadioModem.h
@@ -29,6 +29,8 @@
std::vector<aidl::android::hardware::radio::RadioTechnology> rats);
protected:
+ void onUpdatedResponseFunctions() override;
+
::ndk::ScopedAStatus enableModem(int32_t serial, bool on) override;
::ndk::ScopedAStatus getBasebandVersion(int32_t serial) override;
::ndk::ScopedAStatus getDeviceIdentity(int32_t serial) override;
diff --git a/radio/aidl/minradio/libminradio/include/libminradio/network/RadioNetwork.h b/radio/aidl/minradio/libminradio/include/libminradio/network/RadioNetwork.h
index 4d3505a..a75e4fd 100644
--- a/radio/aidl/minradio/libminradio/include/libminradio/network/RadioNetwork.h
+++ b/radio/aidl/minradio/libminradio/include/libminradio/network/RadioNetwork.h
@@ -30,6 +30,7 @@
protected:
std::vector<::aidl::android::hardware::radio::network::CellInfo> getCellInfoListBase();
+ void onUpdatedResponseFunctions() override;
::ndk::ScopedAStatus getAllowedNetworkTypesBitmap(int32_t serial) override;
::ndk::ScopedAStatus getAvailableBandModes(int32_t serial) override;
diff --git a/radio/aidl/minradio/libminradio/include/libminradio/response.h b/radio/aidl/minradio/libminradio/include/libminradio/response.h
index 5692628..f101a04 100644
--- a/radio/aidl/minradio/libminradio/include/libminradio/response.h
+++ b/radio/aidl/minradio/libminradio/include/libminradio/response.h
@@ -25,4 +25,16 @@
aidl::android::hardware::radio::RadioResponseInfo errorResponse(
int32_t serial, aidl::android::hardware::radio::RadioError error);
+#define RESPOND_ERROR_IF_NOT_CONNECTED(responseMethod) \
+ if (!mContext->isConnected()) RESPOND_NOT_CONNECTED(responseMethod);
+
+#define RESPOND_NOT_CONNECTED(responseMethod) \
+ { \
+ LOG(WARNING) << (RADIO_MODULE ".") << __func__ << " called before rilConnected"; \
+ const auto responseInfo = ::android::hardware::radio::minimal::errorResponse( \
+ serial, ::aidl::android::hardware::radio::RadioError::RADIO_NOT_AVAILABLE); \
+ respond()->responseMethod(responseInfo, {}); \
+ return ok(); \
+ }
+
} // namespace android::hardware::radio::minimal
diff --git a/radio/aidl/minradio/libminradio/modem/RadioModem.cpp b/radio/aidl/minradio/libminradio/modem/RadioModem.cpp
index f29cd39..f5feaf4 100644
--- a/radio/aidl/minradio/libminradio/modem/RadioModem.cpp
+++ b/radio/aidl/minradio/libminradio/modem/RadioModem.cpp
@@ -190,11 +190,13 @@
CHECK(indication);
respond = response;
indicate = indication;
+ setResponseFunctionsBase();
+ return ok();
+}
+void RadioModem::onUpdatedResponseFunctions() {
indicate()->rilConnected(RadioIndicationType::UNSOLICITED);
indicate()->radioStateChanged(RadioIndicationType::UNSOLICITED, aidl::RadioState::ON);
-
- return ok();
}
} // namespace android::hardware::radio::minimal
diff --git a/radio/aidl/minradio/libminradio/network/RadioNetwork.cpp b/radio/aidl/minradio/libminradio/network/RadioNetwork.cpp
index e2d2a56..ce3a17e 100644
--- a/radio/aidl/minradio/libminradio/network/RadioNetwork.cpp
+++ b/radio/aidl/minradio/libminradio/network/RadioNetwork.cpp
@@ -216,7 +216,11 @@
ref<aidl::IRadioNetwork>(), response);
respond = mResponseTracker.get();
indicate = indication;
+ setResponseFunctionsBase();
+ return ok();
+}
+void RadioNetwork::onUpdatedResponseFunctions() {
indicate()->cellInfoList(RadioIndicationType::UNSOLICITED, getCellInfoListBase());
auto signalStrengthResponse = mResponseTracker()->getSignalStrength();
if (signalStrengthResponse.expectOk()) {
@@ -238,8 +242,6 @@
}
}).detach();
}
-
- return ok();
}
ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
diff --git a/radio/aidl/minradio/libminradio/sim/RadioSim.cpp b/radio/aidl/minradio/libminradio/sim/RadioSim.cpp
index 0365a88..58aa711 100644
--- a/radio/aidl/minradio/libminradio/sim/RadioSim.cpp
+++ b/radio/aidl/minradio/libminradio/sim/RadioSim.cpp
@@ -239,6 +239,7 @@
CHECK(indication);
respond = response;
indicate = indication;
+ setResponseFunctionsBase();
return ok();
}
diff --git a/radio/aidl/minradio/minradio-example/service.cpp b/radio/aidl/minradio/minradio-example/service.cpp
index 6d3c020..8b6ae72 100644
--- a/radio/aidl/minradio/minradio-example/service.cpp
+++ b/radio/aidl/minradio/minradio-example/service.cpp
@@ -31,9 +31,10 @@
static std::vector<std::shared_ptr<ndk::ICInterface>> gPublishedHals;
static void publishRadioConfig() {
+ const auto instance = RadioConfig::descriptor + "/default"s;
+ LOG(DEBUG) << "Publishing " << instance;
auto aidlHal = ndk::SharedRefBase::make<RadioConfig>();
gPublishedHals.push_back(aidlHal);
- const auto instance = RadioConfig::descriptor + "/default"s;
const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
}
@@ -47,9 +48,9 @@
return;
}
LOG(DEBUG) << "Publishing " << instance;
-
auto aidlHal = ndk::SharedRefBase::make<T>(context);
gPublishedHals.push_back(aidlHal);
+ context->addHal(aidlHal);
const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
}
@@ -63,13 +64,15 @@
ABinderProcess_startThreadPool();
auto slot1Context = std::make_shared<minimal::SlotContext>(1);
-
publishRadioConfig();
publishRadioHal<RadioData>("slot1", slot1Context);
publishRadioHal<RadioModem>("slot1", slot1Context);
publishRadioHal<RadioNetwork>("slot1", slot1Context);
publishRadioHal<RadioSim>("slot1", slot1Context);
+ // Non-virtual implementation would set up and initialize connection to the modem here
+
+ slot1Context->setConnected();
LOG(DEBUG) << "Minimal Radio HAL service is operational";
ABinderProcess_joinThreadPool();
LOG(FATAL) << "Minimal Radio HAL service has stopped";