Merge "audio: add IAMF formats to schema" into main
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/State.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/State.aidl
index 17f9814..873fb43 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/State.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/State.aidl
@@ -37,4 +37,5 @@
INIT,
IDLE,
PROCESSING,
+ DRAINING,
}
diff --git a/audio/aidl/android/hardware/audio/effect/CommandId.aidl b/audio/aidl/android/hardware/audio/effect/CommandId.aidl
index d940b42..de573bf 100644
--- a/audio/aidl/android/hardware/audio/effect/CommandId.aidl
+++ b/audio/aidl/android/hardware/audio/effect/CommandId.aidl
@@ -33,25 +33,39 @@
/**
* Start effect engine processing.
* An effect instance must start processing data and transfer to PROCESSING state if it is in
- * IDLE state and have all necessary information. Otherwise it must:
- * 1. Throw a EX_ILLEGAL_STATE exception if effect is not in IDLE state, or
- * 2. Throw a EX_TRANSACTION_FAILED for all other errors.
+ * IDLE or DRAINING state and has all necessary information. Otherwise, it must:
+ * 1. Throw an EX_ILLEGAL_STATE exception if the effect is not in IDLE or DRAINING state, or
+ * 2. Throw an EX_TRANSACTION_FAILED for all other errors.
*
- * Depending on parameters set to the effect instance, effect may do process or reverse
- * process after START command.
+ * If an effect instance in DRAINING state receives a START command, it must transit back to
+ * PROCESSING state.
*/
START = 0,
/**
- * Stop effect engine processing with all resource kept.
- * The currently processed audio data will be discarded if the effect engine is in PROCESSING
- * state.
- * Effect instance must do nothing and return ok when it receive STOP command in IDLE state.
+ * Stop effect engine processing with all resources kept.
+ * If the effect is in **PROCESSING** state:
+ * - It must transition to **IDLE** state if no intermediate operations are required.
+ * - It must transition to **DRAINING** state if draining (e.g., fading) is required.
+ * - The instance must automatically transition to **IDLE** after draining.
+ * - It must ignore any new `STOP` commands during **DRAINING**.
+ * - `START` commands during **DRAINING** must transition the instance back to
+ * **PROCESSING**.
+ * If the effect instance is already in **IDLE** state, it must do nothing and return success.
+ *
+ * If the effect instance transitions to DRAINING state:
+ * 1. It must automatically transition to IDLE after completing draining tasks.
+ * 2. It must ignore any new STOP commands received during the DRAINING state.
+ * 3. START commands during DRAINING must immediately transfer the instance back to PROCESSING.
+ *
*/
STOP = 1,
/**
* Keep all parameter settings but reset the buffer content, stop engine processing, and transit
- * instance state to IDLE if its in PROCESSING state.
+ * the instance state to IDLE if it is in PROCESSING state.
* Effect instance must be able to handle RESET command at IDLE and PROCESSING states.
+ *
+ * If the implementation includes intermediate operations such as draining, the RESET command
+ * must bypass DRAINING and immediately transition the state to IDLE.
*/
RESET = 2,
diff --git a/audio/aidl/android/hardware/audio/effect/State.aidl b/audio/aidl/android/hardware/audio/effect/State.aidl
index 85a4afc..1b698d7 100644
--- a/audio/aidl/android/hardware/audio/effect/State.aidl
+++ b/audio/aidl/android/hardware/audio/effect/State.aidl
@@ -24,18 +24,18 @@
* it should transfer to IDLE state after handle the command successfully. Effect instance should
* consume minimal resource and transfer to INIT state after it was close().
*
- * Refer to State.gv for detailed state diagram.
+ * Refer to the state machine diagram `state.gv` for a detailed state diagram.
*/
@VintfStability
@Backing(type="byte")
enum State {
-
/**
* An effect instance is in INIT state by default after it was created with
* IFactory.createEffect(). When an effect instance is in INIT state, it should have instance
* context initialized, and ready to handle IEffect.setParameter(), IEffect.open() as well as
* all getter interfaces.
*
+ * **Requirements in INIT state:**
* In INIT state, effect instance must:
* 1. Not handle any IEffect.command() and return EX_ILLEGAL_STATE with any Command.Id.
* 2. Be able to handle all parameter setting with IEffect.setParameter().
@@ -43,28 +43,32 @@
* IEffect.getState().
* 4. Be able to handle IEffect.open() successfully after configuration.
*
- * Client is expected to do necessary configuration with IEffect.setParameter(), get all
- * resource ready with IEffect.open(), and make sure effect instance transfer to IDLE state
- * before sending commands with IEffect.command() interface. Effect instance must transfer
- * from INIT to IDLE state after handle IEffect.open() call successfully.
+ * **State Transitions:**
+ * - Transitions to **IDLE** after successful `IEffect.open()`.
+ * - Remains in **INIT** on `IEffect.getState()` and `IEffect.getDescriptor()`.
+ * - Transitions to the final state on `IFactory.destroyEffect()`.
*/
INIT,
+
/**
* An effect instance transfer to IDLE state after it was open successfully with IEffect.open()
* in INIT state, or after it was stop/reset with Command.Id.STOP/RESET in PROCESSING state.
*
- * In IDLE state, effect instance must:
+ * **Requirements in IDLE state:**
* 1. Be able to start effect processing engine with IEffect.command(Command.Id.START) call.
* 2. Be able to handle all parameter setting with IEffect.setParameter().
* 3. Be able to handle all getter interface calls like IEffect.getParameter() and
* IEffect.getState().
*
- * The following state transfer can happen in IDLE state:
- * 1. Transfer to PROCESSING if instance receive an START command and start processing data
- * successfully.
- * 2. Transfer to INIT if instance receive a close() call.
+ * **State Transitions:**
+ * - Transitions to **PROCESSING** on `IEffect.command(CommandId.START)` after starting
+ * processing data successfully.
+ * - Transitions to **INIT** on `IEffect.close()`.
+ * - Remains in **IDLE** on `IEffect.getParameter()`, `IEffect.setParameter()`,
+ * `IEffect.getDescriptor()`, `IEffect.command(CommandId.RESET)`, and `IEffect.reopen()`.
*/
IDLE,
+
/**
* An effect instance is in PROCESSING state after it receive an START command and start
* processing data successfully. Effect instance will transfer from PROCESSING to IDLE state if
@@ -75,12 +79,50 @@
* the case of a close() call received when instance in PROCESSING state, it should try to stop
* processing and transfer to IDLE first before close().
*
- * In PROCESSING state, effect instance must:
+ * **Requirements in PROCESSING state:**
* 1. Return EX_ILLEGAL_STATE if it's not able to handle any parameter settings at runtime.
* 2. Be able to handle STOP and RESET for IEffect.command() interface, and return
* EX_ILLEGAL_STATE for all other commands.
* 3. Must be able to handle all get* interface calls like IEffect.getParameter() and
* IEffect.getState().
+ *
+ * **State Transitions:**
+ * - Transitions to **IDLE** on `IEffect.command(CommandId.STOP)` ( if no draining is required
+ * or implemented) or `IEffect.command(CommandId.RESET)`.
+ * - Transitions to **DRAINING** on `IEffect.command(CommandId.STOP)` if draining is required.
+ * - Remains in **PROCESSING** on `IEffect.getParameter()`, `IEffect.setParameter()`,
+ * `IEffect.getDescriptor()`, and `IEffect.reopen()`.
+ *
+ * **Notes:**
+ * - Clients should avoid calling `IEffect.close()` directly in this state; instead, they should
+ * stop processing with `CommandId.STOP` before closing.
+ * - If `IEffect.close()` is called in this state, the effect instance should stop processing,
+ * transition to **IDLE**, and then close.
*/
PROCESSING,
+
+ /**
+ * DRAINING is an optional transitional state where the effect instance completes processing
+ * remaining input buffers or finalizes operations (e.g., fading) before stopping completely.
+ * This state is typically entered after a `CommandId.STOP` command in the PROCESSING state when
+ * draining is required.
+ *
+ * **Requirements in DRAINING state:**
+ * 1. Must handle `CommandId.START` and transition back to **PROCESSING**.
+ * 2. Must handle getter interface calls like `IEffect.getParameter()` and `IEffect.getState()`.
+ * 3. Must automatically transition to **IDLE** after draining is complete.
+ *
+ * **State Transitions:**
+ * - Transitions to **PROCESSING** on `IEffect.command(CommandId.START)`.
+ * - Transitions to **IDLE** on `IEffect.command(CommandId.RESET)`.
+ * - Transitions to **IDLE** automatically after draining is complete.
+ * - Remains in **DRAINING** on `IEffect.getParameter()`, `IEffect.setParameter()`,
+ * `IEffect.getDescriptor()`, and `IEffect.reopen()`.
+ *
+ * **Notes:**
+ * - If not implemented, the effect instance may transition directly from **PROCESSING** to
+ * **IDLE** without this intermediate state.
+ * - Any `CommandId.STOP` commands received during **DRAINING** should be ignored.
+ */
+ DRAINING,
}
diff --git a/audio/aidl/android/hardware/audio/effect/state.gv b/audio/aidl/android/hardware/audio/effect/state.gv
index 22c70c8..2a8194e 100644
--- a/audio/aidl/android/hardware/audio/effect/state.gv
+++ b/audio/aidl/android/hardware/audio/effect/state.gv
@@ -13,26 +13,56 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
// To render: "dot -Tpng state.gv -o state.png"
+
digraph effect_state_machine {
- node[shape = point style = filled fillcolor = black width = 0.5] I;
- node[shape = doublecircle] F;
- node[shape = oval width = 1];
- node[fillcolor = lightgreen] INIT;
- node[fillcolor = lightblue] IDLE;
- node[fillcolor = lightyellow] PROCESSING;
- I -> INIT[label = "IFactory.createEffect" labelfontcolor = "navy"];
- INIT -> F[label = "IFactory.destroyEffect"];
- INIT -> IDLE[label = "IEffect.open()" labelfontcolor = "lime"];
- IDLE -> PROCESSING[label = "IEffect.command(START"];
- PROCESSING -> IDLE[label = "IEffect.command(STOP)\nIEffect.command(RESET)"];
- IDLE -> INIT[label = "IEffect.close()"];
+ rankdir=LR; // Left to Right layout
- INIT -> INIT[label = "IEffect.getState\nIEffect.getDescriptor"];
- IDLE -> IDLE[label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.command(RESET)\nIEffect.reopen"];
- PROCESSING
- -> PROCESSING
- [label = "IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.reopen"];
+ label="Effect State Machine";
+ fontsize=20;
+ labelloc=top;
+
+ node [fontname="Helvetica", fontsize=12, style=filled];
+
+ // Initial state node
+ I [shape=point, fillcolor=black, width=0.2];
+
+ // Final state node
+ F [shape=doublecircle, fillcolor=white, width=0.2];
+
+ // Define other nodes with colors
+ INIT [shape=ellipse, fillcolor=lightgreen];
+ IDLE [shape=ellipse, fillcolor=lightblue];
+ PROCESSING [shape=ellipse, fillcolor=lightyellow];
+ DRAINING [shape=ellipse, fillcolor=lightgrey];
+
+ // Transitions
+ I -> INIT [label="IFactory.createEffect", fontcolor="navy"];
+
+ INIT -> F [label="IFactory.destroyEffect"];
+
+ INIT -> IDLE [label="IEffect.open()", fontcolor="lime"];
+
+ IDLE -> PROCESSING [label="IEffect.command(START)"];
+
+ PROCESSING -> IDLE [label="IEffect.command(STOP)\nIEffect.command(RESET)"];
+
+ PROCESSING -> DRAINING [label="IEffect.command(STOP)", fontcolor="orange"];
+
+ DRAINING -> IDLE [label="Draining complete\n(IEffect.command(RESET)\nautomatic)"];
+
+ DRAINING -> PROCESSING [label="IEffect.command(START)\n(Interrupt draining)"];
+
+ IDLE -> INIT [label="IEffect.close()"];
+
+ // Self-loops
+ INIT -> INIT [label="IEffect.getState\nIEffect.getDescriptor"];
+
+ IDLE -> IDLE [label="IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.command(RESET)\nIEffect.reopen"];
+
+ PROCESSING -> PROCESSING [label="IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.reopen"];
+
+ DRAINING -> DRAINING [label="IEffect.getParameter\nIEffect.setParameter\nIEffect.getDescriptor\nIEffect.reopen\nFading"];
+
}
diff --git a/audio/aidl/default/EffectContext.cpp b/audio/aidl/default/EffectContext.cpp
index 26c88b2..b354dd1 100644
--- a/audio/aidl/default/EffectContext.cpp
+++ b/audio/aidl/default/EffectContext.cpp
@@ -258,4 +258,18 @@
return RetCode::SUCCESS;
}
+RetCode EffectContext::startDraining() {
+ mIsDraining = true;
+ return RetCode::SUCCESS;
+}
+
+RetCode EffectContext::finishDraining() {
+ mIsDraining = false;
+ return RetCode::SUCCESS;
+}
+
+bool EffectContext::isDraining() {
+ return mIsDraining;
+}
+
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/EffectImpl.cpp b/audio/aidl/default/EffectImpl.cpp
index 3e61335..7857f53 100644
--- a/audio/aidl/default/EffectImpl.cpp
+++ b/audio/aidl/default/EffectImpl.cpp
@@ -79,7 +79,6 @@
std::lock_guard lg(mImplMutex);
RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "alreadyClosed");
- // TODO: b/302036943 add reopen implementation
RETURN_IF(!mImplContext, EX_NULL_POINTER, "nullContext");
mImplContext->dupeFmqWithReopen(ret);
return ndk::ScopedAStatus::ok();
@@ -347,7 +346,7 @@
{
std::lock_guard lg(mImplMutex);
- if (mState != State::PROCESSING) {
+ if (mState != State::PROCESSING && mState != State::DRAINING) {
LOG(DEBUG) << getEffectNameWithVersion()
<< " skip process in state: " << toString(mState);
return;
diff --git a/audio/aidl/default/EffectThread.cpp b/audio/aidl/default/EffectThread.cpp
index b515385..1a52c13 100644
--- a/audio/aidl/default/EffectThread.cpp
+++ b/audio/aidl/default/EffectThread.cpp
@@ -68,7 +68,11 @@
RetCode EffectThread::startThread() {
{
std::lock_guard lg(mThreadMutex);
- mStop = false;
+ if (mDraining) {
+ mDraining = false;
+ } else {
+ mStop = false;
+ }
mCv.notify_one();
}
@@ -87,6 +91,25 @@
return RetCode::SUCCESS;
}
+RetCode EffectThread::startDraining() {
+ std::lock_guard lg(mThreadMutex);
+ mDraining = true;
+ mCv.notify_one();
+
+ LOG(VERBOSE) << mName << __func__;
+ return RetCode::SUCCESS;
+}
+
+RetCode EffectThread::finishDraining() {
+ std::lock_guard lg(mThreadMutex);
+ mDraining = false;
+ mStop = true;
+ mCv.notify_one();
+
+ LOG(VERBOSE) << mName << __func__;
+ return RetCode::SUCCESS;
+}
+
void EffectThread::threadLoop() {
pthread_setname_np(pthread_self(), mName.substr(0, kMaxTaskNameLen - 1).c_str());
setpriority(PRIO_PROCESS, 0, mPriority);
diff --git a/audio/aidl/default/audio_effects_config.xml b/audio/aidl/default/audio_effects_config.xml
index 2cef9eb..2e860d8 100644
--- a/audio/aidl/default/audio_effects_config.xml
+++ b/audio/aidl/default/audio_effects_config.xml
@@ -76,6 +76,7 @@
<effect name="bassboost" library="bundle" uuid="8631f300-72e2-11df-b57e-0002a5d5c51b"/>
<effect name="downmix" library="downmix" uuid="93f04452-e4fe-41cc-91f9-e475b6d1d69f"/>
<effect name="dynamics_processing" library="dynamics_processing" uuid="e0e6539b-1781-7261-676f-6d7573696340"/>
+ <effect name="eraser" library="erasersw" uuid="fa81ab46-588b-11ed-9b6a-0242ac120002"/>
<effect name="haptic_generator" library="haptic_generator" uuid="97c4acd1-8b82-4f2f-832e-c2fe5d7a9931"/>
<effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
<effect name="reverb_env_aux" library="reverb" uuid="4a387fc0-8ab3-11df-8bad-0002a5d5c51b"/>
diff --git a/audio/aidl/default/eraser/Eraser.cpp b/audio/aidl/default/eraser/Eraser.cpp
index 157ec79..59cc9a2 100644
--- a/audio/aidl/default/eraser/Eraser.cpp
+++ b/audio/aidl/default/eraser/Eraser.cpp
@@ -133,10 +133,70 @@
LOG(DEBUG) << __func__;
}
+ndk::ScopedAStatus EraserSw::command(CommandId command) {
+ std::lock_guard lg(mImplMutex);
+ RETURN_IF(mState == State::INIT, EX_ILLEGAL_STATE, "instanceNotOpen");
+
+ switch (command) {
+ case CommandId::START:
+ RETURN_OK_IF(mState == State::PROCESSING);
+ mState = State::PROCESSING;
+ mContext->enable();
+ startThread();
+ RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagNotEmptyFailed");
+ break;
+ case CommandId::STOP:
+ RETURN_OK_IF(mState == State::IDLE || mState == State::DRAINING);
+ if (mVersion < kDrainSupportedVersion) {
+ mState = State::IDLE;
+ stopThread();
+ mContext->disable();
+ } else {
+ mState = State::DRAINING;
+ startDraining();
+ mContext->startDraining();
+ }
+ RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagNotEmptyFailed");
+ break;
+ case CommandId::RESET:
+ mState = State::IDLE;
+ RETURN_IF(notifyEventFlag(mDataMqNotEmptyEf) != RetCode::SUCCESS, EX_ILLEGAL_STATE,
+ "notifyEventFlagNotEmptyFailed");
+ stopThread();
+ mImplContext->disable();
+ mImplContext->reset();
+ mImplContext->resetBuffer();
+ break;
+ default:
+ LOG(ERROR) << getEffectNameWithVersion() << __func__ << " instance still processing";
+ return ndk::ScopedAStatus::fromExceptionCodeWithMessage(EX_ILLEGAL_ARGUMENT,
+ "CommandIdNotSupported");
+ }
+ LOG(VERBOSE) << getEffectNameWithVersion() << __func__
+ << " transfer to state: " << toString(mState);
+ return ndk::ScopedAStatus::ok();
+}
+
// Processing method running in EffectWorker thread.
IEffect::Status EraserSw::effectProcessImpl(float* in, float* out, int samples) {
RETURN_VALUE_IF(!mContext, (IEffect::Status{EX_NULL_POINTER, 0, 0}), "nullContext");
- return mContext->process(in, out, samples);
+ IEffect::Status procStatus{STATUS_NOT_ENOUGH_DATA, 0, 0};
+ procStatus = mContext->process(in, out, samples);
+ if (mState == State::DRAINING && procStatus.status == STATUS_NOT_ENOUGH_DATA) {
+ drainingComplete_l();
+ }
+
+ return procStatus;
+}
+
+void EraserSw::drainingComplete_l() {
+ if (mState != State::DRAINING) return;
+
+ LOG(DEBUG) << getEffectNameWithVersion() << __func__;
+ finishDraining();
+ mState = State::IDLE;
}
EraserSwContext::EraserSwContext(int statusDepth, const Parameter::Common& common)
@@ -164,24 +224,47 @@
IEffect::Status EraserSwContext::process(float* in, float* out, int samples) {
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
- IEffect::Status status = {EX_ILLEGAL_ARGUMENT, 0, 0};
-
+ IEffect::Status procStatus = {EX_ILLEGAL_ARGUMENT, 0, 0};
const auto inputChannelCount = getChannelCount(mCommon.input.base.channelMask);
const auto outputChannelCount = getChannelCount(mCommon.output.base.channelMask);
if (inputChannelCount < outputChannelCount) {
LOG(ERROR) << __func__ << " invalid channel count, in: " << inputChannelCount
<< " out: " << outputChannelCount;
- return status;
+ return procStatus;
}
- int iFrames = samples / inputChannelCount;
+ if (samples <= 0 || 0 != samples % inputChannelCount) {
+ LOG(ERROR) << __func__ << " invalid samples: " << samples;
+ return procStatus;
+ }
+
+ const int iFrames = samples / inputChannelCount;
+ const float gainPerSample = 1.f / iFrames;
for (int i = 0; i < iFrames; i++) {
- std::memcpy(out, in, outputChannelCount);
+ if (isDraining()) {
+ const float gain = (iFrames - i - 1) * gainPerSample;
+ for (size_t c = 0; c < outputChannelCount; c++) {
+ out[c] = in[c] * gain;
+ }
+ } else {
+ std::memcpy(out, in, outputChannelCount * sizeof(float));
+ }
+
in += inputChannelCount;
out += outputChannelCount;
}
- return {STATUS_OK, static_cast<int32_t>(iFrames * inputChannelCount),
- static_cast<int32_t>(iFrames * outputChannelCount)};
+
+ // drain for one cycle
+ if (isDraining()) {
+ procStatus.status = STATUS_NOT_ENOUGH_DATA;
+ finishDraining();
+ } else {
+ procStatus.status = STATUS_OK;
+ }
+ procStatus.fmqConsumed = static_cast<int32_t>(iFrames * inputChannelCount);
+ procStatus.fmqProduced = static_cast<int32_t>(iFrames * outputChannelCount);
+
+ return procStatus;
}
} // namespace aidl::android::hardware::audio::effect
diff --git a/audio/aidl/default/eraser/Eraser.h b/audio/aidl/default/eraser/Eraser.h
index 0d4eb8f..7bf2f57 100644
--- a/audio/aidl/default/eraser/Eraser.h
+++ b/audio/aidl/default/eraser/Eraser.h
@@ -63,6 +63,9 @@
IEffect::Status effectProcessImpl(float* in, float* out, int samples)
REQUIRES(mImplMutex) final;
+ ndk::ScopedAStatus command(CommandId command) final;
+ void drainingComplete_l() REQUIRES(mImplMutex);
+
private:
static const std::vector<Range::SpatializerRange> kRanges;
std::shared_ptr<EraserSwContext> mContext GUARDED_BY(mImplMutex);
diff --git a/audio/aidl/default/include/effect-impl/EffectContext.h b/audio/aidl/default/include/effect-impl/EffectContext.h
index 02a4caa..9e44349 100644
--- a/audio/aidl/default/include/effect-impl/EffectContext.h
+++ b/audio/aidl/default/include/effect-impl/EffectContext.h
@@ -86,7 +86,12 @@
virtual RetCode disable();
virtual RetCode reset();
+ virtual RetCode startDraining();
+ virtual RetCode finishDraining();
+ virtual bool isDraining();
+
protected:
+ bool mIsDraining = false;
int mVersion = 0;
size_t mInputFrameSize = 0;
size_t mOutputFrameSize = 0;
diff --git a/audio/aidl/default/include/effect-impl/EffectThread.h b/audio/aidl/default/include/effect-impl/EffectThread.h
index ec2a658..9abcdb8 100644
--- a/audio/aidl/default/include/effect-impl/EffectThread.h
+++ b/audio/aidl/default/include/effect-impl/EffectThread.h
@@ -38,6 +38,8 @@
RetCode destroyThread();
RetCode startThread();
RetCode stopThread();
+ RetCode startDraining();
+ RetCode finishDraining();
// Will call process() in a loop if the thread is running.
void threadLoop();
@@ -49,6 +51,9 @@
*/
virtual void process() = 0;
+ protected:
+ bool mDraining GUARDED_BY(mThreadMutex) = false;
+
private:
static constexpr int kMaxTaskNameLen = 15;
diff --git a/audio/aidl/vts/EffectHelper.h b/audio/aidl/vts/EffectHelper.h
index ace6a82..eedac3d 100644
--- a/audio/aidl/vts/EffectHelper.h
+++ b/audio/aidl/vts/EffectHelper.h
@@ -124,7 +124,7 @@
return;
}
- ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_TRUE(expectState(effect, State::IDLE));
updateFrameSize(common);
}
@@ -155,7 +155,7 @@
if (effect) {
ASSERT_STATUS(status, effect->close());
if (status == EX_NONE) {
- ASSERT_NO_FATAL_FAILURE(expectState(effect, State::INIT));
+ ASSERT_TRUE(expectState(effect, State::INIT));
}
}
}
@@ -166,12 +166,14 @@
ASSERT_STATUS(status, effect->getDescriptor(&desc));
}
- static void expectState(std::shared_ptr<IEffect> effect, State expectState,
- binder_status_t status = EX_NONE) {
- ASSERT_NE(effect, nullptr);
- State state;
- ASSERT_STATUS(status, effect->getState(&state));
- ASSERT_EQ(expectState, state);
+ static bool expectState(std::shared_ptr<IEffect> effect, State expectState) {
+ if (effect == nullptr) return false;
+
+ if (State state; EX_NONE != effect->getState(&state).getStatus() || expectState != state) {
+ return false;
+ }
+
+ return true;
}
static void commandIgnoreRet(std::shared_ptr<IEffect> effect, CommandId command) {
@@ -190,12 +192,14 @@
switch (command) {
case CommandId::START:
- ASSERT_NO_FATAL_FAILURE(expectState(effect, State::PROCESSING));
+ ASSERT_TRUE(expectState(effect, State::PROCESSING));
break;
case CommandId::STOP:
- FALLTHROUGH_INTENDED;
+ ASSERT_TRUE(expectState(effect, State::IDLE) ||
+ expectState(effect, State::DRAINING));
+ break;
case CommandId::RESET:
- ASSERT_NO_FATAL_FAILURE(expectState(effect, State::IDLE));
+ ASSERT_TRUE(expectState(effect, State::IDLE));
break;
default:
return;
@@ -371,6 +375,24 @@
return functor(result);
}
+ // keep writing data to the FMQ until effect transit from DRAINING to IDLE
+ static void waitForDrain(std::vector<float>& inputBuffer, std::vector<float>& outputBuffer,
+ const std::shared_ptr<IEffect>& effect,
+ std::unique_ptr<EffectHelper::StatusMQ>& statusMQ,
+ std::unique_ptr<EffectHelper::DataMQ>& inputMQ,
+ std::unique_ptr<EffectHelper::DataMQ>& outputMQ, int version) {
+ State state;
+ while (effect->getState(&state).getStatus() == EX_NONE && state == State::DRAINING) {
+ EXPECT_NO_FATAL_FAILURE(
+ EffectHelper::writeToFmq(statusMQ, inputMQ, inputBuffer, version));
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(
+ statusMQ, 1, outputMQ, outputBuffer.size(), outputBuffer, std::nullopt));
+ }
+ ASSERT_TRUE(State::IDLE == state);
+ EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, outputBuffer));
+ return;
+ }
+
static void processAndWriteToOutput(std::vector<float>& inputBuffer,
std::vector<float>& outputBuffer,
const std::shared_ptr<IEffect>& effect,
@@ -404,8 +426,9 @@
// Disable the process
if (callStopReset) {
ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::STOP));
+ EXPECT_NO_FATAL_FAILURE(waitForDrain(inputBuffer, outputBuffer, effect, statusMQ,
+ inputMQ, outputMQ, version));
}
- EXPECT_NO_FATAL_FAILURE(EffectHelper::readFromFmq(statusMQ, 0, outputMQ, 0, outputBuffer));
if (callStopReset) {
ASSERT_NO_FATAL_FAILURE(command(effect, CommandId::RESET));
diff --git a/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp
index d43b595..206ce0c 100644
--- a/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp
+++ b/automotive/audiocontrol/aidl/default/converter/src/CarAudioConfigurationXmlConverter.cpp
@@ -645,11 +645,9 @@
bool parseVolumeGroupActivationEntry(const xsd::ActivationVolumeConfigEntryType& xsdEntry,
api::VolumeActivationConfigurationEntry& entry) {
if (!xsdEntry.hasInvocationType()) {
- LOG(ERROR) << __func__ << " Activation config entry missing invocation type";
- return false;
- }
-
- if (!parseVolumeActivationType(xsdEntry.getInvocationType(), entry.type)) {
+ // Legacy file had default invocation type as on playback changed
+ entry.type = api::VolumeInvocationType::ON_PLAYBACK_CHANGED;
+ } else if (!parseVolumeActivationType(xsdEntry.getInvocationType(), entry.type)) {
LOG(ERROR) << __func__ << " Could not parse configuration entry type";
return false;
}
diff --git a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
index c01c0d6..6781a81 100644
--- a/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
+++ b/automotive/audiocontrol/aidl/vts/VtsHalAudioControlTargetTest.cpp
@@ -149,7 +149,9 @@
return false;
}
if (groupDevices.contains(address)) {
- message = " Audio device address can not repeat in the same volume group";
+ message =
+ " Audio device address can not repeat in the same volume group or within audio"
+ " zone configuration if not using configurable audio policy engine";
return false;
}
groupDevices.insert(address);
@@ -196,7 +198,8 @@
void validateVolumeGroupInfo(const AudioZoneConfig& audioZoneConfig,
const VolumeGroupConfig& volumeGroupConfig,
- const AudioDeviceConfiguration& deviceConfig) {
+ const AudioDeviceConfiguration& deviceConfig,
+ std::set<std::string>& groupDevices) {
std::string zoneConfigName = testutils::toAlphaNumeric(ToString(audioZoneConfig.name));
std::string volumeGroupName = testutils::toAlphaNumeric(ToString(volumeGroupConfig.name));
std::string volumeGroupInfo =
@@ -209,7 +212,6 @@
EXPECT_FALSE(volumeGroupConfig.name.empty())
<< volumeGroupInfo << " must have a non-empty volume name";
}
- std::set<std::string> groupDevices;
for (const auto& audioRoute : volumeGroupConfig.carAudioRoutes) {
std::string routeMessage;
EXPECT_TRUE(hasValidAudioRoute(audioRoute, routeMessage, groupDevices))
@@ -254,6 +256,7 @@
std::set<std::string> contextInfoNames;
EXPECT_FALSE(audioZoneConfig.volumeGroups.empty())
<< "Volume groups for zone config " << zoneConfigName.c_str();
+ std::set<std::string> groupDevices;
for (const auto& volumeGroup : audioZoneConfig.volumeGroups) {
ALOGI("Zone config name %s volume group test %s", zoneConfigName.c_str(),
ToString(volumeGroup.name).c_str());
@@ -264,7 +267,11 @@
<< "Context " << context << " repeats in zone config " << zoneConfigName;
contextInfoNames.insert(context);
}
- validateVolumeGroupInfo(audioZoneConfig, volumeGroup, deviceConfig);
+ // Configurable audio policy engine can share devices among volume groups
+ if (deviceConfig.routingConfig == CONFIGURABLE_AUDIO_ENGINE_ROUTING) {
+ groupDevices.clear();
+ }
+ validateVolumeGroupInfo(audioZoneConfig, volumeGroup, deviceConfig, groupDevices);
}
const auto& audioZoneContexts = carAudioZone.audioZoneContext.audioContextInfos;
std::map<std::string, AudioZoneContextInfo> infoNameToInfo;
diff --git a/bluetooth/socket/OWNERS b/bluetooth/socket/OWNERS
new file mode 100644
index 0000000..e7a60e6
--- /dev/null
+++ b/bluetooth/socket/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 27441
+
+include platform/packages/modules/Bluetooth:/OWNERS
+
+jaydenk@google.com
diff --git a/bluetooth/socket/aidl/Android.bp b/bluetooth/socket/aidl/Android.bp
new file mode 100644
index 0000000..44e7f5a
--- /dev/null
+++ b/bluetooth/socket/aidl/Android.bp
@@ -0,0 +1,40 @@
+// Copyright (C) 2024 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"],
+}
+
+aidl_interface {
+ name: "android.hardware.bluetooth.socket",
+ vendor_available: true,
+ host_supported: true,
+ srcs: ["android/hardware/bluetooth/socket/*.aidl"],
+ stability: "vintf",
+ backend: {
+ ndk: {
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.btservices",
+ ],
+ min_sdk_version: "33",
+ },
+ },
+ frozen: false,
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/ChannelInfo.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/ChannelInfo.aidl
new file mode 100644
index 0000000..b9b9593
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/ChannelInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+union ChannelInfo {
+ android.hardware.bluetooth.socket.LeCocChannelInfo leCocChannelInfo;
+ android.hardware.bluetooth.socket.RfcommChannelInfo rfcommChannelInfo;
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/IBluetoothSocket.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/IBluetoothSocket.aidl
new file mode 100644
index 0000000..a961692
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/IBluetoothSocket.aidl
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+interface IBluetoothSocket {
+ void registerCallback(in android.hardware.bluetooth.socket.IBluetoothSocketCallback callback);
+ android.hardware.bluetooth.socket.SocketCapabilities getSocketCapabilities();
+ void opened(in android.hardware.bluetooth.socket.SocketContext context);
+ void closed(long socketId);
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/IBluetoothSocketCallback.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/IBluetoothSocketCallback.aidl
new file mode 100644
index 0000000..35bfb5b
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/IBluetoothSocketCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+interface IBluetoothSocketCallback {
+ void openedComplete(long socketId, in android.hardware.bluetooth.socket.Status status, in String reason);
+ void close(long socketId, in String reason);
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/LeCocCapabilities.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
new file mode 100644
index 0000000..447daa9
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+parcelable LeCocCapabilities {
+ int numberOfSupportedSockets;
+ int mtu;
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/LeCocChannelInfo.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/LeCocChannelInfo.aidl
new file mode 100644
index 0000000..4d6fcb7
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/LeCocChannelInfo.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+parcelable LeCocChannelInfo {
+ int localCid;
+ int remoteCid;
+ int psm;
+ int localMtu;
+ int remoteMtu;
+ int localMps;
+ int remoteMps;
+ int initialRxCredits;
+ int initialTxCredits;
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/RfcommCapabilities.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/RfcommCapabilities.aidl
new file mode 100644
index 0000000..06a75b4
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/RfcommCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+parcelable RfcommCapabilities {
+ int numberOfSupportedSockets;
+ int maxFrameSize;
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/RfcommChannelInfo.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/RfcommChannelInfo.aidl
new file mode 100644
index 0000000..3f9a140
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/RfcommChannelInfo.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+parcelable RfcommChannelInfo {
+ int localCid;
+ int remoteCid;
+ int localMtu;
+ int remoteMtu;
+ int initialRxCredits;
+ int initialTxCredits;
+ int dlci;
+ int maxFrameSize;
+ boolean muxInitiator;
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/SocketCapabilities.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/SocketCapabilities.aidl
new file mode 100644
index 0000000..400f20c
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/SocketCapabilities.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+parcelable SocketCapabilities {
+ android.hardware.bluetooth.socket.LeCocCapabilities leCocCapabilities;
+ android.hardware.bluetooth.socket.RfcommCapabilities rfcommCapabilities;
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/SocketContext.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/SocketContext.aidl
new file mode 100644
index 0000000..e5b31c2
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/SocketContext.aidl
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@VintfStability
+parcelable SocketContext {
+ long socketId;
+ String name;
+ int aclConnectionHandle;
+ android.hardware.bluetooth.socket.ChannelInfo channelInfo;
+ long hubId;
+ long endpointId;
+}
diff --git a/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/Status.aidl b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/Status.aidl
new file mode 100644
index 0000000..63f57a9
--- /dev/null
+++ b/bluetooth/socket/aidl/aidl_api/android.hardware.bluetooth.socket/current/android/hardware/bluetooth/socket/Status.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+@Backing(type="int") @VintfStability
+enum Status {
+ SUCCESS,
+ FAILURE,
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/ChannelInfo.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/ChannelInfo.aidl
new file mode 100644
index 0000000..afae1c0
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/ChannelInfo.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+import android.hardware.bluetooth.socket.LeCocChannelInfo;
+import android.hardware.bluetooth.socket.RfcommChannelInfo;
+
+/**
+ * Used to specify the channel information of different protocol.
+ */
+@VintfStability
+union ChannelInfo {
+ /**
+ * LE L2CAP COC channel information.
+ */
+ LeCocChannelInfo leCocChannelInfo;
+
+ /**
+ * RFCOMM channel information.
+ */
+ RfcommChannelInfo rfcommChannelInfo;
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/IBluetoothSocket.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/IBluetoothSocket.aidl
new file mode 100644
index 0000000..5853c10
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/IBluetoothSocket.aidl
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+import android.hardware.bluetooth.socket.IBluetoothSocketCallback;
+import android.hardware.bluetooth.socket.SocketCapabilities;
+import android.hardware.bluetooth.socket.SocketContext;
+
+/**
+ * The interface for host stack to register callback, get capabilities, and open/close socket.
+ */
+@VintfStability
+interface IBluetoothSocket {
+ /**
+ * API to register a callback for HAL implementation to send asynchronous events.
+ *
+ * @param callback An instance of the |IBluetoothSocketCallback| AIDL interface object
+ */
+ void registerCallback(in IBluetoothSocketCallback callback);
+
+ /**
+ * API to get supported offload socket capabilities.
+ *
+ * @return a socket capabilities
+ */
+ SocketCapabilities getSocketCapabilities();
+
+ /**
+ * API to notify the offload stack that the socket is opened.
+ *
+ * The HAL implementation must use IBluetoothSocketCallback.openedComplete() to indicate the
+ * result of this operation
+ *
+ * @param context Socket context including socket id, channel, hub, and endpoint info
+ */
+ void opened(in SocketContext context);
+
+ /**
+ * API to notify the offload stack that the socket is closed.
+ *
+ * When host app requests to close a socket or the HAL calls IBluetoothSocketCallback.close(),
+ * the host stack closes the socket and sends the notification.
+ *
+ * @param socketId Identifier assigned to the socket by the host stack
+ */
+ void closed(long socketId);
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/IBluetoothSocketCallback.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/IBluetoothSocketCallback.aidl
new file mode 100644
index 0000000..7cd635d
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/IBluetoothSocketCallback.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+import android.hardware.bluetooth.socket.Status;
+
+/**
+ * The interface from the Bluetooth offload socket to the host stack.
+ */
+@VintfStability
+interface IBluetoothSocketCallback {
+ /**
+ * Invoked when IBluetoothSocket.opened() has been completed.
+ *
+ * @param socketId Identifier assigned to the socket by the host stack
+ * @param status Status indicating success or failure
+ * @param reason Reason string of the operation failure for debugging purposes
+ */
+ void openedComplete(long socketId, in Status status, in String reason);
+
+ /**
+ * Invoked when offload app or stack requests host stack to close the socket.
+ *
+ * @param socketId Identifier assigned to the socket by the host stack
+ * @param reason Reason string for closing the socket for debugging purposes
+ */
+ void close(long socketId, in String reason);
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
new file mode 100644
index 0000000..003da11
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocCapabilities.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+/**
+ * Capabilities for LE L2CAP COC that the offload stack supports.
+ */
+@VintfStability
+parcelable LeCocCapabilities {
+ /**
+ * Maximum number of LE COC sockets supported. If not supported, the value must be zero.
+ */
+ int numberOfSupportedSockets;
+
+ /**
+ * Local Maximum Transmission Unit size in octets. The MTU size must be in range 23 to 65535.
+ *
+ * The actual value of the local MTU shared in the connection configuration is set in
+ * LeCocChannelInfo.localMtu in the IBluetoothSocket.opened() context parameter.
+ */
+ int mtu;
+
+ /**
+ * The value used by the Host stack for the local Maximum Packet Size shall be the value
+ * LE_ACL_Data_Packet_Length returned by the controller in response to the command HCI LE Read
+ * Buffer Size. Then, the MPS size must be in range 1 to 255. We do not make the MPS
+ * configurable in HAL because using the maximum value does not require a large amount of
+ * memory.
+ */
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocChannelInfo.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocChannelInfo.aidl
new file mode 100644
index 0000000..af1bd71
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/LeCocChannelInfo.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+/**
+ * LE L2CAP COC channel information
+ */
+@VintfStability
+parcelable LeCocChannelInfo {
+ /**
+ * L2cap local channel ID.
+ */
+ int localCid;
+
+ /**
+ * L2cap remote channel ID.
+ */
+ int remoteCid;
+
+ /**
+ * PSM for L2CAP LE CoC.
+ */
+ int psm;
+
+ /**
+ * Local Maximum Transmission Unit for LE COC specifying the maximum SDU size in bytes that the
+ * local L2CAP layer can receive.
+ */
+ int localMtu;
+
+ /**
+ * Remote Maximum Transmission Unit for LE COC specifying the maximum SDU size in bytes that the
+ * remote L2CAP layer can receive.
+ */
+ int remoteMtu;
+
+ /**
+ * Local Maximum PDU payload Size in bytes that the local L2CAP layer can receive.
+ */
+ int localMps;
+
+ /**
+ * Remote Maximum PDU payload Size in bytes that the remote L2CAP layer can receive.
+ */
+ int remoteMps;
+
+ /**
+ * Protocol initial credits at Rx path.
+ *
+ * The host stack will always set the initial credits to 0 when configuring the L2CAP COC
+ * channel, and this value will always be zero. It means offload stack should send initial
+ * credits to peer device through L2CAP signaling command L2CAP_FLOW_CONTROL_CREDIT_IND when
+ * IBluetoothSocket.opened() is successful.
+ */
+ int initialRxCredits;
+
+ /**
+ * Protocol initial credits at Tx path.
+ */
+ int initialTxCredits;
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/RfcommCapabilities.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/RfcommCapabilities.aidl
new file mode 100644
index 0000000..e5cffff
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/RfcommCapabilities.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+/**
+ * Capabilities for RFCOMM that the offload stack supports.
+ */
+@VintfStability
+parcelable RfcommCapabilities {
+ /**
+ * Maximum number of RFCOMM sockets supported. If not supported, the value must be zero.
+ */
+ int numberOfSupportedSockets;
+
+ /**
+ * Maximum frame size in octets negotiated during DLCI establishment. The frame size must be
+ * in range 23 to 32767.
+ */
+ int maxFrameSize;
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/RfcommChannelInfo.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/RfcommChannelInfo.aidl
new file mode 100644
index 0000000..7c10144
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/RfcommChannelInfo.aidl
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+/**
+ * RFCOMM channel information
+ */
+@VintfStability
+parcelable RfcommChannelInfo {
+ /**
+ * L2cap local channel ID for RFCOMM.
+ */
+ int localCid;
+
+ /**
+ * L2cap remote channel ID for RFCOMM.
+ */
+ int remoteCid;
+
+ /**
+ * Local Maximum Transmission Unit Size in bytes that the local L2CAP layer can receive.
+ */
+ int localMtu;
+
+ /**
+ * Remote Maximum Transmission Unit Size in bytes that the remote L2CAP layer can receive.
+ */
+ int remoteMtu;
+
+ /**
+ * Protocol initial credits at Rx path.
+ *
+ * The host stack will always set the initial credits to 0 when configuring the RFCOMM
+ * channel, and this value will always be zero. It means offload stack should send initial
+ * credits to peer device when IBluetoothSocket.opened() is successful.
+ */
+ int initialRxCredits;
+
+ /**
+ * Protocol initial credits at Tx path.
+ */
+ int initialTxCredits;
+
+ /**
+ * Data Link Connection Identifier (DLCI).
+ */
+ int dlci;
+
+ /**
+ * Maximum frame size negotiated during DLCI establishment.
+ */
+ int maxFrameSize;
+
+ /**
+ * Flag of whether the Android stack initiated the RFCOMM multiplexer control channel.
+ *
+ * This flag determines the value of the Command/Response (C/R) bit of RFCOMM frames.
+ */
+ boolean muxInitiator;
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/SocketCapabilities.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/SocketCapabilities.aidl
new file mode 100644
index 0000000..05a59ee
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/SocketCapabilities.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+import android.hardware.bluetooth.socket.LeCocCapabilities;
+import android.hardware.bluetooth.socket.RfcommCapabilities;
+
+/**
+ * Supported socket protocol capabilities.
+ */
+@VintfStability
+parcelable SocketCapabilities {
+ /**
+ * Supported LE CoC protocol capabilities.
+ */
+ LeCocCapabilities leCocCapabilities;
+
+ /**
+ * Supported RFCOMM protocol capabilities.
+ */
+ RfcommCapabilities rfcommCapabilities;
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/SocketContext.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/SocketContext.aidl
new file mode 100644
index 0000000..5e9be31
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/SocketContext.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+import android.hardware.bluetooth.socket.ChannelInfo;
+
+/**
+ * Socket context.
+ */
+@VintfStability
+parcelable SocketContext {
+ /**
+ * Identifier assigned to the socket by the host stack when the socket is connected to a remote
+ * device. Used to uniquely identify the socket in other callbacks and method invocations. It is
+ * valid only while the socket is connected.
+ */
+ long socketId;
+
+ /**
+ * Descriptive socket name provided by the host app when it creates this socket. This is not
+ * unique across the system, but can help the offload app understand the purpose of the socket
+ * when it receives a socket connection event.
+ */
+ String name;
+
+ /**
+ * ACL connection handle for the socket.
+ */
+ int aclConnectionHandle;
+
+ /**
+ * Channel information of the socket protocol.
+ */
+ ChannelInfo channelInfo;
+
+ /**
+ * The ID of the Hub to which the end point belongs for hardware offload data path.
+ */
+ long hubId;
+
+ /**
+ * The ID of the Hub endpoint for hardware offload data path.
+ */
+ long endpointId;
+}
diff --git a/bluetooth/socket/aidl/android/hardware/bluetooth/socket/Status.aidl b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/Status.aidl
new file mode 100644
index 0000000..d881b09
--- /dev/null
+++ b/bluetooth/socket/aidl/android/hardware/bluetooth/socket/Status.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2024 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.bluetooth.socket;
+
+@VintfStability
+@Backing(type="int")
+enum Status {
+ SUCCESS,
+ FAILURE,
+}
diff --git a/bluetooth/socket/aidl/default/Android.bp b/bluetooth/socket/aidl/default/Android.bp
new file mode 100644
index 0000000..10e673c
--- /dev/null
+++ b/bluetooth/socket/aidl/default/Android.bp
@@ -0,0 +1,47 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_binary {
+ name: "android.hardware.bluetooth.socket-service.default",
+ relative_install_path: "hw",
+ init_rc: ["bluetooth-socket-service-default.rc"],
+ vintf_fragments: [":manifest_android.hardware.bluetooth.socket-service.default.xml"],
+ vendor: true,
+ srcs: [
+ "BluetoothSocket.cpp",
+ "service.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.bluetooth.socket-V1-ndk",
+ "libbase",
+ "libbinder_ndk",
+ "libhidlbase",
+ "libutils",
+ "liblog",
+ ],
+}
+
+cc_fuzz {
+ name: "android.hardware.bluetooth.socket-service_fuzzer",
+ team: "trendy_team_bluetooth",
+ defaults: ["service_fuzzer_defaults"],
+ srcs: [
+ "fuzzer.cpp",
+ "BluetoothSocket.cpp",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.socket-V1-ndk",
+ "liblog",
+ ],
+ fuzz_config: {
+ cc: [
+ "jaydenk@google.com",
+ ],
+ },
+}
+
+filegroup {
+ name: "manifest_android.hardware.bluetooth.socket-service.default.xml",
+ srcs: ["bluetooth-socket-service-default.xml"],
+}
diff --git a/bluetooth/socket/aidl/default/BluetoothSocket.cpp b/bluetooth/socket/aidl/default/BluetoothSocket.cpp
new file mode 100644
index 0000000..5993393
--- /dev/null
+++ b/bluetooth/socket/aidl/default/BluetoothSocket.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 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 "BluetoothSocket.h"
+
+using aidl::android::hardware::bluetooth::socket::Status;
+
+namespace aidl::android::hardware::bluetooth::socket::impl {
+
+BluetoothSocket::BluetoothSocket() {}
+BluetoothSocket::~BluetoothSocket() {}
+
+::ndk::ScopedAStatus BluetoothSocket::registerCallback(
+ const std::shared_ptr<
+ ::aidl::android::hardware::bluetooth::socket::IBluetoothSocketCallback>&
+ in_callback) {
+ if (in_callback == nullptr) {
+ return ndk::ScopedAStatus::fromServiceSpecificError(STATUS_BAD_VALUE);
+ }
+ callback_ = in_callback;
+ return ::ndk::ScopedAStatus::ok();
+}
+::ndk::ScopedAStatus BluetoothSocket::getSocketCapabilities(
+ ::aidl::android::hardware::bluetooth::socket::SocketCapabilities*
+ _aidl_return) {
+ _aidl_return->leCocCapabilities.numberOfSupportedSockets = 0;
+ _aidl_return->leCocCapabilities.mtu = 0;
+ _aidl_return->rfcommCapabilities.numberOfSupportedSockets = 0;
+ _aidl_return->rfcommCapabilities.maxFrameSize = 0;
+ return ::ndk::ScopedAStatus::ok();
+}
+::ndk::ScopedAStatus BluetoothSocket::opened(
+ const ::aidl::android::hardware::bluetooth::socket::SocketContext&
+ /* in_context */) {
+ return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+::ndk::ScopedAStatus BluetoothSocket::closed(int64_t /*in_socketId*/) {
+ return ::ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::bluetooth::socket::impl
diff --git a/bluetooth/socket/aidl/default/BluetoothSocket.h b/bluetooth/socket/aidl/default/BluetoothSocket.h
new file mode 100644
index 0000000..9bb41ec
--- /dev/null
+++ b/bluetooth/socket/aidl/default/BluetoothSocket.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2024 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/bluetooth/socket/BnBluetoothSocket.h>
+
+namespace aidl::android::hardware::bluetooth::socket::impl {
+
+class BluetoothSocket : public BnBluetoothSocket {
+ public:
+ BluetoothSocket();
+ ~BluetoothSocket();
+
+ ::ndk::ScopedAStatus registerCallback(
+ const std::shared_ptr<::aidl::android::hardware::bluetooth::socket::
+ IBluetoothSocketCallback>& in_callback)
+ override;
+ ::ndk::ScopedAStatus getSocketCapabilities(
+ ::aidl::android::hardware::bluetooth::socket::SocketCapabilities*
+ _aidl_return) override;
+ ::ndk::ScopedAStatus opened(
+ const ::aidl::android::hardware::bluetooth::socket::SocketContext&
+ in_context) override;
+ ::ndk::ScopedAStatus closed(int64_t in_socketId) override;
+
+ private:
+ std::shared_ptr<IBluetoothSocketCallback> callback_;
+};
+
+} // namespace aidl::android::hardware::bluetooth::socket::impl
diff --git a/bluetooth/socket/aidl/default/bluetooth-socket-service-default.rc b/bluetooth/socket/aidl/default/bluetooth-socket-service-default.rc
new file mode 100644
index 0000000..f1eb7f7
--- /dev/null
+++ b/bluetooth/socket/aidl/default/bluetooth-socket-service-default.rc
@@ -0,0 +1,4 @@
+service vendor.bluetooth.socket-default /vendor/bin/hw/android.hardware.bluetooth.socket-service.default
+ class hal
+ user nobody
+ group nobody
diff --git a/bluetooth/socket/aidl/default/bluetooth-socket-service-default.xml b/bluetooth/socket/aidl/default/bluetooth-socket-service-default.xml
new file mode 100644
index 0000000..b97074d
--- /dev/null
+++ b/bluetooth/socket/aidl/default/bluetooth-socket-service-default.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.bluetooth.socket</name>
+ <version>1</version>
+ <fqname>IBluetoothSocket/default</fqname>
+ </hal>
+</manifest>
diff --git a/bluetooth/socket/aidl/default/fuzzer.cpp b/bluetooth/socket/aidl/default/fuzzer.cpp
new file mode 100644
index 0000000..062db0f
--- /dev/null
+++ b/bluetooth/socket/aidl/default/fuzzer.cpp
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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 <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include "BluetoothSocket.h"
+
+using ::aidl::android::hardware::bluetooth::socket::impl::BluetoothSocket;
+using ::android::fuzzService;
+using ::ndk::SharedRefBase;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ auto bluetoothSocketAidl = SharedRefBase::make<BluetoothSocket>();
+
+ fuzzService(bluetoothSocketAidl->asBinder().get(),
+ FuzzedDataProvider(data, size));
+
+ return 0;
+}
diff --git a/bluetooth/socket/aidl/default/service.cpp b/bluetooth/socket/aidl/default/service.cpp
new file mode 100644
index 0000000..bd15084
--- /dev/null
+++ b/bluetooth/socket/aidl/default/service.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2023 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 "aidl.android.hardware.bluetooth.socket.service.default"
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <utils/Log.h>
+
+#include "BluetoothSocket.h"
+
+using ::aidl::android::hardware::bluetooth::socket::impl::BluetoothSocket;
+
+int main(int /* argc */, char** /* argv */) {
+ ALOGI("Bluetooth Socket HAL registering");
+ if (!ABinderProcess_setThreadPoolMaxThreadCount(0)) {
+ ALOGE("Failed to set thread pool max thread count");
+ return 1;
+ }
+
+ std::shared_ptr<BluetoothSocket> service =
+ ndk::SharedRefBase::make<BluetoothSocket>();
+ std::string instance =
+ std::string() + BluetoothSocket::descriptor + "/default";
+ auto result =
+ AServiceManager_addService(service->asBinder().get(), instance.c_str());
+ if (result == STATUS_OK) {
+ ABinderProcess_joinThreadPool();
+ } else {
+ ALOGE("Could not register as a service!");
+ }
+ return EXIT_FAILURE;
+}
diff --git a/bluetooth/socket/aidl/vts/Android.bp b/bluetooth/socket/aidl/vts/Android.bp
new file mode 100644
index 0000000..fa9e3b1
--- /dev/null
+++ b/bluetooth/socket/aidl/vts/Android.bp
@@ -0,0 +1,28 @@
+package {
+ default_team: "trendy_team_bluetooth",
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
+cc_test {
+ name: "VtsHalBluetoothSocketTargetTest",
+ defaults: [
+ "use_libaidlvintf_gtest_helper_static",
+ ],
+ srcs: ["VtsHalBluetoothSocketTargetTest.cpp"],
+ shared_libs: [
+ "libbase",
+ "libbinder_ndk",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth.socket-V1-ndk",
+ "libbluetooth-types",
+ ],
+ test_suites: [
+ "general-tests",
+ "vts",
+ ],
+ require_root: true,
+}
diff --git a/bluetooth/socket/aidl/vts/VtsHalBluetoothSocketTargetTest.cpp b/bluetooth/socket/aidl/vts/VtsHalBluetoothSocketTargetTest.cpp
new file mode 100644
index 0000000..1069207
--- /dev/null
+++ b/bluetooth/socket/aidl/vts/VtsHalBluetoothSocketTargetTest.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2024 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/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/bluetooth/socket/BnBluetoothSocketCallback.h>
+#include <aidl/android/hardware/bluetooth/socket/IBluetoothSocket.h>
+#include <aidl/android/hardware/bluetooth/socket/IBluetoothSocketCallback.h>
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <binder/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <future>
+
+using ::aidl::android::hardware::bluetooth::socket::BnBluetoothSocketCallback;
+using ::aidl::android::hardware::bluetooth::socket::IBluetoothSocket;
+using ::aidl::android::hardware::bluetooth::socket::SocketCapabilities;
+using ::aidl::android::hardware::bluetooth::socket::SocketContext;
+using ::ndk::ScopedAStatus;
+
+namespace {
+constexpr static int kCallbackTimeoutMs = 250;
+constexpr static int kOpenedCallbackTimeoutMs = 5000;
+} // namespace
+
+class BluetoothSocketCallback : public BnBluetoothSocketCallback {
+ public:
+ BluetoothSocketCallback(
+ const std::function<
+ void(int64_t in_socketId,
+ ::aidl::android::hardware::bluetooth::socket::Status in_status,
+ const std::string& in_reason)>& on_hal_opened_complete_cb)
+ : on_hal_opened_complete_cb_(on_hal_opened_complete_cb) {}
+
+ ScopedAStatus openedComplete(
+ int64_t in_socketId,
+ ::aidl::android::hardware::bluetooth::socket::Status in_status,
+ const std::string& in_reason) override {
+ on_hal_opened_complete_cb_(in_socketId, in_status, in_reason);
+ return ::ndk::ScopedAStatus::ok();
+ }
+
+ ScopedAStatus close(int64_t /* in_socketId */,
+ const std::string& /* in_reason */) override {
+ return ::ndk::ScopedAStatus::ok();
+ }
+
+ private:
+ std::function<void(
+ int64_t in_socketId,
+ ::aidl::android::hardware::bluetooth::socket::Status in_status,
+ const std::string& in_reason)>
+ on_hal_opened_complete_cb_;
+};
+
+class BluetoothSocketTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ ALOGI("SetUp Socket Test");
+ bluetooth_socket_ = IBluetoothSocket::fromBinder(
+ ndk::SpAIBinder(AServiceManager_waitForService(GetParam().c_str())));
+ ASSERT_NE(bluetooth_socket_, nullptr);
+ }
+
+ virtual void TearDown() override {
+ ALOGI("TearDown Socket Test");
+ bluetooth_socket_ = nullptr;
+ ASSERT_EQ(bluetooth_socket_, nullptr);
+ }
+
+ std::shared_ptr<IBluetoothSocket> bluetooth_socket_;
+};
+
+TEST_P(BluetoothSocketTest, registerCallback) {
+ std::promise<void> open_cb_promise;
+ std::future<void> open_cb_future{open_cb_promise.get_future()};
+ std::shared_ptr<BluetoothSocketCallback> callback =
+ ndk::SharedRefBase::make<BluetoothSocketCallback>(
+ [&open_cb_promise](auto /* socket_id */, auto /* status */,
+ auto /* reason */) {
+ open_cb_promise.set_value();
+ });
+ ScopedAStatus status = bluetooth_socket_->registerCallback(callback);
+ ASSERT_TRUE(status.isOk());
+}
+
+TEST_P(BluetoothSocketTest, GetSocketCapabilities) {
+ SocketCapabilities socket_capabilities;
+ ScopedAStatus status =
+ bluetooth_socket_->getSocketCapabilities(&socket_capabilities);
+ ASSERT_TRUE(status.isOk());
+ ASSERT_TRUE(socket_capabilities.leCocCapabilities.numberOfSupportedSockets >=
+ 0);
+ if (socket_capabilities.leCocCapabilities.numberOfSupportedSockets) {
+ // When LE COC is supported, the local MTU must be configured within the
+ // valid range defined in the L2CAP specification.
+ ASSERT_TRUE(socket_capabilities.leCocCapabilities.mtu >= 23 &&
+ socket_capabilities.leCocCapabilities.mtu <= 65535);
+ }
+ ASSERT_TRUE(socket_capabilities.rfcommCapabilities.numberOfSupportedSockets >=
+ 0);
+ if (socket_capabilities.rfcommCapabilities.numberOfSupportedSockets) {
+ // When RFCOMM is supported, the maximum frame size must be configured
+ // within the valid range defined in the RFCOMM specification.
+ ASSERT_TRUE(socket_capabilities.rfcommCapabilities.maxFrameSize >= 23 &&
+ socket_capabilities.rfcommCapabilities.maxFrameSize <= 32767);
+ }
+}
+
+TEST_P(BluetoothSocketTest, Opened) {
+ std::promise<void> open_cb_promise;
+ std::future<void> open_cb_future{open_cb_promise.get_future()};
+ std::shared_ptr<BluetoothSocketCallback> callback =
+ ndk::SharedRefBase::make<BluetoothSocketCallback>(
+ [&open_cb_promise](auto /* socket_id */, auto /* status */,
+ auto /* reason */) {
+ open_cb_promise.set_value();
+ });
+ bluetooth_socket_->registerCallback(callback);
+ SocketCapabilities socket_capabilities;
+ bluetooth_socket_->getSocketCapabilities(&socket_capabilities);
+
+ SocketContext socket_context;
+ ScopedAStatus status = bluetooth_socket_->opened(socket_context);
+ std::chrono::milliseconds timeout{kOpenedCallbackTimeoutMs};
+ if (status.isOk()) {
+ // If IBluetoothSocket.opened() returns success, the callback
+ // BluetoothSocketCallback.openedComplete() must be called within the
+ // timeout.
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::ready);
+ } else {
+ // If IBluetoothSocket.opened() returns failure, the callback
+ // BluetoothSocketCallback.openedComplete() must not be called.
+ EXPECT_EQ(open_cb_future.wait_for(timeout), std::future_status::timeout);
+ }
+}
+
+TEST_P(BluetoothSocketTest, Closed) {
+ std::promise<void> open_cb_promise;
+ std::future<void> open_cb_future{open_cb_promise.get_future()};
+ std::shared_ptr<BluetoothSocketCallback> callback =
+ ndk::SharedRefBase::make<BluetoothSocketCallback>(
+ [&open_cb_promise](auto /* socket_id */, auto /* status */,
+ auto /* reason */) {
+ open_cb_promise.set_value();
+ });
+ bluetooth_socket_->registerCallback(callback);
+ SocketCapabilities socket_capabilities;
+ bluetooth_socket_->getSocketCapabilities(&socket_capabilities);
+
+ long socket_id = 1;
+ bluetooth_socket_->closed(socket_id);
+}
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BluetoothSocketTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, BluetoothSocketTest,
+ testing::ValuesIn(android::getAidlHalInstanceNames(
+ IBluetoothSocket::descriptor)),
+ android::PrintInstanceNameToString);
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ABinderProcess_startThreadPool();
+ int status = RUN_ALL_TESTS();
+ ALOGI("Test result = %d", status);
+ return status;
+}
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 5ec8d70..8a3efa7 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -139,6 +139,14 @@
</interface>
</hal>
<hal format="aidl">
+ <name>android.hardware.bluetooth.socket</name>
+ <version>1</version>
+ <interface>
+ <name>IBluetoothSocket</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="aidl">
<name>android.hardware.bluetooth.finder</name>
<version>1</version>
<interface>
@@ -607,7 +615,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.tv.input</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>ITvInput</name>
<instance>default</instance>
diff --git a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
index cd47374..5b3a433 100644
--- a/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
+++ b/graphics/composer/2.2/utils/command-buffer/include/composer-command-buffer/2.2/ComposerCommandBuffer.h
@@ -17,19 +17,13 @@
#pragma once
#ifndef LOG_TAG
-#warn "ComposerCommandBuffer.h included without LOG_TAG"
+#warning "ComposerCommandBuffer.h included without LOG_TAG"
#endif
//#define LOG_NDEBUG 0
-#include <algorithm>
-#include <limits>
-#include <memory>
#include <vector>
-#include <inttypes.h>
-#include <string.h>
-
#include <android/hardware/graphics/composer/2.2/IComposer.h>
#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <fmq/MessageQueue.h>
@@ -82,7 +76,7 @@
void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
beginCommand(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
- metadataVec.size() * 2);
+ static_cast<uint16_t>(metadataVec.size() * 2));
for (const auto& metadata : metadataVec) {
writeSigned(static_cast<int32_t>(metadata.key));
writeFloat(metadata.value);
diff --git a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
index 1a9276c..46d8d4a 100644
--- a/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
+++ b/graphics/composer/2.3/utils/command-buffer/include/composer-command-buffer/2.3/ComposerCommandBuffer.h
@@ -17,7 +17,7 @@
#pragma once
#ifndef LOG_TAG
-#warn "ComposerCommandBuffer.h included without LOG_TAG"
+#warning "ComposerCommandBuffer.h included without LOG_TAG"
#endif
//#define LOG_NDEBUG 0
@@ -46,7 +46,7 @@
public:
void setLayerPerFrameMetadata(const hidl_vec<IComposerClient::PerFrameMetadata>& metadataVec) {
beginCommand(IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
- metadataVec.size() * 2);
+ static_cast<uint16_t>(metadataVec.size() * 2));
for (const auto& metadata : metadataVec) {
writeSigned(static_cast<int32_t>(metadata.key));
writeFloat(metadata.value);
diff --git a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
index e981da6..064fc57 100644
--- a/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
+++ b/graphics/composer/2.4/utils/command-buffer/include/composer-command-buffer/2.4/ComposerCommandBuffer.h
@@ -17,7 +17,7 @@
#pragma once
#ifndef LOG_TAG
-#warn "ComposerCommandBuffer.h included without LOG_TAG"
+#warning "ComposerCommandBuffer.h included without LOG_TAG"
#endif
//#define LOG_NDEBUG 0
@@ -63,16 +63,17 @@
beginCommand(IComposerClient::Command::SET_LAYER_GENERIC_METADATA,
static_cast<uint16_t>(commandSize));
- write(key.size());
- writeBlob(key.size(), reinterpret_cast<const unsigned char*>(key.c_str()));
+ write(static_cast<uint32_t>(key.size()));
+ writeBlob(static_cast<uint32_t>(key.size()),
+ reinterpret_cast<const unsigned char*>(key.c_str()));
write(mandatory);
- write(value.size());
- writeBlob(value.size(), value.data());
+ write(static_cast<uint32_t>(value.size()));
+ writeBlob(static_cast<uint32_t>(value.size()), value.data());
endCommand();
}
protected:
- uint32_t sizeToElements(uint32_t size) { return (size + 3) / 4; }
+ uint32_t sizeToElements(size_t size) { return static_cast<uint32_t>((size + 3) / 4); }
};
// This class helps parse a command queue. Note that all sizes/lengths are in
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
index de92105..a38156a 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomParams.aidl
@@ -36,14 +36,9 @@
parcelable CpuHeadroomParams {
android.hardware.power.CpuHeadroomParams.CalculationType calculationType = android.hardware.power.CpuHeadroomParams.CalculationType.MIN;
int calculationWindowMillis = 1000;
- android.hardware.power.CpuHeadroomParams.SelectionType selectionType = android.hardware.power.CpuHeadroomParams.SelectionType.ALL;
int[] tids;
enum CalculationType {
MIN,
AVERAGE,
}
- enum SelectionType {
- ALL,
- PER_CORE,
- }
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomResult.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomResult.aidl
index 9303906..21b1e69 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomResult.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/CpuHeadroomResult.aidl
@@ -35,5 +35,4 @@
@JavaDerive(equals=true, toString=true) @VintfStability
union CpuHeadroomResult {
float globalHeadroom;
- float[] perCoreHeadroom;
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
index 9d20ca1..080c0bd 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/IPower.aidl
@@ -46,8 +46,6 @@
android.hardware.power.SupportInfo getSupportInfo();
android.hardware.power.CpuHeadroomResult getCpuHeadroom(in android.hardware.power.CpuHeadroomParams params);
android.hardware.power.GpuHeadroomResult getGpuHeadroom(in android.hardware.power.GpuHeadroomParams params);
- long getCpuHeadroomMinIntervalMillis();
- long getGpuHeadroomMinIntervalMillis();
oneway void sendCompositionData(in android.hardware.power.CompositionData[] data);
oneway void sendCompositionUpdate(in android.hardware.power.CompositionUpdate update);
}
diff --git a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl
index 9609169..c90125c 100644
--- a/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl
+++ b/power/aidl/aidl_api/android.hardware.power/current/android/hardware/power/SupportInfo.aidl
@@ -41,6 +41,7 @@
long sessionModes;
long sessionTags;
android.hardware.power.SupportInfo.CompositionDataSupportInfo compositionData;
+ android.hardware.power.SupportInfo.HeadroomSupportInfo headroom;
@VintfStability
parcelable CompositionDataSupportInfo {
boolean isSupported;
@@ -48,4 +49,11 @@
int maxBatchSize;
boolean alwaysBatch;
}
+ @VintfStability
+ parcelable HeadroomSupportInfo {
+ boolean isCpuSupported;
+ boolean isGpuSupported;
+ int cpuMinIntervalMillis;
+ int gpuMinIntervalMillis;
+ }
}
diff --git a/power/aidl/android/hardware/power/CpuHeadroomParams.aidl b/power/aidl/android/hardware/power/CpuHeadroomParams.aidl
index 64c7b44..fab8f43 100644
--- a/power/aidl/android/hardware/power/CpuHeadroomParams.aidl
+++ b/power/aidl/android/hardware/power/CpuHeadroomParams.aidl
@@ -42,21 +42,6 @@
int calculationWindowMillis = 1000;
/**
- * Defines how to select the CPU.
- */
- enum SelectionType {
- // Default to return a single value for all cores.
- ALL,
- // Returns per-core headroom in a list.
- PER_CORE,
- }
-
- /**
- * The CPU selection type.
- */
- SelectionType selectionType = SelectionType.ALL;
-
- /**
* The thread TIDs to track.
*
* If tids are not-empty, return the headrooms only for cores that are available
diff --git a/power/aidl/android/hardware/power/CpuHeadroomResult.aidl b/power/aidl/android/hardware/power/CpuHeadroomResult.aidl
index 316d5f6..e7ed8b6 100644
--- a/power/aidl/android/hardware/power/CpuHeadroomResult.aidl
+++ b/power/aidl/android/hardware/power/CpuHeadroomResult.aidl
@@ -29,8 +29,4 @@
* If ALL selection type is requested.
*/
float globalHeadroom;
- /**
- * If PER_CORE selection type is requested.
- */
- float[] perCoreHeadroom;
}
diff --git a/power/aidl/android/hardware/power/IPower.aidl b/power/aidl/android/hardware/power/IPower.aidl
index 41a9379..ce61af4 100644
--- a/power/aidl/android/hardware/power/IPower.aidl
+++ b/power/aidl/android/hardware/power/IPower.aidl
@@ -181,26 +181,6 @@
GpuHeadroomResult getGpuHeadroom(in GpuHeadroomParams params);
/**
- * Minimum polling interval for calling getCpuHeadroom in milliseconds.
- *
- * The getCpuHeadroom API may return cached result if called more frequent
- * than the interval.
- *
- * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported.
- */
- long getCpuHeadroomMinIntervalMillis();
-
- /**
- * Minimum polling interval for calling getGpuHeadroom in milliseconds.
- *
- * The getGpuHeadroom API may return cached result if called more frequent
- * than the interval.
- *
- * @throws EX_UNSUPPORTED_OPERATION if the API is unsupported.
- */
- long getGpuHeadroomMinIntervalMillis();
-
- /**
* Sent to PowerHAL when there are surface-attached sessions being composed,
* providing FPS and frame timing data that can be used to supplement
* and validate timing sent via reportActual. This call can be batched,
diff --git a/power/aidl/android/hardware/power/SupportInfo.aidl b/power/aidl/android/hardware/power/SupportInfo.aidl
index 4178b3a..55287cb 100644
--- a/power/aidl/android/hardware/power/SupportInfo.aidl
+++ b/power/aidl/android/hardware/power/SupportInfo.aidl
@@ -77,6 +77,11 @@
*/
CompositionDataSupportInfo compositionData;
+ /**
+ * Parcel detailing support info for headroom information.
+ */
+ HeadroomSupportInfo headroom;
+
@VintfStability
parcelable CompositionDataSupportInfo {
/**
@@ -106,4 +111,33 @@
*/
boolean alwaysBatch;
}
+
+ @VintfStability
+ parcelable HeadroomSupportInfo {
+ /**
+ * Whether the CPU headroom feature is supported.
+ */
+ boolean isCpuSupported;
+
+ /**
+ * Whether the GPU headroom feature is supported.
+ */
+ boolean isGpuSupported;
+
+ /**
+ * Minimum polling interval for calling getCpuHeadroom in milliseconds
+ *
+ * The getCpuHeadroom API may return cached result if called more frequent
+ * than the interval.
+ */
+ int cpuMinIntervalMillis;
+
+ /**
+ * Minimum polling interval for calling getGpuHeadroom in milliseconds.
+ *
+ * The getGpuHeadroom API may return cached result if called more frequent
+ * than the interval.
+ */
+ int gpuMinIntervalMillis;
+ }
}
diff --git a/power/aidl/default/Power.cpp b/power/aidl/default/Power.cpp
index 8490b62..0a9c90f 100644
--- a/power/aidl/default/Power.cpp
+++ b/power/aidl/default/Power.cpp
@@ -71,33 +71,12 @@
return ScopedAStatus::ok();
}
-ndk::ScopedAStatus Power::getCpuHeadroom(const CpuHeadroomParams& params,
- CpuHeadroomResult* _aidl_return) {
- if (params.selectionType == CpuHeadroomParams::SelectionType::ALL) {
- _aidl_return->set<CpuHeadroomResult::globalHeadroom>(100.0f);
- return ndk::ScopedAStatus::ok();
- } else if (params.selectionType == CpuHeadroomParams::SelectionType::PER_CORE) {
- std::vector<float> headroom = {50.0f, 100.0f};
- _aidl_return->set<CpuHeadroomResult::perCoreHeadroom>(headroom);
- return ndk::ScopedAStatus::ok();
- }
+ndk::ScopedAStatus Power::getCpuHeadroom(const CpuHeadroomParams&, CpuHeadroomResult*) {
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
-ndk::ScopedAStatus Power::getGpuHeadroom(const GpuHeadroomParams& _,
- GpuHeadroomResult* _aidl_return) {
- _aidl_return->set<GpuHeadroomResult::globalHeadroom>(100.0f);
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus Power::getCpuHeadroomMinIntervalMillis(int64_t* _aidl_return) {
- *_aidl_return = 1000;
- return ndk::ScopedAStatus::ok();
-}
-
-ndk::ScopedAStatus Power::getGpuHeadroomMinIntervalMillis(int64_t* _aidl_return) {
- *_aidl_return = 1000;
- return ndk::ScopedAStatus::ok();
+ndk::ScopedAStatus Power::getGpuHeadroom(const GpuHeadroomParams&, GpuHeadroomResult*) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
}
ScopedAStatus Power::createHintSession(int32_t, int32_t, const std::vector<int32_t>& tids, int64_t,
@@ -163,6 +142,12 @@
.disableGpuFences = false,
.maxBatchSize = 1,
.alwaysBatch = false,
+ },
+ .headroom = {
+ .isCpuSupported = false,
+ .isGpuSupported = false,
+ .cpuMinIntervalMillis = 0,
+ .gpuMinIntervalMillis = 0,
}};
// Copy the support object into the binder
*_aidl_return = supportInfo;
diff --git a/power/aidl/default/Power.h b/power/aidl/default/Power.h
index c4aa7ab..118097f 100644
--- a/power/aidl/default/Power.h
+++ b/power/aidl/default/Power.h
@@ -50,8 +50,6 @@
ndk::ScopedAStatus getGpuHeadroom(const GpuHeadroomParams& params,
GpuHeadroomResult* _aidl_return) override;
- ndk::ScopedAStatus getCpuHeadroomMinIntervalMillis(int64_t* _aidl_return) override;
- ndk::ScopedAStatus getGpuHeadroomMinIntervalMillis(int64_t* _aidl_return) override;
ndk::ScopedAStatus sendCompositionData(const std::vector<CompositionData>& in_data) override;
ndk::ScopedAStatus sendCompositionUpdate(const CompositionUpdate& in_update) override;
diff --git a/power/aidl/vts/VtsHalPowerTargetTest.cpp b/power/aidl/vts/VtsHalPowerTargetTest.cpp
index ffe20c6..87797ae 100644
--- a/power/aidl/vts/VtsHalPowerTargetTest.cpp
+++ b/power/aidl/vts/VtsHalPowerTargetTest.cpp
@@ -141,13 +141,13 @@
power = IPower::fromBinder(ndk::SpAIBinder(binder));
auto status = power->getInterfaceVersion(&mServiceVersion);
ASSERT_TRUE(status.isOk());
+ if (mServiceVersion >= 2) {
+ status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &mSession);
+ mSessionSupport = status.isOk();
+ }
if (mServiceVersion >= 6) {
mSupportInfo = std::make_optional<SupportInfo>();
ASSERT_TRUE(power->getSupportInfo(&(*mSupportInfo)).isOk());
- mSessionSupport = mSupportInfo->usesSessions;
- } else if (mServiceVersion >= 2) {
- status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &mSession);
- mSessionSupport = status.isOk();
}
}
@@ -311,13 +311,12 @@
CpuHeadroomParams params;
CpuHeadroomResult headroom;
auto ret = power->getCpuHeadroom(params, &headroom);
- if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ if (!mSupportInfo->headroom.isCpuSupported) {
+ ASSERT_EQ(ret.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
GTEST_SKIP() << "power->getCpuHeadroom is not supported";
}
ASSERT_TRUE(ret.isOk());
- int64_t minIntervalMillis;
- ASSERT_TRUE(power->getCpuHeadroomMinIntervalMillis(&minIntervalMillis).isOk());
- ASSERT_GE(minIntervalMillis, 0);
+ ASSERT_GE(mSupportInfo->headroom.cpuMinIntervalMillis, 0);
ASSERT_EQ(headroom.getTag(), CpuHeadroomResult::globalHeadroom);
ASSERT_GE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 0.0f);
ASSERT_LE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 100.00f);
@@ -330,13 +329,12 @@
GpuHeadroomParams params;
GpuHeadroomResult headroom;
auto ret = power->getGpuHeadroom(params, &headroom);
- if (ret.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
+ if (!mSupportInfo->headroom.isGpuSupported) {
+ ASSERT_EQ(ret.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
GTEST_SKIP() << "power->getGpuHeadroom is not supported";
}
ASSERT_TRUE(ret.isOk());
- int64_t minIntervalMillis;
- ASSERT_TRUE(power->getGpuHeadroomMinIntervalMillis(&minIntervalMillis).isOk());
- ASSERT_GE(minIntervalMillis, 0);
+ ASSERT_GE(mSupportInfo->headroom.gpuMinIntervalMillis, 0);
ASSERT_EQ(headroom.getTag(), GpuHeadroomResult::globalHeadroom);
ASSERT_GE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 0.0f);
ASSERT_LE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 100.00f);
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
index 37737a7..a6fd27a 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetwork.aidl
@@ -92,4 +92,7 @@
oneway void setCellularIdentifierTransparencyEnabled(in int serial, in boolean enabled);
oneway void setSecurityAlgorithmsUpdatedEnabled(in int serial, boolean enable);
oneway void isSecurityAlgorithmsUpdatedEnabled(in int serial);
+ oneway void setSatellitePlmn(in int serial, in int simSlot, in String[] carrierPlmnArray, in String[] allSatellitePlmnArray);
+ oneway void setSatelliteEnabledForCarrier(in int serial, in int simSlot, boolean satelliteEnabled);
+ oneway void isSatelliteEnabledForCarrier(in int serial, in int simSlot);
}
diff --git a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 4c6d100..080b4aa 100644
--- a/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/aidl_api/android.hardware.radio.network/current/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -91,4 +91,7 @@
oneway void setCellularIdentifierTransparencyEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void setSecurityAlgorithmsUpdatedEnabledResponse(in android.hardware.radio.RadioResponseInfo info);
oneway void isSecurityAlgorithmsUpdatedEnabledResponse(in android.hardware.radio.RadioResponseInfo info, in boolean isEnabled);
+ oneway void setSatellitePlmnResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void setSatelliteEnabledForCarrierResponse(in android.hardware.radio.RadioResponseInfo info);
+ oneway void isSatelliteEnabledForCarrierResponse(in android.hardware.radio.RadioResponseInfo info, boolean isEnabled);
}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
index 41bac17..68e4829 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl
@@ -717,4 +717,60 @@
* This is available when android.hardware.telephony.access is defined.
*/
void isSecurityAlgorithmsUpdatedEnabled(in int serial);
+
+ /**
+ * Set the non-terrestrial PLMN with lower priority than terrestrial networks.
+ * MCC/MNC broadcast by the non-terrestrial networks may not be included in OPLMNwACT file on
+ * SIM profile. Acquisition of satellite based system is lower priority to terrestrial
+ * networks. UE shall make all attempts to acquire terrestrial service prior to camping on
+ * satellite LTE service.
+ *
+ * @param serial Serial number of request
+ * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use
+ * this information to determine the relevant carrier.
+ * @param carrierPlmnArray Array of roaming PLMN used for connecting to satellite networks
+ * supported by user subscription.
+ * @param allSatellitePlmnArray allSatellitePlmnArray contains all the PLMNs present in
+ * carrierPlmnArray and also list of satellite PLMNs that are not
+ * supported by the carrier.
+ * Modem should use the allSatellitePlmnArray to identify satellite
+ * PLMNs that are not supported by the carrier and make sure not to
+ * attach to them.
+ *
+ * Response function is IRadioNetworkResponse.setSatellitePlmnResponse()
+ *
+ * This is available when android.hardware.telephony.radio.access is defined.
+ */
+ void setSatellitePlmn(in int serial, in int simSlot, in String[] carrierPlmnArray,
+ in String[] allSatellitePlmnArray);
+
+ /**
+ * Enable or disable satellite in the cellular modem associated with a carrier.
+ *
+ * Refer setSatellitePlmn for the details of satellite PLMN scanning process. Once modem is
+ * disabled, modem should not attach to any of the PLMNs present in allSatellitePlmnArray.
+ * If modem is enabled, modem should attach to only PLMNs present in carrierPlmnArray.
+ *
+ * @param serial Serial number of request
+ * @param simSlot Indicates the SIM slot to which this API will be applied. The modem will use
+ * this information to determine the relevant carrier.
+ * @param satelliteEnabled {@code true} to enable satellite, {@code false} to disable satellite.
+ *
+ * Response function is IRadioNetworkResponse.setSatelliteEnabledForCarrier()
+ *
+ * This is available when android.hardware.telephony.radio.access is defined.
+ */
+ void setSatelliteEnabledForCarrier(in int serial, in int simSlot, boolean satelliteEnabled);
+
+ /**
+ * Check whether satellite is enabled in the cellular modem associated with a carrier.
+ *
+ * @param serial Serial number of request
+ * @param simSlot Indicates the SIM slot to which this API will be applied.
+ *
+ * Response function is IRadioNetworkResponse.isSatelliteEnabledForCarrier()
+ *
+ * This is available when android.hardware.telephony.radio.access is defined.
+ */
+ void isSatelliteEnabledForCarrier(in int serial, in int simSlot);
}
diff --git a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
index 92be4b5..4c1a394 100644
--- a/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
+++ b/radio/aidl/android/hardware/radio/network/IRadioNetworkResponse.aidl
@@ -816,4 +816,53 @@
*/
void isSecurityAlgorithmsUpdatedEnabledResponse(
in RadioResponseInfo info, in boolean isEnabled);
+
+ /**
+ * Response of setSatellitePlmn.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ *
+ * Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_STATE
+ */
+ void setSatellitePlmnResponse(in RadioResponseInfo info);
+
+ /**
+ * Response of setSatelliteEnabledForCarrier.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ *
+ * Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_STATE
+ */
+ void setSatelliteEnabledForCarrierResponse(in RadioResponseInfo info);
+
+ /**
+ * Response of isSatelliteEnabledForCarrier.
+ * This is an optional API.
+ *
+ * @param info Response info struct containing response type, serial no. and error.
+ * @param isEnabled Indicates whether satellite is enabled for carrier or not.
+ *
+ * Valid errors returned:
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:REQUEST_NOT_SUPPORTED
+ * RadioError:INVALID_STATE
+ */
+ void isSatelliteEnabledForCarrierResponse(in RadioResponseInfo info, boolean isEnabled);
}
diff --git a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
index 56724ae..c9a3270 100644
--- a/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
+++ b/radio/aidl/compat/libradiocompat/include/libradiocompat/RadioNetwork.h
@@ -114,6 +114,13 @@
::ndk::ScopedAStatus setSecurityAlgorithmsUpdatedEnabled(int32_t serial, bool enabled) override;
::ndk::ScopedAStatus isSecurityAlgorithmsUpdatedEnabled(int32_t serial) override;
+ ::ndk::ScopedAStatus setSatellitePlmn(
+ int32_t serial, int32_t simSlot, const std::vector<std::string>& carrierPlmnArray,
+ const std::vector<std::string>& allSatellitePlmnArray) override;
+ ::ndk::ScopedAStatus setSatelliteEnabledForCarrier(int32_t serial, int32_t simSlot,
+ bool satelliteEnabled) override;
+ ::ndk::ScopedAStatus isSatelliteEnabledForCarrier(int32_t serial, int32_t simSlot) override;
+
protected:
std::shared_ptr<::aidl::android::hardware::radio::network::IRadioNetworkResponse> respond();
diff --git a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
index 1e43789..b5aee5c 100644
--- a/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
+++ b/radio/aidl/compat/libradiocompat/network/RadioNetwork.cpp
@@ -402,4 +402,28 @@
return ok();
}
+ScopedAStatus RadioNetwork::setSatellitePlmn(
+ int32_t serial, int32_t /*simSlot*/, const std::vector<std::string>& /*carrierPlmnArray*/,
+ const std::vector<std::string>& /*allSatellitePlmnArray*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " setSatellitePlmn is unsupported by HIDL HALs";
+ respond()->setSatellitePlmnResponse(notSupported(serial));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::setSatelliteEnabledForCarrier(int32_t serial, int32_t /*simSlot*/,
+ bool /*enable*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " setSatelliteEnabledForCarrier is unsupported by HIDL HALs";
+ respond()->setSatelliteEnabledForCarrierResponse(notSupported(serial));
+ return ok();
+}
+
+ScopedAStatus RadioNetwork::isSatelliteEnabledForCarrier(int32_t serial, int32_t /*simSlot*/) {
+ LOG_CALL << serial;
+ LOG(ERROR) << " isSatelliteEnabledForCarrier is unsupported by HIDL HALs";
+ respond()->isSatelliteEnabledForCarrierResponse(notSupported(serial), false);
+ return ok();
+}
+
} // namespace android::hardware::radio::compat
diff --git a/radio/aidl/vts/radio_network_response.cpp b/radio/aidl/vts/radio_network_response.cpp
index 4d452d0..df59687 100644
--- a/radio/aidl/vts/radio_network_response.cpp
+++ b/radio/aidl/vts/radio_network_response.cpp
@@ -350,3 +350,24 @@
parent_network.notify(info.serial);
return ndk::ScopedAStatus::ok();
}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSatellitePlmnResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::setSatelliteEnabledForCarrierResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus RadioNetworkResponse::isSatelliteEnabledForCarrierResponse(
+ const RadioResponseInfo& info, bool enabled) {
+ rspInfo = info;
+ this->isSatelliteEnabledForCarrier = enabled;
+ parent_network.notify(info.serial);
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/radio/aidl/vts/radio_network_test.cpp b/radio/aidl/vts/radio_network_test.cpp
index 3d24165..1778c3f 100644
--- a/radio/aidl/vts/radio_network_test.cpp
+++ b/radio/aidl/vts/radio_network_test.cpp
@@ -2614,3 +2614,82 @@
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
}
+
+/*
+ * Test IRadioNetwork.setSatellitePlmn for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSatellitePlmn) {
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+ if (aidl_version < 4) {
+ ALOGI("Skipped the test since"
+ " setSatellitePlmn is not supported on version < 4");
+ GTEST_SKIP();
+ }
+
+ serial = GetRandomSerialNumber();
+ radio_network->setSatellitePlmn(serial, 0, {"123456"}, {"123456, 3456789"});
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+}
+
+/*
+ * Test IRadioNetwork.setSatelliteEnabledForCarrier for the response returned.
+ */
+TEST_P(RadioNetworkTest, setSatelliteEnabledForCarrier) {
+ int32_t aidl_version;
+ ndk::ScopedAStatus aidl_status = radio_network->getInterfaceVersion(&aidl_version);
+ ASSERT_OK(aidl_status);
+ if (aidl_version < 4) {
+ ALOGI("Skipped the test since"
+ " setSatelliteEnabledForCarrier is not supported on version < 4");
+ GTEST_SKIP();
+ }
+
+ // Get current value
+ serial = GetRandomSerialNumber();
+ radio_network->isSatelliteEnabledForCarrier(serial, 0);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ bool originalSatelliteEnabledSetting = radioRsp_network->isSatelliteEnabledForCarrier;
+
+ // We want to test flipping the value, so we are going to set it to the opposite of what
+ // the existing setting is. The test for isSatelliteEnabledForCarrier should check
+ // for the right default value.
+ bool valueToSet = !originalSatelliteEnabledSetting;
+ serial = GetRandomSerialNumber();
+ radio_network->setSatelliteEnabledForCarrier(serial, 0, valueToSet);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+
+ if (radioRsp_network->rspInfo.error == RadioError::NONE) {
+ // Assert the value has changed
+ serial = GetRandomSerialNumber();
+ ndk::ScopedAStatus res = radio_network->isSatelliteEnabledForCarrier(serial, 0);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_network->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::MODEM_ERR, RadioError::REQUEST_NOT_SUPPORTED}));
+ EXPECT_EQ(valueToSet, radioRsp_network->isSatelliteEnabledForCarrier);
+
+ // Reset original state
+ radio_network->setSatelliteEnabledForCarrier(serial, 0, originalSatelliteEnabledSetting);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_network->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_network->rspInfo.serial);
+ }
+}
diff --git a/radio/aidl/vts/radio_network_utils.h b/radio/aidl/vts/radio_network_utils.h
index ad530eb..17c0896 100644
--- a/radio/aidl/vts/radio_network_utils.h
+++ b/radio/aidl/vts/radio_network_utils.h
@@ -48,6 +48,7 @@
std::vector<RadioAccessSpecifier> specifiers;
bool isCellularIdentifierTransparencyEnabled = false;
bool isSecurityAlgorithmsUpdatedEnabled = false;
+ bool isSatelliteEnabledForCarrier = false;
virtual ndk::ScopedAStatus acknowledgeRequest(int32_t serial) override;
@@ -183,6 +184,14 @@
virtual ndk::ScopedAStatus setSecurityAlgorithmsUpdatedEnabledResponse(
const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus setSatellitePlmnResponse(const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus setSatelliteEnabledForCarrierResponse(
+ const RadioResponseInfo& info) override;
+
+ virtual ndk::ScopedAStatus isSatelliteEnabledForCarrierResponse(const RadioResponseInfo& info,
+ bool isEnabled) override;
};
/* Callback class for radio network indication */
diff --git a/tv/input/aidl/Android.bp b/tv/input/aidl/Android.bp
index afc811a..8d36ab1 100644
--- a/tv/input/aidl/Android.bp
+++ b/tv/input/aidl/Android.bp
@@ -45,5 +45,5 @@
},
],
- frozen: true,
+ frozen: false,
}
diff --git a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
index 84fe2fb..2ff2719 100644
--- a/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
+++ b/tv/input/aidl/aidl_api/android.hardware.tv.input/current/android/hardware/tv/input/ITvInput.aidl
@@ -40,6 +40,8 @@
void setCallback(in android.hardware.tv.input.ITvInputCallback callback);
void setTvMessageEnabled(int deviceId, int streamId, in android.hardware.tv.input.TvMessageEventType type, boolean enabled);
void getTvMessageQueueDesc(out android.hardware.common.fmq.MQDescriptor<byte,android.hardware.common.fmq.SynchronizedReadWrite> queue, int deviceId, int streamId);
+ void setPictureProfileId(in int deviceId, in int streamId, in long profileId);
+ void setSoundProfileId(in int deviceId, in int streamId, in long profileId);
const int STATUS_UNKNOWN = 1;
const int STATUS_NO_RESOURCE = 2;
const int STATUS_INVALID_ARGUMENTS = 3;
diff --git a/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
index c63e0ac..e57edf9 100644
--- a/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
+++ b/tv/input/aidl/android/hardware/tv/input/ITvInput.aidl
@@ -109,4 +109,28 @@
*/
void getTvMessageQueueDesc(
out MQDescriptor<byte, SynchronizedReadWrite> queue, int deviceId, int streamId);
+
+ /**
+ * Set the picture profile ID for a specific stream in a device.
+ *
+ * @param deviceId Device ID for the stream to use the profile.
+ * @param streamId Stream ID for the stream to use the profile. Must be one of the
+ * stream IDs returned from getStreamConfigurations().
+ * @param profileId Picture profile ID for the stream. The ID is assigned by the framework,
+ * and can be set by applications or TV input framework. See
+ * android.media.quality.PictureQuality for more details.
+ */
+ void setPictureProfileId(in int deviceId, in int streamId, in long profileId);
+
+ /**
+ * Set the sound profile ID for a specific stream in a device.
+ *
+ * @param deviceId Device ID for the stream to use the profile.
+ * @param streamId Stream ID for the stream to use the profile. Must be one of the
+ * stream IDs returned from getStreamConfigurations().
+ * @param profileId Sound profile ID for the stream. The ID is assigned by the framework,
+ * and can be set by applications or TV input framework. See
+ * android.media.quality.SoundQuality for more details.
+ */
+ void setSoundProfileId(in int deviceId, in int streamId, in long profileId);
}
diff --git a/wifi/aidl/android/hardware/wifi/PasnConfig.aidl b/wifi/aidl/android/hardware/wifi/PasnConfig.aidl
index 4c6b5bf..37ef03c 100644
--- a/wifi/aidl/android/hardware/wifi/PasnConfig.aidl
+++ b/wifi/aidl/android/hardware/wifi/PasnConfig.aidl
@@ -22,12 +22,13 @@
@VintfStability
parcelable PasnConfig {
/**
- * Base Authentication and Key Management (AKM) protocol used for PASN as defined in |Akm|.
+ * Base Authentication and Key Management (AKM) protocol used for PASN. Represented as
+ * at bitmap of |Akm|.
*/
long baseAkm;
/**
- * Pairwise cipher suite used for the PTKSA (Pairwise Transient Key Security Association)
- * as defined in |CipherSuite|
+ * Pairwise cipher suite used for the PTKSA (Pairwise Transient Key Security Association).
+ * Represented as a bitmap of |CipherSuite|.
*/
long cipherSuite;
/**
diff --git a/wifi/aidl/android/hardware/wifi/RttResult.aidl b/wifi/aidl/android/hardware/wifi/RttResult.aidl
index 16b823d..361d7e9 100644
--- a/wifi/aidl/android/hardware/wifi/RttResult.aidl
+++ b/wifi/aidl/android/hardware/wifi/RttResult.aidl
@@ -222,12 +222,13 @@
*/
boolean isSecureLtfEnabled;
/**
- * Base Authentication and Key Management (AKM) protocol used for PASN as defined in |Akm|.
+ * Base Authentication and Key Management (AKM) protocol used for PASN. Represented as
+ * at bitmap of |Akm|.
*/
long baseAkm;
/**
- * Pairwise cipher suite used for the PTKSA (Pairwise Transient Key Security Association)
- * as defined in |CipherSuite|
+ * Pairwise cipher suite used for the PTKSA (Pairwise Transient Key Security Association).
+ * Represented as a bitmap of |CipherSuite|.
*/
long cipherSuite;
/**
diff --git a/wifi/hostapd/aidl/Android.bp b/wifi/hostapd/aidl/Android.bp
index e580573..85d71f3 100644
--- a/wifi/hostapd/aidl/Android.bp
+++ b/wifi/hostapd/aidl/Android.bp
@@ -41,7 +41,9 @@
],
min_sdk_version: "30",
lint: {
- baseline_filename: "lint-baseline.xml",
+ // Disable linter to avoid error about fixed size arrays.
+ // Interface will only be accessed on devices >= T.
+ enabled: false,
},
},
ndk: {
diff --git a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
index f8320c6..0af90d2 100644
--- a/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
+++ b/wifi/hostapd/aidl/aidl_api/android.hardware.wifi.hostapd/current/android/hardware/wifi/hostapd/ApInfo.aidl
@@ -41,5 +41,5 @@
android.hardware.wifi.hostapd.Generation generation;
byte[] apIfaceInstanceMacAddress;
@nullable android.hardware.wifi.common.OuiKeyedData[] vendorData;
- @nullable byte[] mldMacAddress;
+ @nullable byte[6] mldMacAddress;
}
diff --git a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
index 4e1e1c8..8aea70c 100644
--- a/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
+++ b/wifi/hostapd/aidl/android/hardware/wifi/hostapd/ApInfo.aidl
@@ -67,5 +67,5 @@
/**
* MAC Address of the multiple link device (MLD) which apIfaceInstance is associated with.
*/
- @nullable byte[] mldMacAddress;
+ @nullable byte[6] mldMacAddress;
}