Merge "Update NNAPI owners file"
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
index d7d5476..6e8c1d7 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.cpp
@@ -41,12 +41,8 @@
BluetoothAudioProvidersFactory::hearing_aid_provider_instance_;
LeAudioOutputAudioProvider
BluetoothAudioProvidersFactory::leaudio_output_provider_instance_;
-LeAudioOffloadOutputAudioProvider
- BluetoothAudioProvidersFactory::leaudio_offload_output_provider_instance_;
LeAudioInputAudioProvider
BluetoothAudioProvidersFactory::leaudio_input_provider_instance_;
-LeAudioOffloadInputAudioProvider
- BluetoothAudioProvidersFactory::leaudio_offload_input_provider_instance_;
Return<void> BluetoothAudioProvidersFactory::openProvider(
const V2_0::SessionType sessionType, openProvider_cb _hidl_cb) {
@@ -94,15 +90,9 @@
case SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
provider = &leaudio_output_provider_instance_;
break;
- case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
- provider = &leaudio_offload_output_provider_instance_;
- break;
case SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
provider = &leaudio_input_provider_instance_;
break;
- case SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
- provider = &leaudio_offload_input_provider_instance_;
- break;
default:
status = BluetoothAudioStatus::FAILURE;
}
diff --git a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
index f8f557e..714d738 100644
--- a/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.1/default/BluetoothAudioProvidersFactory.h
@@ -56,8 +56,6 @@
static HearingAidAudioProvider hearing_aid_provider_instance_;
static LeAudioOutputAudioProvider leaudio_output_provider_instance_;
static LeAudioInputAudioProvider leaudio_input_provider_instance_;
- static LeAudioOffloadOutputAudioProvider leaudio_offload_output_provider_instance_;
- static LeAudioOffloadInputAudioProvider leaudio_offload_input_provider_instance_;
};
extern "C" IBluetoothAudioProvidersFactory*
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
index bc16b01..f577537 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvider.hal
@@ -59,4 +59,14 @@
*/
startSession_2_2(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
generates (Status status, fmq_sync<uint8_t> dataMQ);
+
+ /**
+ * Called when the audio configuration of the stream has been changed.
+ *
+ * @param audioConfig The audio configuration negotiated with the remote
+ * device. The PCM parameters are set if software based encoding,
+ * otherwise the correct codec configuration is used for hardware
+ * encoding.
+ */
+ updateAudioConfiguration(AudioConfiguration audioConfig);
};
diff --git a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
index 7fb5b6c..ae9c598 100644
--- a/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
+++ b/bluetooth/audio/2.2/IBluetoothAudioProvidersFactory.hal
@@ -48,4 +48,26 @@
*/
openProvider_2_2(SessionType sessionType)
generates (Status status, IBluetoothAudioProvider provider);
+
+ /**
+ * Gets a list of audio capabilities for a session type.
+ *
+ * For software encoding, the PCM capabilities are returned.
+ * For hardware encoding, the supported codecs and their capabilities are
+ * returned.
+ *
+ * @param sessionType The session type (e.g.
+ * A2DP_SOFTWARE_ENCODING_DATAPATH).
+ * @return audioCapabilities A list containing all the capabilities
+ * supported by the sesson type. The capabilities is a list of
+ * available options when configuring the codec for the session.
+ * For software encoding it is the PCM data rate.
+ * For hardware encoding it is the list of supported codecs and their
+ * capabilities.
+ * If a provider isn't supported, an empty list should be returned.
+ * Note: Only one entry should exist per codec when using hardware
+ * encoding.
+ */
+ getProviderCapabilities_2_2(SessionType sessionType)
+ generates (vec<AudioCapabilities> audioCapabilities);
};
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
index 18ac292..202cfb9 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.cpp
@@ -186,6 +186,29 @@
return Void();
}
+Return<void> BluetoothAudioProvider::updateAudioConfiguration(
+ const AudioConfiguration& audioConfig) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
+
+ if (stack_iface_ == nullptr) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " has NO session";
+ return Void();
+ }
+
+ if (audioConfig.getDiscriminator() != audio_config_.getDiscriminator()) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
+ << " audio config type is not match";
+ return Void();
+ }
+
+ audio_config_ = audioConfig;
+ BluetoothAudioSessionReport_2_2::ReportAudioConfigChanged(session_type_,
+ audio_config_);
+
+ return Void();
+}
+
} // namespace implementation
} // namespace V2_2
} // namespace audio
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
index 0f1f3c6..425ea3b 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvider.h
@@ -53,6 +53,8 @@
Return<void> streamStarted(BluetoothAudioStatus status) override;
Return<void> streamSuspended(BluetoothAudioStatus status) override;
Return<void> endSession() override;
+ Return<void> updateAudioConfiguration(
+ const AudioConfiguration& audioConfig) override;
protected:
sp<BluetoothAudioDeathRecipient> death_recipient_;
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
index 51ee422..9435311 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.cpp
@@ -98,15 +98,9 @@
case V2_1::SessionType::LE_AUDIO_SOFTWARE_ENCODING_DATAPATH:
provider = &leaudio_output_provider_instance_;
break;
- case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH:
- provider = &leaudio_offload_output_provider_instance_;
- break;
case V2_1::SessionType::LE_AUDIO_SOFTWARE_DECODED_DATAPATH:
provider = &leaudio_input_provider_instance_;
break;
- case V2_1::SessionType::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH:
- provider = &leaudio_offload_input_provider_instance_;
- break;
default:
status = BluetoothAudioStatus::FAILURE;
}
@@ -221,6 +215,47 @@
return Void();
}
+Return<void> BluetoothAudioProvidersFactory::getProviderCapabilities_2_2(
+ const V2_1::SessionType sessionType,
+ getProviderCapabilities_2_2_cb _hidl_cb) {
+ hidl_vec<V2_2::AudioCapabilities> audio_capabilities =
+ hidl_vec<V2_2::AudioCapabilities>(0);
+ if (sessionType == V2_1::SessionType::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
+ std::vector<CodecCapabilities> db_codec_capabilities =
+ android::bluetooth::audio::GetOffloadCodecCapabilities(sessionType);
+ if (db_codec_capabilities.size()) {
+ audio_capabilities.resize(db_codec_capabilities.size());
+ for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+ audio_capabilities[i].codecCapabilities(db_codec_capabilities[i]);
+ }
+ }
+ } else if (sessionType == V2_1::SessionType::
+ LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ sessionType == V2_1::SessionType::
+ LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ std::vector<LeAudioCodecCapabilitiesPair> db_codec_capabilities =
+ android::bluetooth::audio::GetLeAudioOffloadCodecCapabilities(
+ sessionType);
+ if (db_codec_capabilities.size()) {
+ audio_capabilities.resize(db_codec_capabilities.size());
+ for (int i = 0; i < db_codec_capabilities.size(); ++i) {
+ audio_capabilities[i].leAudioCapabilities(db_codec_capabilities[i]);
+ }
+ }
+ } else if (sessionType != V2_1::SessionType::UNKNOWN) {
+ std::vector<V2_1::PcmParameters> db_pcm_capabilities =
+ android::bluetooth::audio::GetSoftwarePcmCapabilities_2_1();
+ if (db_pcm_capabilities.size() == 1) {
+ audio_capabilities.resize(1);
+ audio_capabilities[0].pcmCapabilities(db_pcm_capabilities[0]);
+ }
+ }
+ LOG(INFO) << __func__ << " - SessionType=" << toString(sessionType)
+ << " supports " << audio_capabilities.size() << " codecs";
+ _hidl_cb(audio_capabilities);
+ return Void();
+}
+
IBluetoothAudioProvidersFactory* HIDL_FETCH_IBluetoothAudioProvidersFactory(
const char* /* name */) {
return new BluetoothAudioProvidersFactory();
diff --git a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
index 658249b..4f549d9 100644
--- a/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
+++ b/bluetooth/audio/2.2/default/BluetoothAudioProvidersFactory.h
@@ -53,6 +53,10 @@
const V2_1::SessionType sessionType,
getProviderCapabilities_2_1_cb _hidl_cb) override;
+ Return<void> getProviderCapabilities_2_2(
+ const V2_1::SessionType sessionType,
+ getProviderCapabilities_2_2_cb _hidl_cb) override;
+
private:
static A2dpSoftwareAudioProvider a2dp_software_provider_instance_;
static A2dpOffloadAudioProvider a2dp_offload_provider_instance_;
diff --git a/bluetooth/audio/2.2/types.hal b/bluetooth/audio/2.2/types.hal
index d5f8a3f..8ec3660 100644
--- a/bluetooth/audio/2.2/types.hal
+++ b/bluetooth/audio/2.2/types.hal
@@ -19,6 +19,8 @@
import @2.1::Lc3Parameters;
import @2.1::PcmParameters;
import @2.0::CodecConfiguration;
+import @2.0::CodecCapabilities;
+import @2.1::CodecType;
enum LeAudioMode : uint8_t {
UNKNOWN = 0x00,
@@ -26,6 +28,12 @@
BROADCAST = 0x02,
};
+enum AudioLocation : uint8_t {
+ UNKNOWN = 0,
+ FRONT_LEFT = 1,
+ FRONT_RIGHT = 2,
+};
+
struct UnicastStreamMap {
/* The connection handle used for a unicast or a broadcast group. */
uint16_t streamHandle;
@@ -70,3 +78,37 @@
CodecConfiguration codecConfig;
LeAudioConfiguration leAudioConfig;
};
+
+/** Used to specify the capabilities of the different session types */
+safe_union AudioCapabilities {
+ PcmParameters pcmCapabilities;
+ CodecCapabilities codecCapabilities;
+ LeAudioCodecCapabilitiesPair leAudioCapabilities;
+};
+
+/**
+ * Used to specify th le audio capabilities pair of the Hardware offload encode and decode.
+ */
+struct LeAudioCodecCapabilitiesPair{
+ LeAudioMode mode;
+ LeAudioCodecCapability encodeCapability;
+ LeAudioCodecCapability decodeCapability;
+};
+
+/**
+ * Used to specify the le audio capabilities of the codecs supported by Hardware offload
+ * for encode or decode.
+ */
+struct LeAudioCodecCapability {
+ CodecType codecType;
+ AudioLocation supportedChannel;
+
+ // The number of connected device
+ uint8_t deviceCount;
+
+ // Supported channel count for each device
+ uint8_t channelCountPerDevice;
+
+ // Should use safe union when there is more than one codec
+ Lc3Parameters capabilities;
+};
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
index dbdf247..368939e 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionControl_2_2.h
@@ -48,20 +48,38 @@
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
- return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
+ PortStatusCallbacks_2_2 cb = {
+ .control_result_cb_ = cbacks.control_result_cb_,
+ .session_changed_cb_ = cbacks.session_changed_cb_,
+ .audio_configuration_changed_cb_ = nullptr};
+ return session_ptr->RegisterStatusCback(cb);
+ }
+ return kObserversCookieUndefined;
+ }
+
+ // The control API helps the bluetooth_audio module to register
+ // PortStatusCallbacks_2_2
+ // @return: cookie - the assigned number to this bluetooth_audio output
+ static uint16_t RegisterControlResultCback(
+ const SessionType_2_1& session_type,
+ const PortStatusCallbacks_2_2& cbacks) {
+ std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+ BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ return session_ptr->RegisterStatusCback(cbacks);
}
return kObserversCookieUndefined;
}
// The control API helps the bluetooth_audio module to unregister
- // PortStatusCallbacks
+ // PortStatusCallbacks and PortStatusCallbacks_2_2
// @param: cookie - indicates which bluetooth_audio output is
static void UnregisterControlResultCback(const SessionType_2_1& session_type,
uint16_t cookie) {
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
- session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
+ session_ptr->UnregisterStatusCback(cookie);
}
}
@@ -76,6 +94,12 @@
} else if (session_type ==
SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
return BluetoothAudioSession_2_2::kInvalidOffloadAudioConfiguration;
+ } else if (
+ session_type ==
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type ==
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ return BluetoothAudioSession_2_2::kInvalidLeOffloadAudioConfiguration;
} else {
return BluetoothAudioSession_2_2::kInvalidSoftwareAudioConfiguration;
}
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
index 194259a..17e140e 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSessionReport_2_2.h
@@ -48,7 +48,7 @@
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
- session_ptr->GetAudioSession()->OnSessionEnded();
+ session_ptr->OnSessionEnded();
}
}
// The API reports the Bluetooth stack has replied the result of startStream
@@ -60,7 +60,20 @@
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
if (session_ptr != nullptr) {
- session_ptr->GetAudioSession()->ReportControlStatus(start_resp, status);
+ session_ptr->ReportControlStatus(start_resp, status);
+ }
+ }
+ // The API reports the Bluetooth stack has replied the changed of the audio
+ // configuration, and will inform registered bluetooth_audio outputs
+ static void ReportAudioConfigChanged(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type,
+ const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+ audio_config) {
+ std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
+ BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
+ if (session_ptr != nullptr) {
+ session_ptr->ReportAudioConfigChanged(audio_config);
}
}
};
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
index ee2096b..60ac4ec 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.cpp
@@ -29,6 +29,13 @@
using ::android::hardware::audio::common::V5_0::AudioSource;
using ::android::hardware::audio::common::V5_0::RecordTrackMetadata;
using ::android::hardware::audio::common::V5_0::SinkMetadata;
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
+using ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration;
+using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
+using PcmParameters_2_1 =
+ ::android::hardware::bluetooth::audio::V2_1::PcmParameters;
+using SampleRate_2_1 = ::android::hardware::bluetooth::audio::V2_1::SampleRate;
using SessionType_2_1 =
::android::hardware::bluetooth::audio::V2_1::SessionType;
@@ -38,10 +45,24 @@
using AudioConfiguration_2_1 =
::android::hardware::bluetooth::audio::V2_1::AudioConfiguration;
+static constexpr PcmParameters_2_1 kInvalidPcmParameters = {
+ .sampleRate = SampleRate_2_1::RATE_UNKNOWN,
+ .channelMode = ChannelMode::UNKNOWN,
+ .bitsPerSample = BitsPerSample::BITS_UNKNOWN,
+ .dataIntervalUs = 0,
+};
+
+static LeAudioConfiguration kInvalidLeAudioConfig = {
+ .mode = LeAudioMode::UNKNOWN,
+ .config = {},
+};
+
::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
BluetoothAudioSession_2_2::invalidSoftwareAudioConfiguration = {};
::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
BluetoothAudioSession_2_2::invalidOffloadAudioConfiguration = {};
+::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
+ BluetoothAudioSession_2_2::invalidLeOffloadAudioConfiguration = {};
using IBluetoothAudioPort_2_2 =
::android::hardware::bluetooth::audio::V2_2::IBluetoothAudioPort;
@@ -72,6 +93,10 @@
} else {
session_type_2_1_ = (session_type);
}
+ invalidSoftwareAudioConfiguration.pcmConfig(kInvalidPcmParameters);
+ invalidOffloadAudioConfiguration.codecConfig(
+ audio_session->kInvalidCodecConfiguration);
+ invalidLeOffloadAudioConfiguration.leAudioConfig(kInvalidLeAudioConfig);
}
bool BluetoothAudioSession_2_2::IsSessionReady() {
@@ -149,9 +174,17 @@
BluetoothAudioSession_2_2::GetAudioConfig() {
std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
if (IsSessionReady()) {
+ auto audio_config_discriminator = audio_config_2_2_.getDiscriminator();
// If session is unknown it means it should be 2.0 type
if (session_type_2_1_ != SessionType_2_1::UNKNOWN) {
- if (audio_config_2_2_ != invalidSoftwareAudioConfiguration)
+ if ((audio_config_discriminator ==
+ ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
+ hidl_discriminator::pcmConfig &&
+ audio_config_2_2_ != kInvalidSoftwareAudioConfiguration) ||
+ (audio_config_discriminator ==
+ ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration::
+ hidl_discriminator::leAudioConfig &&
+ audio_config_2_2_ != kInvalidLeOffloadAudioConfiguration))
return audio_config_2_2_;
::android::hardware::bluetooth::audio::V2_2::AudioConfiguration toConf;
@@ -181,8 +214,10 @@
}
return toConf;
} else if (session_type_2_1_ ==
- SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH) {
- return kInvalidOffloadAudioConfiguration;
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type_2_1_ ==
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ return kInvalidLeOffloadAudioConfiguration;
} else {
return kInvalidSoftwareAudioConfiguration;
}
@@ -314,18 +349,190 @@
LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
<< " DataMQ Invalid";
audio_config_2_2_ =
- (session_type_2_1_ == SessionType_2_1::A2DP_HARDWARE_OFFLOAD_DATAPATH
- ? kInvalidOffloadAudioConfiguration
+ ((session_type_2_1_ ==
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type_2_1_ ==
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH)
+ ? kInvalidLeOffloadAudioConfiguration
: kInvalidSoftwareAudioConfiguration);
} else {
audio_session->stack_iface_ = stack_iface;
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
<< ", AudioConfiguration=" << toString(audio_config);
- audio_session->ReportSessionStatus();
+ ReportSessionStatus();
};
}
}
+// The report function is used to report that the Bluetooth stack has ended the
+// session, and will invoke session_changed_cb_ to notify registered
+// bluetooth_audio outputs
+void BluetoothAudioSession_2_2::OnSessionEnded() {
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ bool toggled = IsSessionReady();
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_);
+ if (session_type_2_1_ == SessionType_2_1::UNKNOWN) {
+ audio_session->OnSessionEnded();
+ return;
+ }
+
+ audio_config_2_2_ =
+ ((session_type_2_1_ ==
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH ||
+ session_type_2_1_ ==
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH)
+ ? kInvalidLeOffloadAudioConfiguration
+ : kInvalidSoftwareAudioConfiguration);
+ audio_session->stack_iface_ = nullptr;
+ audio_session->UpdateDataPath(nullptr);
+ if (toggled) {
+ ReportSessionStatus();
+ }
+}
+
+// The control function helps the bluetooth_audio module to register
+// PortStatusCallbacks_2_2
+// @return: cookie - the assigned number to this bluetooth_audio output
+uint16_t BluetoothAudioSession_2_2::RegisterStatusCback(
+ const PortStatusCallbacks_2_2& cbacks) {
+ if (session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ PortStatusCallbacks cb = {
+ .control_result_cb_ = cbacks.control_result_cb_,
+ .session_changed_cb_ = cbacks.session_changed_cb_};
+ return audio_session->RegisterStatusCback(cb);
+ }
+
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ uint16_t cookie = ObserversCookieGetInitValue(session_type_2_1_);
+ uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_2_1_);
+
+ while (cookie < cookie_upper_bound) {
+ if (observers_.find(cookie) == observers_.end()) {
+ break;
+ }
+ ++cookie;
+ }
+ if (cookie >= cookie_upper_bound) {
+ LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " has " << observers_.size()
+ << " observers already (No Resource)";
+ return kObserversCookieUndefined;
+ }
+ std::shared_ptr<struct PortStatusCallbacks_2_2> cb =
+ std::make_shared<struct PortStatusCallbacks_2_2>();
+ *cb = cbacks;
+ observers_[cookie] = cb;
+ return cookie;
+}
+
+// The control function helps the bluetooth_audio module to unregister
+// PortStatusCallbacks_2_2
+// @param: cookie - indicates which bluetooth_audio output is
+void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) {
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ if (session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ audio_session->UnregisterStatusCback(cookie);
+ return;
+ }
+ if (observers_.erase(cookie) != 1) {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " no such provider=0x"
+ << android::base::StringPrintf("%04x", cookie);
+ }
+}
+
+// invoking the registered session_changed_cb_
+void BluetoothAudioSession_2_2::ReportSessionStatus() {
+ // This is locked already by OnSessionStarted / OnSessionEnded
+ if (session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ audio_session->ReportSessionStatus();
+ return;
+ }
+ if (observers_.empty()) {
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " has NO port state observer";
+ return;
+ }
+ for (auto& observer : observers_) {
+ uint16_t cookie = observer.first;
+ std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+ LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " notify to bluetooth_audio=0x"
+ << android::base::StringPrintf("%04x", cookie);
+ cb->session_changed_cb_(cookie);
+ }
+}
+
+// The report function is used to report that the Bluetooth stack has notified
+// the result of startStream or suspendStream, and will invoke
+// control_result_cb_ to notify registered bluetooth_audio outputs
+void BluetoothAudioSession_2_2::ReportControlStatus(
+ bool start_resp, const BluetoothAudioStatus& status) {
+ if (session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ audio_session->ReportControlStatus(start_resp, status);
+ return;
+ }
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ if (observers_.empty()) {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " has NO port state observer";
+ return;
+ }
+ for (auto& observer : observers_) {
+ uint16_t cookie = observer.first;
+ std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+ LOG(INFO) << __func__ << " - status=" << toString(status)
+ << " for SessionType=" << toString(session_type_2_1_)
+ << ", bluetooth_audio=0x"
+ << android::base::StringPrintf("%04x", cookie)
+ << (start_resp ? " started" : " suspended");
+ cb->control_result_cb_(cookie, start_resp, status);
+ }
+}
+
+// The report function is used to report that the Bluetooth stack has notified
+// the result of startStream or suspendStream, and will invoke
+// control_result_cb_ to notify registered bluetooth_audio outputs
+void BluetoothAudioSession_2_2::ReportAudioConfigChanged(
+ const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+ audio_config) {
+ if (session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type_2_1_ !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ return;
+ }
+ std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
+ audio_config_2_2_ = audio_config;
+ if (observers_.empty()) {
+ LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
+ << " has NO port state observer";
+ return;
+ }
+ for (auto& observer : observers_) {
+ uint16_t cookie = observer.first;
+ std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
+ LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_2_1_)
+ << ", bluetooth_audio=0x"
+ << android::base::StringPrintf("%04x", cookie);
+ if (cb->audio_configuration_changed_cb_ != nullptr) {
+ cb->audio_configuration_changed_cb_(cookie);
+ }
+ }
+}
+
std::unique_ptr<BluetoothAudioSessionInstance_2_2>
BluetoothAudioSessionInstance_2_2::instance_ptr =
std::unique_ptr<BluetoothAudioSessionInstance_2_2>(
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
index 3f1f0e0..3673fd8 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSession_2_2.h
@@ -28,6 +28,40 @@
namespace bluetooth {
namespace audio {
+inline uint16_t ObserversCookieGetInitValue(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
+}
+inline uint16_t ObserversCookieGetUpperBound(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type) {
+ return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
+ kObserversCookieSize;
+}
+
+struct PortStatusCallbacks_2_2 {
+ // control_result_cb_ - when the Bluetooth stack reports results of
+ // streamStarted or streamSuspended, the BluetoothAudioProvider will invoke
+ // this callback to report to the bluetooth_audio module.
+ // @param: cookie - indicates which bluetooth_audio output should handle
+ // @param: start_resp - this report is for startStream or not
+ // @param: status - the result of startStream
+ std::function<void(uint16_t cookie, bool start_resp,
+ const BluetoothAudioStatus& status)>
+ control_result_cb_;
+ // session_changed_cb_ - when the Bluetooth stack start / end session, the
+ // BluetoothAudioProvider will invoke this callback to notify to the
+ // bluetooth_audio module.
+ // @param: cookie - indicates which bluetooth_audio output should handle
+ std::function<void(uint16_t cookie)> session_changed_cb_;
+ // audio_configuration_changed_cb_ - when the Bluetooth stack change the audio
+ // configuration, the BluetoothAudioProvider will invoke this callback to
+ // notify to the bluetooth_audio module.
+ // @param: cookie - indicates which bluetooth_audio output should handle
+ std::function<void(uint16_t cookie)> audio_configuration_changed_cb_;
+};
+
class BluetoothAudioSession_2_2 {
private:
std::shared_ptr<BluetoothAudioSession> audio_session;
@@ -47,6 +81,15 @@
invalidSoftwareAudioConfiguration;
static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
invalidOffloadAudioConfiguration;
+ static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
+ invalidLeOffloadAudioConfiguration;
+
+ // saving those registered bluetooth_audio's callbacks
+ std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks_2_2>>
+ observers_;
+
+ // invoking the registered session_changed_cb_
+ void ReportSessionStatus();
public:
BluetoothAudioSession_2_2(
@@ -69,12 +112,40 @@
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
audio_config);
+ // The report function is used to report that the Bluetooth stack has ended
+ // the session, and will invoke session_changed_cb_ to notify registered
+ // bluetooth_audio outputs
+ void OnSessionEnded();
+
// Those control functions are for the bluetooth_audio module to start,
// suspend, stop stream, to check position, and to update metadata.
bool StartStream();
bool SuspendStream();
void StopStream();
+ // The control function helps the bluetooth_audio module to register
+ // PortStatusCallbacks_2_2
+ // @return: cookie - the assigned number to this bluetooth_audio output
+ uint16_t RegisterStatusCback(const PortStatusCallbacks_2_2& cbacks);
+
+ // The control function helps the bluetooth_audio module to unregister
+ // PortStatusCallbacks_2_2
+ // @param: cookie - indicates which bluetooth_audio output is
+ void UnregisterStatusCback(uint16_t cookie);
+
+ // The report function is used to report that the Bluetooth stack has notified
+ // the result of startStream or suspendStream, and will invoke
+ // control_result_cb_ to notify registered bluetooth_audio outputs
+ void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status);
+
+ // The report function is used to report that the Bluetooth stack has notified
+ // the audio configuration changed, and will invoke
+ // audio_configuration_changed_cb_ to notify registered bluetooth_audio
+ // outputs
+ void ReportAudioConfigChanged(
+ const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
+ audio_config);
+
// The control function is for the bluetooth_audio module to get the current
// AudioConfiguration
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
@@ -88,6 +159,9 @@
static constexpr ::android::hardware::bluetooth::audio::V2_2::
AudioConfiguration& kInvalidOffloadAudioConfiguration =
invalidOffloadAudioConfiguration;
+ static constexpr ::android::hardware::bluetooth::audio::V2_2::
+ AudioConfiguration& kInvalidLeOffloadAudioConfiguration =
+ invalidLeOffloadAudioConfiguration;
};
class BluetoothAudioSessionInstance_2_2 {
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
index 5becdaa..34cfd7e 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.cpp
@@ -24,9 +24,59 @@
namespace bluetooth {
namespace audio {
+using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
+using ::android::hardware::bluetooth::audio::V2_1::CodecType;
+using ::android::hardware::bluetooth::audio::V2_1::Lc3FrameDuration;
+using ::android::hardware::bluetooth::audio::V2_1::Lc3Parameters;
+using ::android::hardware::bluetooth::audio::V2_1::SampleRate;
+using ::android::hardware::bluetooth::audio::V2_2::AudioLocation;
+using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair;
+using ::android::hardware::bluetooth::audio::V2_2::LeAudioCodecCapability;
+using ::android::hardware::bluetooth::audio::V2_2::LeAudioMode;
using SessionType_2_1 =
::android::hardware::bluetooth::audio::V2_1::SessionType;
+// Stores the list of offload supported capability
+std::vector<LeAudioCodecCapabilitiesPair> kDefaultOffloadLeAudioCapabilities;
+
+static const LeAudioCodecCapability kInvalidLc3Capability = {
+ .codecType = CodecType::UNKNOWN};
+
+// Default Supported Codecs
+// LC3 16_1: sample rate: 16 kHz, frame duration: 7.5 ms, octets per frame: 30
+static const Lc3Parameters kLc3Capability_16_1 = {
+ .samplingFrequency = SampleRate::RATE_16000,
+ .frameDuration = Lc3FrameDuration::DURATION_7500US,
+ .octetsPerFrame = 30};
+
+// Default Supported Codecs
+// LC3 16_2: sample rate: 16 kHz, frame duration: 10 ms, octets per frame: 40
+static const Lc3Parameters kLc3Capability_16_2 = {
+ .samplingFrequency = SampleRate::RATE_16000,
+ .frameDuration = Lc3FrameDuration::DURATION_10000US,
+ .octetsPerFrame = 40};
+
+// Default Supported Codecs
+// LC3 48_4: sample rate: 48 kHz, frame duration: 10 ms, octets per frame: 120
+static const Lc3Parameters kLc3Capability_48_4 = {
+ .samplingFrequency = SampleRate::RATE_48000,
+ .frameDuration = Lc3FrameDuration::DURATION_10000US,
+ .octetsPerFrame = 120};
+
+static const std::vector<Lc3Parameters> supportedLc3CapabilityList = {
+ kLc3Capability_48_4, kLc3Capability_16_2, kLc3Capability_16_1};
+
+static AudioLocation stereoAudio = static_cast<AudioLocation>(
+ AudioLocation::FRONT_LEFT | AudioLocation::FRONT_RIGHT);
+static AudioLocation monoAudio = AudioLocation::UNKNOWN;
+
+// Stores the supported setting of audio location, connected device, and the
+// channel count for each device
+std::vector<std::tuple<AudioLocation, uint8_t, uint8_t>>
+ supportedDeviceSetting = {std::make_tuple(stereoAudio, 2, 1),
+ std::make_tuple(monoAudio, 1, 2),
+ std::make_tuple(monoAudio, 1, 1)};
+
bool IsOffloadLeAudioConfigurationValid(
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
session_type,
@@ -44,6 +94,60 @@
return true;
}
+LeAudioCodecCapability composeLc3Capability(AudioLocation audioLocation,
+ uint8_t deviceCnt,
+ uint8_t channelCount,
+ Lc3Parameters capability) {
+ return LeAudioCodecCapability{.codecType = CodecType::LC3,
+ .supportedChannel = audioLocation,
+ .deviceCount = deviceCnt,
+ .channelCountPerDevice = channelCount,
+ .capabilities = capability};
+}
+
+std::vector<LeAudioCodecCapabilitiesPair> GetLeAudioOffloadCodecCapabilities(
+ const SessionType_2_1& session_type) {
+ if (session_type !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
+ session_type !=
+ SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
+ return std::vector<LeAudioCodecCapabilitiesPair>(0);
+ }
+
+ if (kDefaultOffloadLeAudioCapabilities.empty()) {
+ for (auto [audioLocation, deviceCnt, channelCount] :
+ supportedDeviceSetting) {
+ for (auto capability : supportedLc3CapabilityList) {
+ LeAudioCodecCapability lc3Capability = composeLc3Capability(
+ audioLocation, deviceCnt, channelCount, capability);
+ LeAudioCodecCapability lc3MonoCapability =
+ composeLc3Capability(monoAudio, 1, 1, capability);
+
+ // Adds the capability for encode only
+ kDefaultOffloadLeAudioCapabilities.push_back(
+ {.mode = LeAudioMode::UNICAST,
+ .encodeCapability = lc3Capability,
+ .decodeCapability = kInvalidLc3Capability});
+
+ // Adds the capability for decode only
+ kDefaultOffloadLeAudioCapabilities.push_back(
+ {.mode = LeAudioMode::UNICAST,
+ .encodeCapability = kInvalidLc3Capability,
+ .decodeCapability = lc3Capability});
+
+ // Adds the capability for the case that encode and decode exist at the
+ // same time
+ kDefaultOffloadLeAudioCapabilities.push_back(
+ {.mode = LeAudioMode::UNICAST,
+ .encodeCapability = lc3Capability,
+ .decodeCapability = lc3MonoCapability});
+ }
+ }
+ }
+
+ return kDefaultOffloadLeAudioCapabilities;
+}
+
} // namespace audio
} // namespace bluetooth
} // namespace android
diff --git a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
index 8321616..89da6a3 100644
--- a/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
+++ b/bluetooth/audio/utils/session/BluetoothAudioSupportedCodecsDB_2_2.h
@@ -30,6 +30,11 @@
session_type,
const ::android::hardware::bluetooth::audio::V2_2::LeAudioConfiguration&
le_audio_codec_config);
+
+std::vector<hardware::bluetooth::audio::V2_2::LeAudioCodecCapabilitiesPair>
+GetLeAudioOffloadCodecCapabilities(
+ const ::android::hardware::bluetooth::audio::V2_1::SessionType&
+ session_type);
} // namespace audio
} // namespace bluetooth
} // namespace android
diff --git a/compatibility_matrices/compatibility_matrix.3.xml b/compatibility_matrices/compatibility_matrix.3.xml
index a75ed25..468735d 100644
--- a/compatibility_matrices/compatibility_matrix.3.xml
+++ b/compatibility_matrices/compatibility_matrix.3.xml
@@ -207,7 +207,10 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+ If the HIDL health HAL exists, it must be at least version 2.0.
+ See DeviceManifestTest.HealthHal -->
+ <hal format="hidl" optional="true">
<name>android.hardware.health</name>
<version>2.0</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.4.xml b/compatibility_matrices/compatibility_matrix.4.xml
index 3b8ee21..96f291f 100644
--- a/compatibility_matrices/compatibility_matrix.4.xml
+++ b/compatibility_matrices/compatibility_matrix.4.xml
@@ -213,7 +213,10 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+ If the HIDL health HAL exists, it must be at least version 2.0.
+ See DeviceManifestTest.HealthHal -->
+ <hal format="hidl" optional="true">
<name>android.hardware.health</name>
<version>2.0</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 0fb21a7..3642814 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -238,7 +238,10 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+ If the HIDL health HAL exists, it must be at least version 2.1.
+ See DeviceManifestTest.HealthHal -->
+ <hal format="hidl" optional="true">
<name>android.hardware.health</name>
<version>2.1</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.6.xml b/compatibility_matrices/compatibility_matrix.6.xml
index aee2c51..9c42cb0 100644
--- a/compatibility_matrices/compatibility_matrix.6.xml
+++ b/compatibility_matrices/compatibility_matrix.6.xml
@@ -268,7 +268,10 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="false">
+ <!-- Either the AIDL or the HIDL health HAL must exist on the device.
+ If the HIDL health HAL exists, it must be at least version 2.1.
+ See DeviceManifestTest.HealthHal -->
+ <hal format="hidl" optional="true">
<name>android.hardware.health</name>
<version>2.1</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 8a7804f..fcff6bc 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -299,9 +299,9 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="hidl" optional="true">
+ <hal format="aidl" optional="true">
<name>android.hardware.ir</name>
- <version>1.0</version>
+ <version>1</version>
<interface>
<name>IConsumerIr</name>
<instance>default</instance>
diff --git a/dumpstate/aidl/Android.bp b/dumpstate/aidl/Android.bp
index e18eade..22d836b 100644
--- a/dumpstate/aidl/Android.bp
+++ b/dumpstate/aidl/Android.bp
@@ -34,7 +34,6 @@
enabled: false,
},
ndk: {
- separate_platform_variant: false,
vndk: {
enabled: true,
},
diff --git a/health/aidl/Android.bp b/health/aidl/Android.bp
index 6e2f1d4..22bb4fa 100644
--- a/health/aidl/Android.bp
+++ b/health/aidl/Android.bp
@@ -37,7 +37,6 @@
sdk_version: "module_current",
},
ndk: {
- separate_platform_variant: false,
vndk: {
enabled: true,
},
diff --git a/health/aidl/vts/functional/Android.bp b/health/aidl/vts/functional/Android.bp
index 434f565..d315c60 100644
--- a/health/aidl/vts/functional/Android.bp
+++ b/health/aidl/vts/functional/Android.bp
@@ -43,6 +43,7 @@
"libhealthtest_headers",
],
test_suites: [
+ "general-tests",
"vts",
],
}
diff --git a/ir/OWNERS b/ir/OWNERS
new file mode 100644
index 0000000..04de9ef
--- /dev/null
+++ b/ir/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 163905
+connoro@google.com
diff --git a/ir/aidl/Android.bp b/ir/aidl/Android.bp
new file mode 100644
index 0000000..6dacb85
--- /dev/null
+++ b/ir/aidl/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+aidl_interface {
+ name: "android.hardware.ir",
+ vendor_available: true,
+ srcs: ["android/hardware/ir/*.aidl"],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: false,
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ ndk: {
+ vndk: {
+ // TODO(b/206116595) enable this
+ enabled: false,
+ },
+ },
+ },
+}
diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl
new file mode 100644
index 0000000..4a0d286
--- /dev/null
+++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/ConsumerIrFreqRange.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.ir;
+@VintfStability
+parcelable ConsumerIrFreqRange {
+ int minHz;
+ int maxHz;
+}
diff --git a/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
new file mode 100644
index 0000000..056a8b1
--- /dev/null
+++ b/ir/aidl/aidl_api/android.hardware.ir/current/android/hardware/ir/IConsumerIr.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.ir;
+@VintfStability
+interface IConsumerIr {
+ android.hardware.ir.ConsumerIrFreqRange[] getCarrierFreqs();
+ void transmit(in int carrierFreq, in int[] pattern);
+}
diff --git a/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl b/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl
new file mode 100644
index 0000000..ab0276a
--- /dev/null
+++ b/ir/aidl/android/hardware/ir/ConsumerIrFreqRange.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.ir;
+
+@VintfStability
+parcelable ConsumerIrFreqRange {
+ int minHz;
+ int maxHz;
+}
diff --git a/ir/aidl/android/hardware/ir/IConsumerIr.aidl b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
new file mode 100644
index 0000000..d14fa56
--- /dev/null
+++ b/ir/aidl/android/hardware/ir/IConsumerIr.aidl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.ir;
+
+import android.hardware.ir.ConsumerIrFreqRange;
+
+@VintfStability
+interface IConsumerIr {
+ /**
+ * Enumerates which frequencies the IR transmitter supports.
+ *
+ * Status OK (EX_NONE) on success.
+ *
+ * @return - an array of all supported frequency ranges.
+ */
+ ConsumerIrFreqRange[] getCarrierFreqs();
+
+ /**
+ * Sends an IR pattern at a given frequency in HZ.
+ *
+ * The pattern is alternating series of carrier on and off periods measured in
+ * microseconds. The carrier should be turned off at the end of a transmit
+ * even if there are and odd number of entries in the pattern array.
+ *
+ * This call must return when the transmit is complete or encounters an error.
+ *
+ * Status OK (EX_NONE) on success.
+ * EX_UNSUPPORTED_OPERATION when the frequency is not supported.
+ */
+ void transmit(in int carrierFreq, in int[] pattern);
+}
diff --git a/ir/aidl/default/Android.bp b/ir/aidl/default/Android.bp
new file mode 100644
index 0000000..6519664
--- /dev/null
+++ b/ir/aidl/default/Android.bp
@@ -0,0 +1,33 @@
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Example binder service of the ir HAL.
+cc_binary {
+ name: "android.hardware.ir-service.example",
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.ir-service.example.rc"],
+ vendor: true,
+ vintf_fragments: ["android.hardware.ir-service.example.xml"],
+
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "android.hardware.ir-V1-ndk",
+ ],
+
+ srcs: ["main.cpp"],
+}
diff --git a/ir/aidl/default/android.hardware.ir-service.example.rc b/ir/aidl/default/android.hardware.ir-service.example.rc
new file mode 100644
index 0000000..56def64
--- /dev/null
+++ b/ir/aidl/default/android.hardware.ir-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.ir-default /vendor/bin/hw/android.hardware.ir-service.example
+ class hal
+ user nobody
+ group nobody
diff --git a/ir/aidl/default/android.hardware.ir-service.example.xml b/ir/aidl/default/android.hardware.ir-service.example.xml
new file mode 100644
index 0000000..1a63520
--- /dev/null
+++ b/ir/aidl/default/android.hardware.ir-service.example.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.ir</name>
+ <version>1</version>
+ <fqname>IConsumerIr/default</fqname>
+ </hal>
+</manifest>
diff --git a/ir/aidl/default/main.cpp b/ir/aidl/default/main.cpp
new file mode 100644
index 0000000..764aeaf
--- /dev/null
+++ b/ir/aidl/default/main.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/ir/BnConsumerIr.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <numeric>
+
+namespace aidl::android::hardware::ir {
+
+const std::vector<ConsumerIrFreqRange> kSupportedFreqs = {
+ {2000, 4000},
+ {10000, 30000},
+};
+
+class ConsumerIr : public BnConsumerIr {
+ ::ndk::ScopedAStatus getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) override;
+ ::ndk::ScopedAStatus transmit(int32_t in_carrierFreq,
+ const std::vector<int32_t>& in_pattern) override;
+};
+
+::ndk::ScopedAStatus ConsumerIr::getCarrierFreqs(std::vector<ConsumerIrFreqRange>* _aidl_return) {
+ *_aidl_return = kSupportedFreqs;
+ return ::ndk::ScopedAStatus::ok();
+}
+
+bool isSupportedFreq(int32_t freq) {
+ for (const auto& range : kSupportedFreqs) {
+ if (freq >= range.minHz && freq <= range.maxHz) return true;
+ }
+ return false;
+}
+
+::ndk::ScopedAStatus ConsumerIr::transmit(int32_t in_carrierFreq,
+ const std::vector<int32_t>& in_pattern) {
+ if (isSupportedFreq(in_carrierFreq)) {
+ // trasmit the pattern, each integer is number of microseconds in an
+ // alternating on/off state.
+ usleep(std::accumulate(in_pattern.begin(), in_pattern.end(), 0));
+ return ::ndk::ScopedAStatus::ok();
+ } else {
+ // unsupported operation
+ return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+ }
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::ir
+
+using aidl::android::hardware::ir::ConsumerIr;
+
+int main() {
+ auto binder = ::ndk::SharedRefBase::make<ConsumerIr>();
+ const std::string name = std::string() + ConsumerIr::descriptor + "/default";
+ CHECK_EQ(STATUS_OK, AServiceManager_addService(binder->asBinder().get(), name.c_str()))
+ << "Failed to register " << name;
+
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+ ABinderProcess_joinThreadPool();
+
+ return EXIT_FAILURE; // should not reached
+}
diff --git a/ir/aidl/vts/Android.bp b/ir/aidl/vts/Android.bp
new file mode 100644
index 0000000..c2491b8
--- /dev/null
+++ b/ir/aidl/vts/Android.bp
@@ -0,0 +1,43 @@
+//
+// Copyright (C) 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalIrTargetTest",
+ defaults: [
+ "VtsHalTargetTestDefaults",
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalIrTargetTest.cpp"],
+ shared_libs: [
+ "libbinder_ndk",
+ ],
+ static_libs: [
+ "android.hardware.ir-V1-ndk",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+}
diff --git a/ir/aidl/vts/VtsHalIrTargetTest.cpp b/ir/aidl/vts/VtsHalIrTargetTest.cpp
new file mode 100644
index 0000000..3527625
--- /dev/null
+++ b/ir/aidl/vts/VtsHalIrTargetTest.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ir_aidl_hal_test"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/ir/IConsumerIr.h>
+#include <android-base/logging.h>
+#include <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <algorithm>
+#include <vector>
+
+using ::aidl::android::hardware::ir::ConsumerIrFreqRange;
+using ::aidl::android::hardware::ir::IConsumerIr;
+using ::ndk::SpAIBinder;
+
+class ConsumerIrTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ mIr = IConsumerIr::fromBinder(
+ SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(mIr, nullptr);
+ }
+
+ std::shared_ptr<IConsumerIr> mIr;
+};
+
+// Test transmit() for the min and max frequency of every available range
+TEST_P(ConsumerIrTest, TransmitTest) {
+ std::vector<ConsumerIrFreqRange> ranges;
+ const auto& ret = mIr->getCarrierFreqs(&ranges);
+ ASSERT_TRUE(ret.isOk());
+
+ if (ranges.size() > 0) {
+ uint32_t len = 16;
+ std::vector<int32_t> vec;
+ vec.resize(len);
+ std::fill(vec.begin(), vec.end(), 1000);
+ for (auto range = ranges.begin(); range != ranges.end(); range++) {
+ EXPECT_TRUE(mIr->transmit(range->minHz, vec).isOk());
+ EXPECT_TRUE(mIr->transmit(range->maxHz, vec).isOk());
+ }
+ }
+}
+
+// Test transmit() when called with invalid frequencies
+TEST_P(ConsumerIrTest, BadFreqTest) {
+ uint32_t len = 16;
+ std::vector<int32_t> vec;
+ vec.resize(len);
+ std::fill(vec.begin(), vec.end(), 1);
+ const auto& res = mIr->transmit(-1, vec);
+ EXPECT_FALSE(res.isOk());
+ EXPECT_EQ(res.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ConsumerIrTest);
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, ConsumerIrTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(IConsumerIr::descriptor)),
+ ::android::PrintInstanceNameToString);
diff --git a/memtrack/OWNERS b/memtrack/OWNERS
new file mode 100644
index 0000000..a182ed9
--- /dev/null
+++ b/memtrack/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 30545
+connoro@google.com
diff --git a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
index e2fa6e4..af3641a 100644
--- a/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/1.3/vts/functional/MemoryDomainTests.cpp
@@ -1158,12 +1158,15 @@
auto [buffer, token] = allocateBuffer(preparedModel, {0}, {0}, kTestOperand.dimensions);
if (buffer == nullptr) return;
- Request::MemoryPool sharedMemory = createSharedMemoryPool(kTestOperandDataSize);
- Request::MemoryPool deviceMemory = createDeviceMemoryPool(token);
+ // Use an incompatible dimension and make sure the length matches with the bad dimension.
auto badDimensions = kTestOperand.dimensions;
badDimensions[0] = 2;
+ const uint32_t badTestOperandDataSize = kTestOperandDataSize * 2;
+
+ Request::MemoryPool sharedMemory = createSharedMemoryPool(badTestOperandDataSize);
+ Request::MemoryPool deviceMemory = createDeviceMemoryPool(token);
RequestArgument sharedMemoryArg = {
- .location = {.poolIndex = 0, .offset = 0, .length = kTestOperandDataSize},
+ .location = {.poolIndex = 0, .offset = 0, .length = badTestOperandDataSize},
.dimensions = badDimensions};
RequestArgument deviceMemoryArg = {.location = {.poolIndex = 1}};
RequestArgument deviceMemoryArgWithBadDimensions = {.location = {.poolIndex = 1},
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
index cfcd42c..3342619 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/DataProfileInfo.aidl
@@ -52,6 +52,8 @@
int mtuV6;
boolean preferred;
boolean persistent;
+ boolean alwaysOn;
+ @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor;
const int ID_DEFAULT = 0;
const int ID_TETHERED = 1;
const int ID_IMS = 2;
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
index a648675..dc6092a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioData.aidl
@@ -46,7 +46,7 @@
oneway void setDataThrottling(in int serial, in android.hardware.radio.data.DataThrottlingAction dataThrottlingAction, in long completionDurationMillis);
oneway void setInitialAttachApn(in int serial, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
oneway void setResponseFunctions(in android.hardware.radio.data.IRadioDataResponse radioDataResponse, in android.hardware.radio.data.IRadioDataIndication radioDataIndication);
- oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in @nullable android.hardware.radio.data.TrafficDescriptor trafficDescriptor, in boolean matchAllRuleAllowed);
+ oneway void setupDataCall(in int serial, in android.hardware.radio.AccessNetwork accessNetwork, in android.hardware.radio.data.DataProfileInfo dataProfileInfo, in boolean roamingAllowed, in android.hardware.radio.data.DataRequestReason reason, in android.hardware.radio.data.LinkAddress[] addresses, in String[] dnses, in int pduSessionId, in @nullable android.hardware.radio.data.SliceInfo sliceInfo, in boolean matchAllRuleAllowed);
oneway void startHandover(in int serial, in int callId);
oneway void startKeepalive(in int serial, in android.hardware.radio.data.KeepaliveRequest keepalive);
oneway void stopKeepalive(in int serial, in int sessionHandle);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
index e496c7b..b0cc1eb 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.data/current/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -37,5 +37,5 @@
oneway void dataCallListChanged(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.SetupDataCallResult[] dcList);
oneway void keepaliveStatus(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.KeepaliveStatus status);
oneway void pcoData(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.PcoDataInfo pco);
- oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in String apn);
+ oneway void unthrottleApn(in android.hardware.radio.RadioIndicationType type, in android.hardware.radio.data.DataProfileInfo dataProfileInfo);
}
diff --git a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
index a1c3c27..b5cf633 100644
--- a/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
+++ b/radio/aidl/android/hardware/radio/config/SimSlotStatus.aidl
@@ -42,7 +42,13 @@
*/
String eid;
/**
- * PortInfo contains the ICCID, logical slot ID, and port state
+ * PortInfo contains the ICCID, logical slot ID, and port state.
+ * Cardstate has no relationship with whether the slot is active or inactive. Should always
+ * report up at least 1 port otherwise the logicalSlotIndex and portActive info will be lost.
+ * For example, the pSIM can be removed, but the slot can still be active. In that case, the
+ * SIM_STATUS reported for the corresponding logical stack will show CARDSTATE_ABSENT.
+ * Similarly, even if there is no profile enabled on the eSIM, that port can still be the
+ * active port in the slot mapping.
*/
SimPortInfo[] portInfo;
}
diff --git a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
index 7657fc9..0f06119 100644
--- a/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
+++ b/radio/aidl/android/hardware/radio/data/DataProfileInfo.aidl
@@ -20,6 +20,7 @@
import android.hardware.radio.data.ApnAuthType;
import android.hardware.radio.data.ApnTypes;
import android.hardware.radio.data.PdpProtocolType;
+import android.hardware.radio.data.TrafficDescriptor;
@VintfStability
parcelable DataProfileInfo {
@@ -115,4 +116,19 @@
* If the same data profile exists, this data profile must overwrite it.
*/
boolean persistent;
+ /**
+ * Indicates the PDU session brought up by this data profile should be always-on.
+ * An always-on PDU Session is a PDU Session for which User Plane resources have to be
+ * activated during every transition from CM-IDLE mode to CM-CONNECTED state.
+ * See 3GPP TS 23.501 section 5.6.13 for the details.
+ */
+ boolean alwaysOn;
+ /**
+ * TrafficDescriptor for which data connection needs to be established.
+ * It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2.
+ * It includes an optional DNN which, if present, must be used for traffic matching --
+ * it does not specify the end point to be used for the data call. The end point is specified by
+ * apn; apn must be used as the end point if one is not specified through URSP rules.
+ */
+ @nullable TrafficDescriptor trafficDescriptor;
}
diff --git a/radio/aidl/android/hardware/radio/data/IRadioData.aidl b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
index 9f5ba4c..54a045c 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioData.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioData.aidl
@@ -219,12 +219,6 @@
* EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice
* passed from EPDG is rejected, then the data failure cause must be
* DataCallFailCause:SLICE_REJECTED.
- * @param trafficDescriptor TrafficDescriptor for which data connection needs to be established.
- * It is used for URSP traffic matching as described in TS 24.526 Section 4.2.2.
- * It includes an optional DNN which, if present, must be used for traffic matching --
- * it does not specify the end point to be used for the data call. The end point is
- * specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end point if
- * one is not specified through URSP rules.
* @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this
* request is allowed. If false, this request must not use the match-all URSP rule and if
* a non-match-all rule is not found (or if URSP rules are not available) it should
@@ -238,7 +232,6 @@
in DataProfileInfo dataProfileInfo, in boolean roamingAllowed,
in DataRequestReason reason, in LinkAddress[] addresses, in String[] dnses,
in int pduSessionId, in @nullable SliceInfo sliceInfo,
- in @nullable TrafficDescriptor trafficDescriptor,
in boolean matchAllRuleAllowed);
/**
diff --git a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
index 8e73ee3..1772c88 100644
--- a/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
+++ b/radio/aidl/android/hardware/radio/data/IRadioDataIndication.aidl
@@ -17,6 +17,7 @@
package android.hardware.radio.data;
import android.hardware.radio.RadioIndicationType;
+import android.hardware.radio.data.DataProfileInfo;
import android.hardware.radio.data.KeepaliveStatus;
import android.hardware.radio.data.PcoDataInfo;
import android.hardware.radio.data.SetupDataCallResult;
@@ -68,7 +69,7 @@
* is sent, AOSP will no longer throttle calls to IRadioData.SetupDataCall for the given APN.
*
* @param type Type of radio indication
- * @param apn Apn to unthrottle
+ * @param dataProfileInfo Data profile info.
*/
- void unthrottleApn(in RadioIndicationType type, in String apn);
+ void unthrottleApn(in RadioIndicationType type, in DataProfileInfo dataProfileInfo);
}
diff --git a/radio/aidl/compat/libradiocompat/Android.bp b/radio/aidl/compat/libradiocompat/Android.bp
index 43d9378..5294de4 100644
--- a/radio/aidl/compat/libradiocompat/Android.bp
+++ b/radio/aidl/compat/libradiocompat/Android.bp
@@ -56,7 +56,9 @@
"libutils",
],
srcs: [
+ "DriverContext.cpp",
"RadioCompatBase.cpp",
+ "RadioIndication.cpp",
"RadioResponse.cpp",
"commonStructs.cpp",
"config/RadioConfig.cpp",
diff --git a/radio/aidl/compat/libradiocompat/DriverContext.cpp b/radio/aidl/compat/libradiocompat/DriverContext.cpp
new file mode 100644
index 0000000..a07173e
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/DriverContext.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/DriverContext.h>
+
+namespace android::hardware::radio::compat {
+
+namespace aidl = ::aidl::android::hardware::radio;
+
+void DriverContext::addDataProfile(const aidl::data::DataProfileInfo& profile) {
+ mDataProfiles[profile.apn] = profile;
+}
+
+aidl::data::DataProfileInfo DriverContext::getDataProfile(const std::string& apn) {
+ const auto it = mDataProfiles.find(apn);
+ if (it != mDataProfiles.end()) return it->second;
+
+ // if not found in cache, return a made up default
+ return {
+ .apn = apn,
+ };
+}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
index a9eac68..dba6c19 100644
--- a/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
+++ b/radio/aidl/compat/libradiocompat/RadioCompatBase.cpp
@@ -20,12 +20,13 @@
namespace android::hardware::radio::compat {
-RadioCompatBase::RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
- sp<RadioIndication> radioIndication)
- : mHal1_5(hidlHal),
+RadioCompatBase::RadioCompatBase(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal,
+ sp<RadioResponse> radioResponse, sp<RadioIndication> radioInd)
+ : mContext(context),
+ mHal1_5(hidlHal),
mHal1_6(V1_6::IRadio::castFrom(hidlHal)),
mRadioResponse(radioResponse),
- mRadioIndication(radioIndication) {}
+ mRadioIndication(radioInd) {}
V1_6::IRadioResponse& RadioCompatBase::respond() {
CHECK(mRadioResponse) << "This shouldn't happen (response functions are passed in constructor)";
diff --git a/radio/aidl/compat/libradiocompat/RadioIndication.cpp b/radio/aidl/compat/libradiocompat/RadioIndication.cpp
new file mode 100644
index 0000000..30ef6a0
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/RadioIndication.cpp
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libradiocompat/RadioIndication.h>
+
+namespace android::hardware::radio::compat {
+
+RadioIndication::RadioIndication(std::shared_ptr<DriverContext> context) : mContext(context) {}
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/RadioResponse.cpp b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
index 35b0ac1..e1bd446 100644
--- a/radio/aidl/compat/libradiocompat/RadioResponse.cpp
+++ b/radio/aidl/compat/libradiocompat/RadioResponse.cpp
@@ -22,6 +22,8 @@
namespace android::hardware::radio::compat {
+RadioResponse::RadioResponse(std::shared_ptr<DriverContext> context) : mContext(context) {}
+
Return<void> RadioResponse::acknowledgeRequest(int32_t serial) {
LOG_CALL << serial;
// TODO(b/203699028): send to correct requestor or confirm if spam is not a problem
diff --git a/radio/aidl/compat/libradiocompat/data/RadioData.cpp b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
index fdb1273..cc6f526 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioData.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioData.cpp
@@ -139,14 +139,15 @@
const aidl::DataProfileInfo& dataProfileInfo, bool roamingAllowed,
aidl::DataRequestReason reason, const std::vector<aidl::LinkAddress>& addresses,
const std::vector<std::string>& dnses, int32_t pduSessId,
- const std::optional<aidl::SliceInfo>& sliceInfo,
- const std::optional<aidl::TrafficDescriptor>& trDesc, bool matchAllRuleAllowed) {
+ const std::optional<aidl::SliceInfo>& sliceInfo, bool matchAllRuleAllowed) {
if (mHal1_6) {
mHal1_6->setupDataCall_1_6( //
serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
V1_2::DataRequestReason(reason), toHidl(addresses), toHidl(dnses), pduSessId,
toHidl<V1_6::OptionalSliceInfo>(sliceInfo),
- toHidl<V1_6::OptionalTrafficDescriptor>(trDesc), matchAllRuleAllowed);
+ toHidl<V1_6::OptionalTrafficDescriptor>(dataProfileInfo.trafficDescriptor),
+ matchAllRuleAllowed);
+ mContext->addDataProfile(dataProfileInfo);
} else {
mHal1_5->setupDataCall_1_5( //
serial, V1_5::AccessNetwork(accessNetwork), toHidl(dataProfileInfo), roamingAllowed,
diff --git a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
index f51d1a8..a680e56 100644
--- a/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
+++ b/radio/aidl/compat/libradiocompat/data/RadioIndication-data.cpp
@@ -83,7 +83,7 @@
const hidl_string& apn) {
LOG_CALL << type;
CHECK_CB(mDataCb);
- mDataCb->unthrottleApn(toAidl(type), apn);
+ mDataCb->unthrottleApn(toAidl(type), mContext->getDataProfile(apn));
return {};
}
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h
new file mode 100644
index 0000000..6833aca
--- /dev/null
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/DriverContext.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <aidl/android/hardware/radio/data/DataProfileInfo.h>
+
+#include <map>
+
+namespace android::hardware::radio::compat {
+
+class DriverContext {
+ std::map<std::string, ::aidl::android::hardware::radio::data::DataProfileInfo> mDataProfiles;
+
+ public:
+ void addDataProfile(const ::aidl::android::hardware::radio::data::DataProfileInfo& profile);
+ ::aidl::android::hardware::radio::data::DataProfileInfo getDataProfile(const std::string& apn);
+};
+
+} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
index a412c34..21d7898 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioCompatBase.h
@@ -15,6 +15,7 @@
*/
#pragma once
+#include "DriverContext.h"
#include "RadioIndication.h"
#include "RadioResponse.h"
@@ -24,6 +25,8 @@
class RadioCompatBase {
protected:
+ std::shared_ptr<DriverContext> mContext;
+
sp<V1_5::IRadio> mHal1_5;
sp<V1_6::IRadio> mHal1_6;
@@ -33,8 +36,8 @@
V1_6::IRadioResponse& respond();
public:
- RadioCompatBase(sp<V1_5::IRadio> hidlHal, sp<RadioResponse> radioResponse,
- sp<RadioIndication> radioIndication);
+ RadioCompatBase(std::shared_ptr<DriverContext> context, sp<V1_5::IRadio> hidlHal,
+ sp<RadioResponse> radioResponse, sp<RadioIndication> radioIndication);
};
} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
index 900a669..ba8bb0a 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioData.h
@@ -55,7 +55,6 @@
const std::vector<::aidl::android::hardware::radio::data::LinkAddress>& addresses,
const std::vector<std::string>& dnses, int32_t pduSessionId,
const std::optional<::aidl::android::hardware::radio::data::SliceInfo>& sliceInfo,
- const std::optional<::aidl::android::hardware::radio::data::TrafficDescriptor>& trDescr,
bool matchAllRuleAllowed) override;
::ndk::ScopedAStatus startHandover(int32_t serial, int32_t callId) override;
::ndk::ScopedAStatus startKeepalive(
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
index 20e0973..4d03063 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioIndication.h
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "DriverContext.h"
+
#include <aidl/android/hardware/radio/data/IRadioDataIndication.h>
#include <aidl/android/hardware/radio/messaging/IRadioMessagingIndication.h>
#include <aidl/android/hardware/radio/modem/IRadioModemIndication.h>
@@ -26,6 +28,8 @@
namespace android::hardware::radio::compat {
class RadioIndication : public V1_6::IRadioIndication {
+ std::shared_ptr<DriverContext> mContext;
+
std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> mDataCb;
std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingIndication>
mMessagingCb;
@@ -181,6 +185,8 @@
const hidl_vec<V1_6::PhonebookRecordInfo>& records) override;
public:
+ RadioIndication(std::shared_ptr<DriverContext> context);
+
void setResponseFunction(
std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataIndication> dataCb);
void setResponseFunction(
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
index 5db963f..344864f 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioResponse.h
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "DriverContext.h"
+
#include <aidl/android/hardware/radio/data/IRadioDataResponse.h>
#include <aidl/android/hardware/radio/messaging/IRadioMessagingResponse.h>
#include <aidl/android/hardware/radio/modem/IRadioModemResponse.h>
@@ -26,6 +28,8 @@
namespace android::hardware::radio::compat {
class RadioResponse : public V1_6::IRadioResponse {
+ std::shared_ptr<DriverContext> mContext;
+
std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> mDataCb;
std::shared_ptr<::aidl::android::hardware::radio::messaging::IRadioMessagingResponse>
mMessagingCb;
@@ -409,6 +413,8 @@
int32_t updatedRecordIndex) override;
public:
+ RadioResponse(std::shared_ptr<DriverContext> context);
+
void setResponseFunction(
std::shared_ptr<::aidl::android::hardware::radio::data::IRadioDataResponse> dataCb);
void setResponseFunction(
diff --git a/radio/aidl/compat/service/service.cpp b/radio/aidl/compat/service/service.cpp
index 2a67569..6bcd4b0 100644
--- a/radio/aidl/compat/service/service.cpp
+++ b/radio/aidl/compat/service/service.cpp
@@ -36,7 +36,8 @@
static std::vector<std::shared_ptr<ndk::ICInterface>> gPublishedHals;
template <typename T>
-static void publishRadioHal(sp<V1_5::IRadio> hidlHal, sp<compat::RadioResponse> responseCb,
+static void publishRadioHal(std::shared_ptr<compat::DriverContext> context,
+ sp<V1_5::IRadio> hidlHal, sp<compat::RadioResponse> responseCb,
sp<compat::RadioIndication> indicationCb, const std::string& slot) {
const auto instance = T::descriptor + "/"s + slot;
if (!AServiceManager_isDeclared(instance.c_str())) {
@@ -45,7 +46,7 @@
}
LOG(DEBUG) << "Publishing " << instance;
- auto aidlHal = ndk::SharedRefBase::make<T>(hidlHal, responseCb, indicationCb);
+ auto aidlHal = ndk::SharedRefBase::make<T>(context, hidlHal, responseCb, indicationCb);
gPublishedHals.push_back(aidlHal);
const auto status = AServiceManager_addService(aidlHal->asBinder().get(), instance.c_str());
CHECK_EQ(status, STATUS_OK);
@@ -57,16 +58,18 @@
hidl_utils::linkDeathToDeath(radioHidl);
- auto responseCb = sp<compat::RadioResponse>::make();
- auto indicationCb = sp<compat::RadioIndication>::make();
+ auto context = std::make_shared<compat::DriverContext>();
+
+ auto responseCb = sp<compat::RadioResponse>::make(context);
+ auto indicationCb = sp<compat::RadioIndication>::make(context);
radioHidl->setResponseFunctions(responseCb, indicationCb).assertOk();
- publishRadioHal<compat::RadioData>(radioHidl, responseCb, indicationCb, slot);
- publishRadioHal<compat::RadioMessaging>(radioHidl, responseCb, indicationCb, slot);
- publishRadioHal<compat::RadioModem>(radioHidl, responseCb, indicationCb, slot);
- publishRadioHal<compat::RadioNetwork>(radioHidl, responseCb, indicationCb, slot);
- publishRadioHal<compat::RadioSim>(radioHidl, responseCb, indicationCb, slot);
- publishRadioHal<compat::RadioVoice>(radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioData>(context, radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioMessaging>(context, radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioModem>(context, radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioNetwork>(context, radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioSim>(context, radioHidl, responseCb, indicationCb, slot);
+ publishRadioHal<compat::RadioVoice>(context, radioHidl, responseCb, indicationCb, slot);
}
static void publishRadioConfig() {