Merge "Updates to VMS Utils to support HAL Client Publisher"
diff --git a/atrace/1.0/default/AtraceDevice.cpp b/atrace/1.0/default/AtraceDevice.cpp
index 43bcd9a..35d11e9 100644
--- a/atrace/1.0/default/AtraceDevice.cpp
+++ b/atrace/1.0/default/AtraceDevice.cpp
@@ -30,24 +30,25 @@
struct TracingConfig {
std::string description;
+ // path and if error on failure
std::vector<std::pair<std::string, bool>> paths;
};
// This is a map stores categories and their sysfs paths with required flags
const std::map<std::string, TracingConfig> kTracingMap = {
- // gfx
- {
- "gfx",
- {"Graphics",
- {{"/sys/kernel/debug/tracing/events/mdss/enable", false},
- {"/sys/kernel/debug/tracing/events/sde/enable", false},
- {"/sys/kernel/debug/tracing/events/mali_systrace/enable", false}}},
- },
- {
- "ion",
- {"ION allocation",
- {{"/sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable", true}}},
- },
+ // gfx
+ {
+ "gfx",
+ {"Graphics",
+ {{"/sys/kernel/debug/tracing/events/mdss/enable", false},
+ {"/sys/kernel/debug/tracing/events/sde/enable", false},
+ {"/sys/kernel/debug/tracing/events/mali_systrace/enable", false}}},
+ },
+ {
+ "ion",
+ {"ION allocation",
+ {{"/sys/kernel/debug/tracing/events/kmem/ion_alloc_buffer_start/enable", false}}},
+ },
};
// Methods from ::android::hardware::atrace::V1_0::IAtraceDevice follow.
diff --git a/camera/device/3.5/types.hal b/camera/device/3.5/types.hal
index f98c603..6d861e2 100644
--- a/camera/device/3.5/types.hal
+++ b/camera/device/3.5/types.hal
@@ -21,6 +21,14 @@
import @3.2::CameraBlobId;
/**
+ * If the result metadata cannot be produced for a physical camera device part of a logical
+ * multi-camera, then HAL must invoke the notification callback and pass a message with ERROR_RESULT
+ * code and errorStreamId that contains the stream id associated with that physical device.
+ * The behavior during absent result metadata remains unchanged for a logical or a non-logical
+ * camera device and the errorStreamId must be set to -1.
+ */
+
+/**
* StreamConfiguration:
*
* Identical to @3.4::StreamConfiguration, except that it contains streamConfigCounter
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index d77bb0e..5dfc783 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -767,7 +767,7 @@
const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& metadata);
void verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
- bool expectedStatus);
+ bool expectedStatus, bool expectStreamCombQuery);
void verifyLogicalCameraResult(const camera_metadata_t* staticMetadata,
const ::android::hardware::camera::common::V1_0::helper::CameraMetadata& resultMetadata);
@@ -2877,8 +2877,9 @@
createStreamConfiguration(streams3_2, StreamConfigurationMode::NORMAL_MODE,
&config3_2, &config3_4, &config3_5, jpegBufferSize);
if (session3_5 != nullptr) {
+ bool expectStreamCombQuery = (isLogicalMultiCamera(staticMeta) == Status::OK);
verifyStreamCombination(cameraDevice3_5, config3_4,
- /*expectedStatus*/ true);
+ /*expectedStatus*/ true, expectStreamCombQuery);
config3_5.streamConfigCounter = streamConfigCounter++;
ret = session3_5->configureStreams_3_5(config3_5,
[streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -2971,7 +2972,8 @@
createStreamConfiguration(streams, StreamConfigurationMode::NORMAL_MODE,
&config3_2, &config3_4, &config3_5, jpegBufferSize);
if (session3_5 != nullptr) {
- verifyStreamCombination(cameraDevice3_5, config3_4, /*expectedStatus*/ false);
+ verifyStreamCombination(cameraDevice3_5, config3_4, /*expectedStatus*/ false,
+ /*expectStreamCombQuery*/false);
config3_5.streamConfigCounter = streamConfigCounter++;
ret = session3_5->configureStreams_3_5(config3_5,
[](Status s, device::V3_4::HalStreamConfiguration) {
@@ -3232,7 +3234,7 @@
&config3_2, &config3_4, &config3_5, jpegBufferSize);
if (session3_5 != nullptr) {
verifyStreamCombination(cameraDevice3_5, config3_4,
- /*expectedStatus*/ true);
+ /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
config3_5.streamConfigCounter = streamConfigCounter++;
ret = session3_5->configureStreams_3_5(config3_5,
[](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -3483,7 +3485,7 @@
&config3_2, &config3_4, &config3_5, jpegBufferSize);
if (session3_5 != nullptr) {
verifyStreamCombination(cameraDevice3_5, config3_4,
- /*expectedStatus*/ true);
+ /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
config3_5.streamConfigCounter = streamConfigCounter++;
ret = session3_5->configureStreams_3_5(config3_5,
[](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -3578,7 +3580,7 @@
&config3_2, &config3_4, &config3_5);
if (session3_5 != nullptr) {
verifyStreamCombination(cameraDevice3_5, config3_4,
- /*expectedStatus*/ true);
+ /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
config3_5.streamConfigCounter = streamConfigCounter++;
ret = session3_5->configureStreams_3_5(config3_5,
[streamId](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -3811,7 +3813,7 @@
&config3_2, &config3_4, &config3_5, jpegBufferSize);
if (session3_5 != nullptr) {
verifyStreamCombination(cameraDevice3_5, config3_4,
- /*expectedStatus*/ true);
+ /*expectedStatus*/ true, /*expectStreamCombQuery*/ false);
config3_5.streamConfigCounter = streamConfigCounter++;
ret = session3_5->configureStreams_3_5(config3_5,
[](Status s, device::V3_4::HalStreamConfiguration halConfig) {
@@ -5535,11 +5537,12 @@
void CameraHidlTest::verifyStreamCombination(sp<device::V3_5::ICameraDevice> cameraDevice3_5,
const ::android::hardware::camera::device::V3_4::StreamConfiguration &config3_4,
- bool expectedStatus) {
+ bool expectedStatus, bool expectMethodSupported) {
if (cameraDevice3_5.get() != nullptr) {
auto ret = cameraDevice3_5->isStreamCombinationSupported(config3_4,
- [expectedStatus] (Status s, bool combStatus) {
- ASSERT_TRUE((Status::OK == s) || (Status::METHOD_NOT_SUPPORTED == s));
+ [expectedStatus, expectMethodSupported] (Status s, bool combStatus) {
+ ASSERT_TRUE((Status::OK == s) ||
+ (!expectMethodSupported && Status::METHOD_NOT_SUPPORTED == s));
if (Status::OK == s) {
ASSERT_TRUE(combStatus == expectedStatus);
}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 566bd48..09cbc20 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -301,7 +301,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.nfc</name>
- <version>1.1</version>
+ <version>1.2</version>
<interface>
<name>INfc</name>
<instance>default</instance>
diff --git a/current.txt b/current.txt
index 96c1bbf..8518c5e 100644
--- a/current.txt
+++ b/current.txt
@@ -396,6 +396,8 @@
d702fb01dc2a0733aa820b7eb65435ee3334f75632ef880bafd2fb8803a20a58 android.hardware.gnss@1.0::IGnssMeasurementCallback
7c7721c0f773fcf422b71a4f558545e9e36acc973e58ca51e5bd53905cf46bc0 android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer
d4fea995378bb4f421b4e24ccf68cad2734ab07fe4f874a126ba558b99df5766 android.hardware.graphics.composer@2.1::IComposerClient
+f7d7cb747dc01a9fdb2d39a80003b4d8df9be733d65f5842198802eb6209db69 android.hardware.graphics.mapper@2.0::IMapper
+65a021fa89085b62fc96b2b6d3bef2f9103cf4d63379c68bc154fd9eef672852 android.hardware.health@1.0::types
b7ecf29927055ec422ec44bf776223f07d79ad9f92ccf9becf167e62c2607e7a android.hardware.keymaster@4.0::IKeymasterDevice
574e8f1499436fb4075894dcae0b36682427956ecb114f17f1fe22d116a83c6b android.hardware.neuralnetworks@1.0::IPreparedModel
417ab60fe1ef786778047e4486f3d868ebce570d91addd8fe4251515213072de android.hardware.neuralnetworks@1.0::types
@@ -446,7 +448,7 @@
09ab9b24994429d9bb32a3fb420b6f6be3e47eb655139a2c08c4e80d3f33ff95 android.hardware.camera.device@3.5::ICameraDevice
06237de53c42890029e3f8fe7d1480d078469c0d07608e51c37b4d485d342992 android.hardware.camera.device@3.5::ICameraDeviceCallback
08c68b196e2fc4e5ba67ba0d0917bde828a87cbe2cffec19d04733972da9eb49 android.hardware.camera.device@3.5::ICameraDeviceSession
-a848f7cb3cb3d080cf175bf08412322bfddb535168253796cdf777afdbf05b38 android.hardware.camera.device@3.5::types
+f9b8b388c0c76669e4b9189e4943efd2982f9bda5c10e276f96cc91bc8e818d6 android.hardware.camera.device@3.5::types
f727d5f350f55a6d3354aad2feb64e43200de77c10d9d642465566bc260bb8ec android.hardware.camera.metadata@3.4::types
0fb39a7809ad1c52b3efbbed5ef4749b06c2a4f1f19cdc3efa2e3d9b28f1205c android.hardware.camera.provider@2.5::ICameraProvider
f5777403d65135a5407723671bc7a864cdca83aea13ee3ce2894b95e6588ca3a android.hardware.camera.provider@2.5::types
@@ -512,7 +514,7 @@
92714960d1a53fc2ec557302b41c7cc93d2636d8364a44bd0f85be0c92927ff8 android.hardware.neuralnetworks@1.2::IExecutionCallback
36e1064c869965dee533c537cefbe87e54db8bd8cd45be7e0e93e00e8a43863a android.hardware.neuralnetworks@1.2::IPreparedModel
e1c734d1545e1a4ae749ff1dd9704a8e594c59aea7c8363159dc258e93e0df3b android.hardware.neuralnetworks@1.2::IPreparedModelCallback
-209a5ee694b94328afb2af2768f1fe6a69148e2cbb85ec3c340a36eed818c697 android.hardware.neuralnetworks@1.2::types
+9b3963253e521cca19fd81aeca83aee6dcfe3bdf2805c07cb2d3f64381709b71 android.hardware.neuralnetworks@1.2::types
cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
diff --git a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h
index 436e461..5826b12 100644
--- a/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h
+++ b/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h
@@ -162,6 +162,7 @@
Error destroyLayer(Display display, Layer layer) override {
int32_t err = mDispatch.destroyLayer(mDevice, display, layer);
+ onLayerDestroyed(display, layer);
return static_cast<Error>(err);
}
@@ -327,6 +328,7 @@
std::vector<IComposerClient::Composition>* outCompositionTypes,
uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
std::vector<uint32_t>* outRequestMasks) override {
+ onBeforeValidateDisplay(display);
uint32_t typesCount = 0;
uint32_t reqsCount = 0;
int32_t err = mDispatch.validateDisplay(mDevice, display, &typesCount, &reqsCount);
@@ -335,17 +337,15 @@
return static_cast<Error>(err);
}
- err = mDispatch.getChangedCompositionTypes(mDevice, display, &typesCount, nullptr, nullptr);
+ err = getChangedCompositionTypes(display, &typesCount, nullptr, nullptr);
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
std::vector<Layer> changedLayers(typesCount);
std::vector<IComposerClient::Composition> compositionTypes(typesCount);
- err = mDispatch.getChangedCompositionTypes(
- mDevice, display, &typesCount, changedLayers.data(),
- reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>(
- compositionTypes.data()));
+ err = getChangedCompositionTypes(display, &typesCount, changedLayers.data(),
+ compositionTypes.data());
if (err != HWC2_ERROR_NONE) {
return static_cast<Error>(err);
}
@@ -578,6 +578,15 @@
return true;
}
+ virtual int32_t getChangedCompositionTypes(Display display, uint32_t* outTypesCount,
+ Layer* outChangedLayers,
+ IComposerClient::Composition* outCompositionTypes) {
+ return getChangedCompositionTypesInternal(display, outTypesCount, outChangedLayers,
+ outCompositionTypes);
+ }
+ virtual void onLayerDestroyed(Display /* display */, Layer /* layer */) {}
+ virtual void onBeforeValidateDisplay(Display /* display */) {}
+
static void hotplugHook(hwc2_callback_data_t callbackData, hwc2_display_t display,
int32_t connected) {
auto hal = static_cast<HwcHalImpl*>(callbackData);
@@ -596,6 +605,15 @@
hal->mEventCallback->onVsync(display, timestamp);
}
+ int32_t getChangedCompositionTypesInternal(Display display, uint32_t* outTypesCount,
+ Layer* outChangedLayers,
+ IComposerClient::Composition* outCompositionTypes) {
+ return mDispatch.getChangedCompositionTypes(
+ mDevice, display, outTypesCount, outChangedLayers,
+ reinterpret_cast<std::underlying_type<IComposerClient::Composition>::type*>(
+ outCompositionTypes));
+ }
+
hwc2_device_t* mDevice = nullptr;
std::unordered_set<hwc2_capability_t> mCapabilities;
diff --git a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
index 070cf80..9d67e04 100644
--- a/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
+++ b/graphics/composer/2.3/utils/passthrough/include/composer-passthrough/2.3/HwcHal.h
@@ -42,6 +42,20 @@
using V2_1::Display;
using V2_1::Error;
+namespace {
+
+bool isIdentityMatrix(const float* matrix) {
+ if (matrix[0] == 1.0 && matrix[1] == 0.0 && matrix[2] == 0.0 && matrix[3] == 0.0 &&
+ matrix[4] == 0.0 && matrix[5] == 1.0 && matrix[6] == 0.0 && matrix[7] == 0.0 &&
+ matrix[8] == 0.0 && matrix[9] == 0.0 && matrix[10] == 1.0 && matrix[11] == 0.0 &&
+ matrix[12] == 0.0 && matrix[13] == 0.0 && matrix[14] == 0.0 && matrix[15] == 1.0) {
+ return true;
+ }
+ return false;
+}
+
+} // namespace
+
// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
template <typename Hal>
class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal> {
@@ -130,6 +144,16 @@
Error setLayerColorTransform(Display display, Layer layer, const float* matrix) override {
if (!mDispatch.setLayerColorTransform) {
+ if (isIdentityMatrix(matrix)) {
+ // If an identity matrix is set, then we can remove the layer from client
+ // composition list.
+ mClientCompositionLayers[display].erase(layer);
+ return Error::UNSUPPORTED;
+ }
+ // if setLayerColorTransform is not implemented, per spec we want to make sure the
+ // layer marked as client composition, and thus we maintain a list, and mark all these
+ // layers as client composition later before validate the display.
+ mClientCompositionLayers[display].insert(layer);
return Error::UNSUPPORTED;
}
int32_t err = mDispatch.setLayerColorTransform(mDevice, display, layer, matrix);
@@ -294,7 +318,79 @@
return true;
}
- private:
+ int32_t getChangedCompositionTypes(Display display, uint32_t* outTypesCount,
+ Layer* outChangedLayers,
+ IComposerClient::Composition* outCompositionTypes) override {
+ if (outChangedLayers == nullptr && outCompositionTypes == nullptr) {
+ uint32_t typesCount = 0;
+ int32_t error = BaseType2_1::getChangedCompositionTypesInternal(display, &typesCount,
+ nullptr, nullptr);
+ if (error != HWC2_ERROR_NONE) {
+ return error;
+ }
+ mChangedLayersCache[display].reserve(typesCount);
+ mCompositionTypesCache[display].reserve(typesCount);
+ error = BaseType2_1::getChangedCompositionTypesInternal(
+ display, &typesCount, mChangedLayersCache[display].data(),
+ mCompositionTypesCache[display].data());
+ if (error != HWC2_ERROR_NONE) {
+ return error;
+ }
+ for (Layer layer : mClientCompositionLayers[display]) {
+ bool exist = false;
+ for (uint32_t i = 0; i < typesCount; ++i) {
+ if (mChangedLayersCache[display][i] == layer) {
+ exist = true;
+ break;
+ }
+ }
+ if (!exist) {
+ mChangedLayersCache[display].push_back(layer);
+ mCompositionTypesCache[display].push_back(IComposerClient::Composition::CLIENT);
+ }
+ }
+ *outTypesCount = mChangedLayersCache[display].size();
+ return error;
+ }
+ for (uint32_t i = 0; i < *outTypesCount; ++i) {
+ if (outChangedLayers != nullptr) {
+ outChangedLayers[i] = mChangedLayersCache[display][i];
+ }
+ if (outCompositionTypes != nullptr) {
+ outCompositionTypes[i] = mCompositionTypesCache[display][i];
+ }
+ }
+ return HWC2_ERROR_NONE;
+ }
+
+ void onLayerDestroyed(Display display, Layer layer) override {
+ if (mClientCompositionLayers.find(display) == mClientCompositionLayers.end()) {
+ return;
+ }
+ mClientCompositionLayers[display].erase(layer);
+ }
+
+ void onBeforeValidateDisplay(Display display) override {
+ if (mClientCompositionLayers.find(display) == mClientCompositionLayers.end()) {
+ return;
+ }
+
+ // clear the cache proactively so that we don't hold too much memory over time.
+ mChangedLayersCache[display].clear();
+ mCompositionTypesCache[display].clear();
+
+ // SET_LAYER_COLOR_TRANSFORM is optional, and thus if it's not implemented, we need to
+ // follow the spec to make sure those layers marked as client composition before validate
+ // the display.
+ if (!mDispatch.setLayerColorTransform) {
+ for (Layer layer : mClientCompositionLayers[display]) {
+ BaseType2_1::setLayerCompositionType(
+ display, layer, static_cast<int32_t>(IComposerClient::Composition::CLIENT));
+ }
+ }
+ }
+
+ private:
struct {
HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA getDisplayIdentificationData;
HWC2_PFN_SET_LAYER_COLOR_TRANSFORM setLayerColorTransform;
@@ -318,6 +414,9 @@
using BaseType2_2::getRenderIntents;
using BaseType2_2::setColorMode_2_2;
using BaseType2_2::setLayerPerFrameMetadata;
+ std::map<Display, std::set<Layer>> mClientCompositionLayers;
+ std::map<Display, std::vector<Layer>> mChangedLayersCache;
+ std::map<Display, std::vector<IComposerClient::Composition>> mCompositionTypesCache;
};
} // namespace detail
diff --git a/graphics/mapper/2.0/IMapper.hal b/graphics/mapper/2.0/IMapper.hal
index 4566135..0e18f42 100644
--- a/graphics/mapper/2.0/IMapper.hal
+++ b/graphics/mapper/2.0/IMapper.hal
@@ -147,6 +147,9 @@
* outside of accessRegion is undefined, except that it must not cause
* process termination.
*
+ * An accessRegion of all-zeros means the entire buffer. That is, it is
+ * equivalent to '(0,0)-(buffer width, buffer height)'.
+ *
* data will be filled with a pointer to the locked buffer memory. This
* address will represent the top-left corner of the entire buffer, even
* if accessRegion does not begin at the top-left corner.
diff --git a/health/1.0/types.hal b/health/1.0/types.hal
index 377d1bd..90b8bb1 100644
--- a/health/1.0/types.hal
+++ b/health/1.0/types.hal
@@ -190,7 +190,13 @@
/** Remaining battery capacity in percent */
int32_t batteryLevel;
- /** Instantaneous battery voltage in uV */
+ /**
+ * Instantaneous battery voltage in millivolts (mV).
+ *
+ * Historically, the unit of this field is microvolts (uV), but all
+ * clients and implementations uses millivolts in practice, making it
+ * the de-facto standard.
+ */
int32_t batteryVoltage;
/** Instantaneous battery temperature in tenths of degree celcius */
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 106f332..c819b52 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -125,9 +125,9 @@
ADD_FAILURE() << "asking for burst execution at V1_0";
return nullptr;
}
-static std::unique_ptr<::android::nn::ExecutionBurstController> CreateBurst(
+static std::shared_ptr<::android::nn::ExecutionBurstController> CreateBurst(
const sp<V1_2::IPreparedModel>& preparedModel) {
- return ::android::nn::createExecutionBurstController(preparedModel, /*blocking=*/true);
+ return ::android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
}
enum class Executor { ASYNC, SYNC, BURST };
enum class OutputType { FULLY_SPECIFIED, UNSPECIFIED, INSUFFICIENT };
@@ -286,7 +286,7 @@
SCOPED_TRACE("burst");
// create burst
- const std::unique_ptr<::android::nn::ExecutionBurstController> controller =
+ const std::shared_ptr<::android::nn::ExecutionBurstController> controller =
CreateBurst(preparedModel);
ASSERT_NE(nullptr, controller.get());
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 8c57796..67a61c1 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -1188,8 +1188,11 @@
* value if the recurrent projection layer exists, and should otherwise
* have no value.
* * (API level >= 29) The four layer normalization weights either all have
- * values or none of them have values. Layer normalization is used when
- * values are present.
+ * values or none of them have values. Additionally, if CIFG is used,
+ * input layer normalization weights tensor is omitted and the other layer
+ * normalization weights either all have values or none of them have
+ * values. Layer normalization is used when the values of all the layer
+ * normalization weights are present.
*
* References:
*
diff --git a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
index b15f657..870d017 100644
--- a/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
+++ b/neuralnetworks/1.2/vts/functional/ValidateRequest.cpp
@@ -155,8 +155,8 @@
SCOPED_TRACE(message + " [burst]");
// create burst
- std::unique_ptr<::android::nn::ExecutionBurstController> burst =
- ::android::nn::createExecutionBurstController(preparedModel, /*blocking=*/true);
+ std::shared_ptr<::android::nn::ExecutionBurstController> burst =
+ ::android::nn::ExecutionBurstController::create(preparedModel, /*blocking=*/true);
ASSERT_NE(nullptr, burst.get());
// create memory keys
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 76d8758..2093c25 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -758,3 +758,40 @@
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE}));
}
}
+
+/*
+ * Test IRadio.getDataRegistrationStateResponse_1_4() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, getDataRegistrationState_1_4) {
+ int rat;
+ serial = GetRandomSerialNumber();
+
+ Return<void> res = radio_v1_4->getDataRegistrationState(serial);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("getDataRegistrationStateResponse_1_4, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+
+ ASSERT_TRUE(CheckAnyOfErrors(
+ radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE, RadioError::NOT_PROVISIONED}));
+
+ rat = radioRsp_v1_4->dataRegResp.base.rat;
+ /*
+ * - Expect Valid vopsinfo when device is on LTE
+ * - Expect empty vopsInfo when device is not on LTE
+ */
+ if (rat == ((int )::android::hardware::radio::V1_4::RadioTechnology::LTE)
+ || (rat == (int )::android::hardware::radio::V1_4::RadioTechnology::LTE_CA)) {
+
+ EXPECT_EQ(::android::hardware::radio::V1_4::DataRegStateResult::VopsInfo::hidl_discriminator
+ ::lteVopsInfo, radioRsp_v1_4->dataRegResp.vopsInfo.getDiscriminator());
+ } else {
+
+ EXPECT_EQ(::android::hardware::radio::V1_4::DataRegStateResult::VopsInfo::hidl_discriminator
+ ::noinit, radioRsp_v1_4->dataRegResp.vopsInfo.getDiscriminator());
+ }
+}
diff --git a/sensors/2.0/default/Android.bp b/sensors/2.0/default/Android.bp
index d05634b..05a34bb 100644
--- a/sensors/2.0/default/Android.bp
+++ b/sensors/2.0/default/Android.bp
@@ -23,7 +23,7 @@
"Sensor.cpp",
"Sensors.cpp",
],
- init_rc: ["android.hardware.sensors@2.0-service.rc"],
+ init_rc: ["android.hardware.sensors@2.0-service-mock.rc"],
shared_libs: [
"android.hardware.sensors@1.0",
"android.hardware.sensors@2.0",
diff --git a/sensors/2.0/default/android.hardware.sensors@2.0-service.rc b/sensors/2.0/default/android.hardware.sensors@2.0-service-mock.rc
similarity index 100%
rename from sensors/2.0/default/android.hardware.sensors@2.0-service.rc
rename to sensors/2.0/default/android.hardware.sensors@2.0-service-mock.rc
diff --git a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
index 65fd115..53fa8d6 100644
--- a/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.3/default/tests/mock_wifi_legacy_hal.h
@@ -43,6 +43,12 @@
const std::string& iface_name));
MOCK_METHOD1(getDriverVersion, std::pair<wifi_error, std::string>(
const std::string& iface_name));
+
+ MOCK_METHOD2(selectTxPowerScenario,
+ wifi_error(const std::string& iface_name,
+ wifi_power_scenario scenario));
+ MOCK_METHOD1(resetTxPowerScenario,
+ wifi_error(const std::string& iface_name));
MOCK_METHOD2(nanRegisterCallbackHandlers,
wifi_error(const std::string&, const NanCallbackHandlers&));
MOCK_METHOD2(nanDisableRequest,
diff --git a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
index 134563c..7928328 100644
--- a/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.3/default/tests/wifi_chip_unit_tests.cpp
@@ -122,7 +122,7 @@
void setup_MultiIfaceCombination() {
// clang-format off
const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinations = {
- {{{{IfaceType::STA}, 3}}}
+ {{{{IfaceType::STA}, 3}, {{IfaceType::AP}, 1}}}
};
const std::vector<V1_0::IWifiChip::ChipMode> modes = {
{feature_flags::chip_mode_ids::kV3, combinations}
@@ -261,6 +261,17 @@
return success;
}
+ sp<WifiChip> chip_;
+ ChipId chip_id_ = kFakeChipId;
+ std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+ new NiceMock<legacy_hal::MockWifiLegacyHal>};
+ std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
+ mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
+ std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
+ new NiceMock<iface_util::MockWifiIfaceUtil>};
+ std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
+ feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
+
public:
void SetUp() override {
chip_ = new WifiChip(chip_id_, legacy_hal_, mode_controller_,
@@ -272,17 +283,12 @@
.WillRepeatedly(testing::Return(legacy_hal::WIFI_SUCCESS));
}
- private:
- sp<WifiChip> chip_;
- ChipId chip_id_ = kFakeChipId;
- std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
- new NiceMock<legacy_hal::MockWifiLegacyHal>};
- std::shared_ptr<NiceMock<mode_controller::MockWifiModeController>>
- mode_controller_{new NiceMock<mode_controller::MockWifiModeController>};
- std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
- new NiceMock<iface_util::MockWifiIfaceUtil>};
- std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
- feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
+ void TearDown() override {
+ // Restore default system iface names (This should ideally be using a
+ // mock).
+ property_set("wifi.interface", "wlan0");
+ property_set("wifi.concurrent.interface", "wlan1");
+ }
};
////////// V1 Iface Combinations ////////////
@@ -300,7 +306,7 @@
TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
findModeAndConfigureForIfaceType(IfaceType::STA);
- ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
}
TEST_F(WifiChipV1IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
@@ -326,7 +332,7 @@
TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
findModeAndConfigureForIfaceType(IfaceType::AP);
- ASSERT_FALSE(createIface(IfaceType::AP).empty());
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
}
TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
@@ -359,7 +365,7 @@
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
findModeAndConfigureForIfaceType(IfaceType::STA);
- ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
}
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
@@ -427,7 +433,7 @@
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
findModeAndConfigureForIfaceType(IfaceType::AP);
- ASSERT_FALSE(createIface(IfaceType::AP).empty());
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
}
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
@@ -445,18 +451,18 @@
ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}
-TEST_F(WifiChipV1IfaceCombinationTest, RttControllerFlowStaModeNoSta) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeNoSta) {
findModeAndConfigureForIfaceType(IfaceType::STA);
ASSERT_TRUE(createRttController());
}
-TEST_F(WifiChipV1IfaceCombinationTest, RttControllerFlowStaModeWithSta) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowStaModeWithSta) {
findModeAndConfigureForIfaceType(IfaceType::STA);
ASSERT_FALSE(createIface(IfaceType::STA).empty());
ASSERT_TRUE(createRttController());
}
-TEST_F(WifiChipV1IfaceCombinationTest, RttControllerFlowApToSta) {
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, RttControllerFlowApToSta) {
findModeAndConfigureForIfaceType(IfaceType::AP);
const auto ap_iface_name = createIface(IfaceType::AP);
ASSERT_FALSE(ap_iface_name.empty());
@@ -468,6 +474,30 @@
ASSERT_TRUE(createRttController());
}
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ chip_->selectTxPowerScenario_1_2(
+ V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+ [](const WifiStatus& status) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ });
+}
+
+TEST_F(WifiChipV1_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
+ findModeAndConfigureForIfaceType(IfaceType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan0");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ chip_->selectTxPowerScenario_1_2(
+ V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+ [](const WifiStatus& status) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ });
+}
+
////////// V2 + Aware Iface Combinations ////////////
// Mode 1 - STA + STA/AP
// - STA + P2P/NAN
@@ -483,7 +513,7 @@
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) {
findModeAndConfigureForIfaceType(IfaceType::STA);
- ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
}
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) {
@@ -498,19 +528,25 @@
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) {
findModeAndConfigureForIfaceType(IfaceType::STA);
- ASSERT_FALSE(createIface(IfaceType::AP).empty());
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
}
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldFail) {
findModeAndConfigureForIfaceType(IfaceType::AP);
- ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
ASSERT_TRUE(createIface(IfaceType::STA).empty());
}
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) {
findModeAndConfigureForIfaceType(IfaceType::AP);
- ASSERT_FALSE(createIface(IfaceType::AP).empty());
- ASSERT_FALSE(createIface(IfaceType::STA).empty());
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApSta_ShouldSucceed) {
+ findModeAndConfigureForIfaceType(IfaceType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
}
TEST_F(WifiChipV2_AwareIfaceCombinationTest,
@@ -640,6 +676,30 @@
ASSERT_TRUE(createRttController());
}
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlySta) {
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan0", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ chip_->selectTxPowerScenario_1_2(
+ V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+ [](const WifiStatus& status) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ });
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest, SelectTxScenarioWithOnlyAp) {
+ findModeAndConfigureForIfaceType(IfaceType::AP);
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+ EXPECT_CALL(*legacy_hal_, selectTxPowerScenario("wlan1", testing::_))
+ .WillOnce(testing::Return(legacy_hal::WIFI_SUCCESS));
+ chip_->selectTxPowerScenario_1_2(
+ V1_2::IWifiChip::TxPowerScenario::ON_HEAD_CELL_OFF,
+ [](const WifiStatus& status) {
+ ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
+ });
+}
+
////////// V1 Iface Combinations when AP creation is disabled //////////
class WifiChipV1_AwareDisabledApIfaceCombinationTest : public WifiChipTest {
public:
@@ -707,8 +767,8 @@
property_set("wifi.interface", "bad0");
property_set("wifi.concurrent.interface", "bad1");
findModeAndConfigureForIfaceType(IfaceType::STA);
- ASSERT_EQ(createIface(IfaceType::STA), "test0");
- ASSERT_EQ(createIface(IfaceType::STA), "test1");
+ ASSERT_EQ(createIface(IfaceType::STA), "bad0");
+ ASSERT_EQ(createIface(IfaceType::STA), "bad1");
ASSERT_EQ(createIface(IfaceType::STA), "test2");
}
@@ -724,6 +784,16 @@
ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
}
+TEST_F(WifiChip_MultiIfaceTest, CreateApStartsWithIdx1) {
+ findModeAndConfigureForIfaceType(IfaceType::STA);
+ // First AP will be slotted to wlan1.
+ ASSERT_EQ(createIface(IfaceType::AP), "wlan1");
+ // First STA will be slotted to wlan0.
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
+ // All further STA will be slotted to the remaining free indices.
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
+ ASSERT_EQ(createIface(IfaceType::STA), "wlan3");
+}
} // namespace implementation
} // namespace V1_3
} // namespace wifi
diff --git a/wifi/1.3/default/wifi_chip.cpp b/wifi/1.3/default/wifi_chip.cpp
index 3697d50..25eb289 100644
--- a/wifi/1.3/default/wifi_chip.cpp
+++ b/wifi/1.3/default/wifi_chip.cpp
@@ -41,7 +41,9 @@
constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
constexpr uint32_t kMaxRingBufferFileNum = 20;
constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
-constexpr unsigned kMaxWlanIfaces = 100;
+constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
+constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
+constexpr unsigned kMaxWlanIfaces = 5;
template <typename Iface>
void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
@@ -105,6 +107,13 @@
return buffer.data();
}
+void setActiveWlanIfaceNameProperty(const std::string& ifname) {
+ auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
+ if (res != 0) {
+ PLOG(ERROR) << "Failed to set active wlan iface name property";
+ }
+}
+
// delete files that meet either conditions:
// 1. older than a predefined time in the wifi tombstone dir.
// 2. Files in excess to a predefined amount, starting from the oldest ones
@@ -316,13 +325,16 @@
is_valid_(true),
current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
modes_(feature_flags.lock()->getChipModes()),
- debug_ring_buffer_cb_registered_(false) {}
+ debug_ring_buffer_cb_registered_(false) {
+ setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
+}
void WifiChip::invalidate() {
if (!writeRingbufferFilesInternal()) {
LOG(ERROR) << "Error writing files to flash";
}
invalidateAndRemoveAllIfaces();
+ setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
legacy_hal_.reset();
event_cb_handler_.invalidate();
is_valid_ = false;
@@ -641,7 +653,7 @@
legacy_hal::wifi_error legacy_status;
uint32_t legacy_feature_set;
uint32_t legacy_logger_feature_set;
- const auto ifname = getWlanIfaceName(0);
+ const auto ifname = getFirstActiveWlanIfaceName();
std::tie(legacy_status, legacy_feature_set) =
legacy_hal_.lock()->getSupportedFeatureSet(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
@@ -693,6 +705,7 @@
}
current_mode_id_ = mode_id;
LOG(INFO) << "Configured chip in mode " << mode_id;
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
return status;
}
@@ -709,7 +722,7 @@
IWifiChip::ChipDebugInfo result;
legacy_hal::wifi_error legacy_status;
std::string driver_desc;
- const auto ifname = getWlanIfaceName(0);
+ const auto ifname = getFirstActiveWlanIfaceName();
std::tie(legacy_status, driver_desc) =
legacy_hal_.lock()->getDriverVersion(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
@@ -741,7 +754,8 @@
legacy_hal::wifi_error legacy_status;
std::vector<uint8_t> driver_dump;
std::tie(legacy_status, driver_dump) =
- legacy_hal_.lock()->requestDriverMemoryDump(getWlanIfaceName(0));
+ legacy_hal_.lock()->requestDriverMemoryDump(
+ getFirstActiveWlanIfaceName());
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get driver debug dump: "
<< legacyErrorToString(legacy_status);
@@ -756,7 +770,8 @@
legacy_hal::wifi_error legacy_status;
std::vector<uint8_t> firmware_dump;
std::tie(legacy_status, firmware_dump) =
- legacy_hal_.lock()->requestFirmwareMemoryDump(getWlanIfaceName(0));
+ legacy_hal_.lock()->requestFirmwareMemoryDump(
+ getFirstActiveWlanIfaceName());
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get firmware debug dump: "
<< legacyErrorToString(legacy_status);
@@ -766,10 +781,10 @@
}
std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
- if (!canCurrentModeSupportIfaceOfType(IfaceType::AP)) {
+ if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
- std::string ifname = allocateApOrStaIfaceName();
+ std::string ifname = allocateApIfaceName();
sp<WifiApIface> iface =
new WifiApIface(ifname, legacy_hal_, iface_util_, feature_flags_);
ap_ifaces_.push_back(iface);
@@ -778,6 +793,7 @@
LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
}
}
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
}
@@ -809,15 +825,16 @@
LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
}
}
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
return createWifiStatus(WifiStatusCode::SUCCESS);
}
std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
- if (!canCurrentModeSupportIfaceOfType(IfaceType::NAN)) {
+ if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
// These are still assumed to be based on wlan0.
- std::string ifname = getWlanIfaceName(0);
+ std::string ifname = getFirstActiveWlanIfaceName();
sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
nan_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -860,7 +877,7 @@
}
std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
- if (!canCurrentModeSupportIfaceOfType(IfaceType::P2P)) {
+ if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
std::string ifname = getP2pIfaceName();
@@ -906,10 +923,10 @@
}
std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
- if (!canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
+ if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
- std::string ifname = allocateApOrStaIfaceName();
+ std::string ifname = allocateStaIfaceName();
sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
sta_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -917,6 +934,7 @@
LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
}
}
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
}
@@ -948,6 +966,7 @@
LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
}
}
+ setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
return createWifiStatus(WifiStatusCode::SUCCESS);
}
@@ -959,8 +978,8 @@
"(and RTT by extension)";
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
- sp<WifiRttController> rtt =
- new WifiRttController(getWlanIfaceName(0), bound_iface, legacy_hal_);
+ sp<WifiRttController> rtt = new WifiRttController(
+ getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
rtt_controllers_.emplace_back(rtt);
return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
}
@@ -971,7 +990,7 @@
std::vector<legacy_hal::wifi_ring_buffer_status>
legacy_ring_buffer_status_vec;
std::tie(legacy_status, legacy_ring_buffer_status_vec) =
- legacy_hal_.lock()->getRingBuffersStatus(getWlanIfaceName(0));
+ legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
@@ -993,7 +1012,7 @@
}
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->startRingBufferLogging(
- getWlanIfaceName(0), ring_name,
+ getFirstActiveWlanIfaceName(), ring_name,
static_cast<
std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
verbose_level),
@@ -1010,7 +1029,8 @@
return status;
}
legacy_hal::wifi_error legacy_status =
- legacy_hal_.lock()->getRingBufferData(getWlanIfaceName(0), ring_name);
+ legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(),
+ ring_name);
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1026,7 +1046,7 @@
WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
- getWlanIfaceName(0));
+ getFirstActiveWlanIfaceName());
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1035,7 +1055,7 @@
legacy_hal::wifi_error legacy_status;
legacy_hal::WakeReasonStats legacy_stats;
std::tie(legacy_status, legacy_stats) =
- legacy_hal_.lock()->getWakeReasonStats(getWlanIfaceName(0));
+ legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
@@ -1067,10 +1087,10 @@
}
};
legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
- getWlanIfaceName(0), on_alert_callback);
+ getFirstActiveWlanIfaceName(), on_alert_callback);
} else {
legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
- getWlanIfaceName(0));
+ getFirstActiveWlanIfaceName());
}
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1078,20 +1098,20 @@
WifiStatus WifiChip::selectTxPowerScenarioInternal(
V1_1::IWifiChip::TxPowerScenario scenario) {
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
- getWlanIfaceName(0),
+ getFirstActiveWlanIfaceName(),
hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiChip::resetTxPowerScenarioInternal() {
auto legacy_status =
- legacy_hal_.lock()->resetTxPowerScenario(getWlanIfaceName(0));
+ legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
auto legacy_status = legacy_hal_.lock()->setLatencyMode(
- getWlanIfaceName(0),
+ getFirstActiveWlanIfaceName(),
hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1107,7 +1127,7 @@
WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
TxPowerScenario scenario) {
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
- getWlanIfaceName(0),
+ getFirstActiveWlanIfaceName(),
hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1197,7 +1217,7 @@
};
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->registerRingBufferCallbackHandler(
- getWlanIfaceName(0), on_ring_buffer_data_callback);
+ getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
if (legacy_status == legacy_hal::WIFI_SUCCESS) {
debug_ring_buffer_cb_registered_ = true;
@@ -1231,7 +1251,7 @@
};
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
- getWlanIfaceName(0), on_radio_mode_change_callback);
+ getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
return createWifiStatusFromLegacyError(legacy_status);
}
@@ -1298,8 +1318,9 @@
return expanded_combos;
}
-bool WifiChip::canExpandedIfaceCombinationSupportIfaceOfType(
- const std::map<IfaceType, size_t>& combo, IfaceType requested_type) {
+bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
+ const std::map<IfaceType, size_t>& expanded_combo,
+ IfaceType requested_type) {
const auto current_combo = getCurrentIfaceCombination();
// Check if we have space for 1 more iface of |type| in this combo
@@ -1309,7 +1330,7 @@
if (type == requested_type) {
num_ifaces_needed++;
}
- size_t num_ifaces_allowed = combo.at(type);
+ size_t num_ifaces_allowed = expanded_combo.at(type);
if (num_ifaces_needed > num_ifaces_allowed) {
return false;
}
@@ -1320,8 +1341,10 @@
// This method does the following:
// a) Enumerate all possible iface combos by expanding the current
// ChipIfaceCombination.
-// b) Check if the requested iface type can be added to the current mode.
-bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType type) {
+// b) Check if the requested iface type can be added to the current mode
+// with the iface combination that is already active.
+bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(
+ IfaceType requested_type) {
if (!isValidModeId(current_mode_id_)) {
LOG(ERROR) << "Chip not configured in a mode yet";
return false;
@@ -1330,8 +1353,8 @@
for (const auto& combination : combinations) {
const auto expanded_combos = expandIfaceCombinations(combination);
for (const auto& expanded_combo : expanded_combos) {
- if (canExpandedIfaceCombinationSupportIfaceOfType(expanded_combo,
- type)) {
+ if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
+ expanded_combo, requested_type)) {
return true;
}
}
@@ -1339,6 +1362,62 @@
return false;
}
+// Note: This does not consider ifaces already active. It only checks if the
+// provided expanded iface combination can support the requested combo.
+bool WifiChip::canExpandedIfaceComboSupportIfaceCombo(
+ const std::map<IfaceType, size_t>& expanded_combo,
+ const std::map<IfaceType, size_t>& req_combo) {
+ // Check if we have space for 1 more iface of |type| in this combo
+ for (const auto type :
+ {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
+ if (req_combo.count(type) == 0) {
+ // Iface of "type" not in the req_combo.
+ continue;
+ }
+ size_t num_ifaces_needed = req_combo.at(type);
+ size_t num_ifaces_allowed = expanded_combo.at(type);
+ if (num_ifaces_needed > num_ifaces_allowed) {
+ return false;
+ }
+ }
+ return true;
+}
+// This method does the following:
+// a) Enumerate all possible iface combos by expanding the current
+// ChipIfaceCombination.
+// b) Check if the requested iface combo can be added to the current mode.
+// Note: This does not consider ifaces already active. It only checks if the
+// current mode can support the requested combo.
+bool WifiChip::canCurrentModeSupportIfaceCombo(
+ const std::map<IfaceType, size_t>& req_combo) {
+ if (!isValidModeId(current_mode_id_)) {
+ LOG(ERROR) << "Chip not configured in a mode yet";
+ return false;
+ }
+ const auto combinations = getCurrentModeIfaceCombinations();
+ for (const auto& combination : combinations) {
+ const auto expanded_combos = expandIfaceCombinations(combination);
+ for (const auto& expanded_combo : expanded_combos) {
+ if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo,
+ req_combo)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// This method does the following:
+// a) Enumerate all possible iface combos by expanding the current
+// ChipIfaceCombination.
+// b) Check if the requested iface type can be added to the current mode.
+bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) {
+ // Check if we can support atleast 1 iface of type.
+ std::map<IfaceType, size_t> req_iface_combo;
+ req_iface_combo[requested_type] = 1;
+ return canCurrentModeSupportIfaceCombo(req_iface_combo);
+}
+
bool WifiChip::isValidModeId(ChipModeId mode_id) {
for (const auto& mode : modes_) {
if (mode.id == mode_id) {
@@ -1348,11 +1427,32 @@
return false;
}
-// Return the first wlan (wlan0, wlan1 etc.) not already in use.
-// This doesn't check the actual presence of these interfaces.
-std::string WifiChip::allocateApOrStaIfaceName() {
- for (unsigned i = 0; i < kMaxWlanIfaces; i++) {
- const auto ifname = getWlanIfaceName(i);
+bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
+ // Check if we can support atleast 1 STA & 1 AP concurrently.
+ std::map<IfaceType, size_t> req_iface_combo;
+ req_iface_combo[IfaceType::AP] = 1;
+ req_iface_combo[IfaceType::STA] = 1;
+ return canCurrentModeSupportIfaceCombo(req_iface_combo);
+}
+
+std::string WifiChip::getFirstActiveWlanIfaceName() {
+ for (unsigned idx = 0; idx < kMaxWlanIfaces; idx++) {
+ const auto ifname = getWlanIfaceName(idx);
+ if (findUsingName(sta_ifaces_, ifname)) return ifname;
+ if (findUsingName(ap_ifaces_, ifname)) return ifname;
+ }
+ // This could happen if the chip call is made before any STA/AP
+ // iface is created. Default to wlan0 for such cases.
+ LOG(WARNING) << "No active wlan interfaces in use!";
+ return getWlanIfaceName(0);
+}
+
+// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
+// not already in use.
+// Note: This doesn't check the actual presence of these interfaces.
+std::string WifiChip::allocateApOrStaIfaceName(uint32_t start_idx) {
+ for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
+ const auto ifname = getWlanIfaceName(idx);
if (findUsingName(ap_ifaces_, ifname)) continue;
if (findUsingName(sta_ifaces_, ifname)) continue;
return ifname;
@@ -1362,6 +1462,19 @@
return {};
}
+// AP iface names start with idx 1 for modes supporting
+// concurrent STA, else start with idx 0.
+std::string WifiChip::allocateApIfaceName() {
+ return allocateApOrStaIfaceName(
+ isStaApConcurrencyAllowedInCurrentMode() ? 1 : 0);
+}
+
+// STA iface names start with idx 0.
+// Primary STA iface will always be 0.
+std::string WifiChip::allocateStaIfaceName() {
+ return allocateApOrStaIfaceName(0);
+}
+
bool WifiChip::writeRingbufferFilesInternal() {
if (!removeOldFilesInternal()) {
LOG(ERROR) << "Error occurred while deleting old tombstone files";
diff --git a/wifi/1.3/default/wifi_chip.h b/wifi/1.3/default/wifi_chip.h
index 3eb0aee..3d12f4c 100644
--- a/wifi/1.3/default/wifi_chip.h
+++ b/wifi/1.3/default/wifi_chip.h
@@ -224,11 +224,23 @@
std::map<IfaceType, size_t> getCurrentIfaceCombination();
std::vector<std::map<IfaceType, size_t>> expandIfaceCombinations(
const IWifiChip::ChipIfaceCombination& combination);
- bool canExpandedIfaceCombinationSupportIfaceOfType(
- const std::map<IfaceType, size_t>& combo, IfaceType type);
- bool canCurrentModeSupportIfaceOfType(IfaceType type);
+ bool canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
+ const std::map<IfaceType, size_t>& expanded_combo,
+ IfaceType requested_type);
+ bool canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(
+ IfaceType requested_type);
+ bool canExpandedIfaceComboSupportIfaceCombo(
+ const std::map<IfaceType, size_t>& expanded_combo,
+ const std::map<IfaceType, size_t>& req_combo);
+ bool canCurrentModeSupportIfaceCombo(
+ const std::map<IfaceType, size_t>& req_combo);
+ bool canCurrentModeSupportIfaceOfType(IfaceType requested_type);
bool isValidModeId(ChipModeId mode_id);
- std::string allocateApOrStaIfaceName();
+ bool isStaApConcurrencyAllowedInCurrentMode();
+ std::string getFirstActiveWlanIfaceName();
+ std::string allocateApOrStaIfaceName(uint32_t start_idx);
+ std::string allocateApIfaceName();
+ std::string allocateStaIfaceName();
bool writeRingbufferFilesInternal();
ChipId chip_id_;
diff --git a/wifi/1.3/default/wifi_legacy_hal.cpp b/wifi/1.3/default/wifi_legacy_hal.cpp
index 5aa98c4..7f9b635 100644
--- a/wifi/1.3/default/wifi_legacy_hal.cpp
+++ b/wifi/1.3/default/wifi_legacy_hal.cpp
@@ -777,7 +777,7 @@
}
wifi_error WifiLegacyHal::startSendingOffloadedPacket(
- const std::string& iface_name, uint32_t cmd_id,
+ const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type,
const std::vector<uint8_t>& ip_packet_data,
const std::array<uint8_t, 6>& src_address,
const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) {
@@ -787,9 +787,9 @@
std::vector<uint8_t> dst_address_internal(
dst_address.data(), dst_address.data() + dst_address.size());
return global_func_table_.wifi_start_sending_offloaded_packet(
- cmd_id, getIfaceHandle(iface_name), ip_packet_data_internal.data(),
- ip_packet_data_internal.size(), src_address_internal.data(),
- dst_address_internal.data(), period_in_ms);
+ cmd_id, getIfaceHandle(iface_name), ether_type,
+ ip_packet_data_internal.data(), ip_packet_data_internal.size(),
+ src_address_internal.data(), dst_address_internal.data(), period_in_ms);
}
wifi_error WifiLegacyHal::stopSendingOffloadedPacket(
diff --git a/wifi/1.3/default/wifi_legacy_hal.h b/wifi/1.3/default/wifi_legacy_hal.h
index 4d6beb3..a3ed460 100644
--- a/wifi/1.3/default/wifi_legacy_hal.h
+++ b/wifi/1.3/default/wifi_legacy_hal.h
@@ -246,7 +246,7 @@
fw_roaming_state_t state);
wifi_error configureNdOffload(const std::string& iface_name, bool enable);
wifi_error startSendingOffloadedPacket(
- const std::string& iface_name, uint32_t cmd_id,
+ const std::string& iface_name, uint32_t cmd_id, uint16_t ether_type,
const std::vector<uint8_t>& ip_packet_data,
const std::array<uint8_t, 6>& src_address,
const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms);
@@ -254,9 +254,9 @@
uint32_t cmd_id);
wifi_error setScanningMacOui(const std::string& iface_name,
const std::array<uint8_t, 3>& oui);
- wifi_error selectTxPowerScenario(const std::string& iface_name,
- wifi_power_scenario scenario);
- wifi_error resetTxPowerScenario(const std::string& iface_name);
+ virtual wifi_error selectTxPowerScenario(const std::string& iface_name,
+ wifi_power_scenario scenario);
+ virtual wifi_error resetTxPowerScenario(const std::string& iface_name);
wifi_error setLatencyMode(const std::string& iface_name,
wifi_latency_mode mode);
// Logger/debug functions.
diff --git a/wifi/1.3/default/wifi_sta_iface.cpp b/wifi/1.3/default/wifi_sta_iface.cpp
index 17f3e3d..a6539e5 100644
--- a/wifi/1.3/default/wifi_sta_iface.cpp
+++ b/wifi/1.3/default/wifi_sta_iface.cpp
@@ -562,12 +562,12 @@
WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data,
- uint16_t /* ether_type */, const std::array<uint8_t, 6>& src_address,
+ uint16_t ether_type, const std::array<uint8_t, 6>& src_address,
const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) {
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->startSendingOffloadedPacket(
- ifname_, cmd_id, ip_packet_data, src_address, dst_address,
- period_in_ms);
+ ifname_, cmd_id, ether_type, ip_packet_data, src_address,
+ dst_address, period_in_ms);
return createWifiStatusFromLegacyError(legacy_status);
}