Merge "Make states atomic and update comments" into sc-dev
diff --git a/audio/7.0/IDevice.hal b/audio/7.0/IDevice.hal
index e423f29..85c789a 100644
--- a/audio/7.0/IDevice.hal
+++ b/audio/7.0/IDevice.hal
@@ -245,6 +245,7 @@
/**
* Gets the HW synchronization source of the device. Calling this method is
* equivalent to getting AUDIO_PARAMETER_HW_AV_SYNC on the legacy HAL.
+ *
* Optional method
*
* @return retval operation completion status: OK or NOT_SUPPORTED.
@@ -255,6 +256,7 @@
/**
* Sets whether the screen is on. Calling this method is equivalent to
* setting AUDIO_PARAMETER_KEY_SCREEN_STATE on the legacy HAL.
+ *
* Optional method
*
* @param turnedOn whether the screen is turned on.
diff --git a/audio/7.0/IStream.hal b/audio/7.0/IStream.hal
index 393e38f..e4987c2 100644
--- a/audio/7.0/IStream.hal
+++ b/audio/7.0/IStream.hal
@@ -110,6 +110,7 @@
/**
* Return the set of devices which this stream is connected to.
+ *
* Optional method
*
* @return retval operation completion status: OK or NOT_SUPPORTED.
@@ -133,6 +134,7 @@
/**
* Sets the HW synchronization source. Calling this method is equivalent to
* setting AUDIO_PARAMETER_STREAM_HW_AV_SYNC on the legacy HAL.
+ *
* Optional method
*
* @param hwAvSync HW synchronization source
diff --git a/audio/7.0/IStreamIn.hal b/audio/7.0/IStreamIn.hal
index bf9ae52..be4bda4 100644
--- a/audio/7.0/IStreamIn.hal
+++ b/audio/7.0/IStreamIn.hal
@@ -24,6 +24,7 @@
* Returns the source descriptor of the input stream. Calling this method is
* equivalent to getting AUDIO_PARAMETER_STREAM_INPUT_SOURCE on the legacy
* HAL.
+ *
* Optional method
*
* @return retval operation completion status.
@@ -33,6 +34,7 @@
/**
* Set the input gain for the audio driver.
+ *
* Optional method
*
* @param gain 1.0f is unity, 0.0f is zero.
@@ -42,6 +44,7 @@
/**
* Called when the metadata of the stream's sink has been changed.
+ *
* Optional method
*
* @param sinkMetadata Description of the audio that is suggested by the clients.
@@ -148,7 +151,8 @@
/**
* Return a recent count of the number of audio frames received and the
- * clock time associated with that frame count.
+ * clock time associated with that frame count. The count must not reset to
+ * zero when a PCM input enters standby.
*
* @return retval INVALID_STATE if the device is not ready/available,
* NOT_SUPPORTED if the command is not supported,
diff --git a/audio/7.0/IStreamOut.hal b/audio/7.0/IStreamOut.hal
index 78cb51b..6e8498e 100644
--- a/audio/7.0/IStreamOut.hal
+++ b/audio/7.0/IStreamOut.hal
@@ -35,6 +35,7 @@
* allowing to directly set the volume as apposed to via the framework.
* This method might produce multiple PCM outputs or hardware accelerated
* codecs, such as MP3 or AAC.
+ *
* Optional method
*
* @param left left channel attenuation, 1.0f is unity, 0.0f is zero.
@@ -46,6 +47,7 @@
/**
* Called when the metadata of the stream's source has been changed.
+ *
* Optional method
*
* @param sourceMetadata Description of the audio that is played by the clients.
@@ -130,6 +132,7 @@
/**
* Return the number of audio frames written by the audio DSP to DAC since
* the output has exited standby.
+ *
* Optional method
*
* @return retval operation completion status.
@@ -141,6 +144,7 @@
* Get the local time at which the next write to the audio driver will be
* presented. The units are microseconds, where the epoch is decided by the
* local audio HAL.
+ *
* Optional method
*
* @return retval operation completion status.
@@ -253,8 +257,11 @@
drain(AudioDrain type) generates (Result retval);
/**
- * Notifies to the audio driver to flush the queued data. Stream must
- * already be paused before calling 'flush'.
+ * Notifies to the audio driver to flush (that is, drop) the queued
+ * data. Stream must already be paused before calling 'flush'. For
+ * compressed and offload streams the frame count returned by
+ * 'getPresentationPosition' must reset after flush.
+ *
* Optional method
*
* Implementation of this function is mandatory for offloaded playback.
@@ -266,12 +273,14 @@
/**
* Return a recent count of the number of audio frames presented to an
* external observer. This excludes frames which have been written but are
- * still in the pipeline. The count is not reset to zero when output enters
- * standby. Also returns the value of CLOCK_MONOTONIC as of this
+ * still in the pipeline. The count must not reset to zero when a PCM output
+ * enters standby. For compressed and offload streams it is recommended that
+ * HAL resets the frame count.
+ *
+ * This method also returns the value of CLOCK_MONOTONIC as of this
* presentation count. The returned count is expected to be 'recent', but
* does not need to be the most recent possible value. However, the
* associated time must correspond to whatever count is returned.
- *
* Example: assume that N+M frames have been presented, where M is a 'small'
* number. Then it is permissible to return N instead of N+M, and the
* timestamp must correspond to N rather than N+M. The terms 'recent' and
@@ -287,6 +296,7 @@
/**
* Selects a presentation for decoding from a next generation media stream
* (as defined per ETSI TS 103 190-2) and a program within the presentation.
+ *
* Optional method
*
* @param presentationId selected audio presentation.
diff --git a/audio/common/7.0/types.hal b/audio/common/7.0/types.hal
index bea0705..4f920e4 100644
--- a/audio/common/7.0/types.hal
+++ b/audio/common/7.0/types.hal
@@ -344,7 +344,7 @@
DeviceAddress device;
} destination;
AudioChannelMask channelMask;
- /** Tags from AudioTrack audio atttributes */
+ /** Tags from AudioRecord audio atttributes */
vec<AudioTag> tags;
};
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
index 73513f4..5915a53 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/DefaultConfig.h
@@ -996,6 +996,15 @@
},
.initialValue = {.int32Values = {LIGHT_SWITCH_AUTO}}},
+ {.config =
+ {
+ .prop = toInt(VehicleProperty::EVS_SERVICE_REQUEST),
+ .access = VehiclePropertyAccess::READ,
+ .changeMode = VehiclePropertyChangeMode::ON_CHANGE,
+ },
+ .initialValue = {.int32Values = {toInt(EvsServiceType::REARVIEW),
+ toInt(EvsServiceState::OFF)}}},
+
{.config = {.prop = VEHICLE_MAP_SERVICE,
.access = VehiclePropertyAccess::READ_WRITE,
.changeMode = VehiclePropertyChangeMode::ON_CHANGE}},
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
index 548285a..9be9ea7 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.cpp
@@ -31,6 +31,14 @@
GeneratorHub::GeneratorHub(const OnHalEvent& onHalEvent)
: mOnHalEvent(onHalEvent), mThread(&GeneratorHub::run, this) {}
+GeneratorHub::~GeneratorHub() {
+ mShuttingDownFlag.store(true);
+ mCond.notify_all();
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
void GeneratorHub::registerGenerator(int32_t cookie, FakeValueGeneratorPtr generator) {
{
std::lock_guard<std::mutex> g(mLock);
@@ -58,15 +66,18 @@
}
void GeneratorHub::run() {
- while (true) {
+ while (!mShuttingDownFlag.load()) {
std::unique_lock<std::mutex> g(mLock);
// Pop events whose generator does not exist (may be already unregistered)
while (!mEventQueue.empty()
&& mGenerators.find(mEventQueue.top().cookie) == mGenerators.end()) {
mEventQueue.pop();
}
- // Wait until event queue is not empty
- mCond.wait(g, [this] { return !mEventQueue.empty(); });
+ // Wait until event queue is not empty or shutting down flag is set
+ mCond.wait(g, [this] { return !mEventQueue.empty() || mShuttingDownFlag.load(); });
+ if (mShuttingDownFlag.load()) {
+ break;
+ }
const VhalEvent& curEvent = mEventQueue.top();
diff --git a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h
index dcf6a4f..b25dbf1 100644
--- a/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h
+++ b/automotive/vehicle/2.0/default/impl/vhal_v2_0/GeneratorHub.h
@@ -58,7 +58,7 @@
public:
GeneratorHub(const OnHalEvent& onHalEvent);
- ~GeneratorHub() = default;
+ ~GeneratorHub();
/**
* Register a new generator. The generator will be discarded if it could not produce next event.
@@ -84,6 +84,7 @@
mutable std::mutex mLock;
std::condition_variable mCond;
std::thread mThread;
+ std::atomic<bool> mShuttingDownFlag{false};
};
} // namespace impl
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index e3fd16d..94645a4 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2927,6 +2927,29 @@
| VehicleArea:GLOBAL),
/**
+ * Enable/request an EVS service.
+ *
+ * The property provides a generalized way to trigger EVS services. VHAL
+ * should use this property to request Android to start or stop EVS service.
+ *
+ * int32Values[0] = a type of the EVS service. The value must be one of enums in
+ * EvsServiceType.
+ * int32Values[1] = the state of the EVS service. The value must be one of enums in
+ * EvsServiceState.
+ *
+ * For example, to enable rear view EVS service, android side can set the property value as
+ * [EvsServiceType::REAR_VIEW, EvsServiceState::ON].
+ *
+ * @change_mode VehiclePropertyChangeMode:ON_CHANGE
+ * @access VehiclePropertyAccess:READ
+ */
+ EVS_SERVICE_REQUEST = (
+ 0x0F10
+ | VehiclePropertyGroup:SYSTEM
+ | VehiclePropertyType:INT32_VEC
+ | VehicleArea:GLOBAL),
+
+ /**
* Defines a request to apply power policy.
*
* VHAL sets this property to change car power policy. Car power policy service subscribes to
@@ -3037,7 +3060,7 @@
/**
* Starts the ClusterUI in cluster display.
*
- * int32[0]: the type of ClusterUI to show
+ * int32: the type of ClusterUI to show
* 0 indicates ClusterHome, that is a home screen of cluster display, and provides
* the default UI and a kind of launcher functionality for cluster display.
* the other values are followed by OEM's definition.
@@ -3057,12 +3080,12 @@
* int32[0]: on/off: 0 - off, 1 - on, -1 - don't care
* int32[1]: width: positive number - actual width in pixels
-1 - don't care (should set "don't care" both width and height)
- * int32[2]: height: ditto with width
+ * int32[2]: height: same format with 'width'
* int32[3]: Inset - left: positive number - actual left inset value in pixels
-1 - don't care (should set "don't care" all Inset fields)
- * int32[4]: Inset - top
- * int32[5]: Inset - right
- * int32[6]: Inset - bottom
+ * int32[4]: Inset - top: same format with 'left'
+ * int32[5]: Inset - right: same format with 'left'
+ * int32[6]: Inset - bottom: same format with 'left'
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:READ
@@ -3097,9 +3120,9 @@
* -1 indicates the area isn't used any more.
* bytes: the array to represent the availability of ClusterUI.
* 0 indicates non-available and 1 indicates available.
- * For example, let's assume a car supports 3 UI like HOME, MAPS, CALL and it only supports
- * CALL UI only when the cellular network is available. Then, if the nework is avaibale,
- * it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
+ * For example, let's assume a car supports 3 OEM defined ClusterUI like HOME, MAPS, CALL,
+ * and it only supports CALL UI only when the cellular network is available. Then, if the
+ * nework is avaibale, it'll send [1 1 1], and if it's out of network, it'll send [1 1 0].
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:WRITE
@@ -3117,7 +3140,7 @@
* request to turn the display on to show some specific ClusterUI.
* ClusterOS should response this with CLUSTER_DISPLAY_STATE.
*
- * int32[0]: the type of ClusterUI to show
+ * int32: the type of ClusterUI to show
*
* @change_mode VehiclePropertyChangeMode:ON_CHANGE
* @access VehiclePropertyAccess:WRITE
@@ -3213,6 +3236,33 @@
};
/**
+ * Used by EVS_SERVICE_REQUEST to enumerate the service's type.
+ */
+enum EvsServiceType : int32_t {
+
+ REARVIEW = 0,
+ SURROUNDVIEW = 1,
+};
+
+/**
+ * Used by EVS_SERVICE_REQUEST to enumerate the service's state.
+ */
+enum EvsServiceState : int32_t {
+
+ OFF = 0,
+ ON = 1,
+};
+
+/**
+ * Index in int32VAlues for VehicleProperty#EVS_SERVICE_REQUEST property.
+ */
+enum EvsServiceRequestIndex : int32_t {
+
+ TYPE = 0,
+ STATE = 1,
+};
+
+/**
* Used by lights state properties to enumerate the current state of the lights.
*
* Most XXX_LIGHTS_STATE properties will only report ON and OFF states. Only
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
index 2600e61..c19534c 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -59,7 +59,5 @@
VENDOR = 22,
FIRST_FRAME_RECEIVED = 23,
DARK_GLASSES_DETECTED = 24,
- FACE_COVERING_DETECTED = 25,
- EYES_NOT_VISIBLE = 26,
- MOUTH_NOT_VISIBLE = 27,
+ MOUTH_COVERING_DETECTED = 25,
}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
index 0d1ef45..fc4a4d0 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/IFace.aidl
@@ -36,5 +36,4 @@
interface IFace {
android.hardware.biometrics.face.SensorProps[] getSensorProps();
android.hardware.biometrics.face.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.face.ISessionCallback cb);
- void reset();
}
diff --git a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
index 4aef61a..205429b 100644
--- a/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/aidl_api/android.hardware.biometrics.face/current/android/hardware/biometrics/face/ISession.aidl
@@ -34,7 +34,7 @@
package android.hardware.biometrics.face;
@VintfStability
interface ISession {
- void generateChallenge(in int cookie, in int timeoutSec);
+ void generateChallenge(in int cookie);
void revokeChallenge(in int cookie, in long challenge);
android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat, in android.hardware.biometrics.face.EnrollmentType type, in android.hardware.biometrics.face.Feature[] features, in android.hardware.common.NativeHandle previewSurface);
android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
index 217a9bb..a3b229e 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/AcquiredInfo.aidl
@@ -187,7 +187,7 @@
*/
ROLL_TOO_EXTREME = 18,
- /**
+ /**
* The user’s face has been obscured by some object.
*
* The user should be informed to remove any objects from the line of sight from
@@ -230,18 +230,5 @@
* A face mask or face covering detected. This can be useful for providing relevant feedback to
* the user and enabling an alternative authentication logic if the implementation supports it.
*/
- FACE_COVERING_DETECTED = 25,
-
- /**
- * Either one or both eyes are not visible in the frame. Prefer to use DARK_GLASSES_DETECTED if
- * the eyes are not visible due to dark glasses.
- */
- EYES_NOT_VISIBLE = 26,
-
- /**
- * The mouth is not visible in the frame. Prefer to use MASK_DETECTED if the mouth is not
- * visible due to a mask.
- */
- MOUTH_NOT_VISIBLE = 27,
+ MOUTH_COVERING_DETECTED = 25,
}
-
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
index afb7c8d..11cdf77 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/IFace.aidl
@@ -50,14 +50,4 @@
* @return A new session.
*/
ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
-
- /**
- * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close
- * its current session, and release all of the acquired resources.
- *
- * This should be used as a last resort to recover the HAL if the current session becomes
- * unresponsive. The implementation might choose to restart the HAL process to get back into a
- * good state.
- */
- void reset();
}
diff --git a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
index 6f2014a..66c7c38 100644
--- a/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
+++ b/biometrics/face/aidl/android/hardware/biometrics/face/ISession.aidl
@@ -45,7 +45,7 @@
* to allow addition of biometric enrollments.
* To secure this path, the following path is taken:
* 1) Upon user requesting face enroll, the framework requests
- * IFace#generateChallenge
+ * ISession#generateChallenge
* 2) Framework sends the challenge to the credential subsystem, and upon credential
* confirmation, a HAT is created, containing the challenge in the "challenge" field.
* 3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
@@ -53,11 +53,10 @@
* 5) Implementation now has confidence that the user entered their credential to allow
* biometric enrollment.
*
- * Note that the interface allows multiple in-flight challenges. For example, invoking
- * generateChallenge(0, 0, timeoutSec) twice does not invalidate the first challenge. The
- * challenge is invalidated only when:
- * 1) The provided timeout expires, or
- * 2) IFace#revokeChallenge is invoked
+ * Note that this interface allows multiple in-flight challenges. Invoking generateChallenge
+ * twice does not invalidate the first challenge. The challenge is invalidated only when:
+ * 1) Its lifespan exceeds the HAL's internal challenge timeout
+ * 2) IFingerprint#revokeChallenge is invoked
*
* For example, the following is a possible table of valid challenges:
* ----------------------------------------------
@@ -70,9 +69,8 @@
* ----------------------------------------------
*
* @param cookie A unique number identifying this operation
- * @param timeoutSec Duration for which the challenge is valid for
*/
- void generateChallenge(in int cookie, in int timeoutSec);
+ void generateChallenge(in int cookie);
/**
* revokeChallenge:
@@ -113,7 +111,7 @@
*
* Before capturing face data, the implementation must first verify the authenticity and
* integrity of the provided HardwareAuthToken. In addition, it must check that the challenge
- * within the provided HardwareAuthToken is valid. See IFace#generateChallenge. If any of
+ * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of
* the above checks fail, the framework must be notified via ISessionCallback#onError and the
* HAL must notify the framework when it returns to the idle state. See
* Error::UNABLE_TO_PROCESS.
diff --git a/biometrics/face/aidl/default/Face.cpp b/biometrics/face/aidl/default/Face.cpp
index 73e50f3..a4520de 100644
--- a/biometrics/face/aidl/default/Face.cpp
+++ b/biometrics/face/aidl/default/Face.cpp
@@ -63,8 +63,4 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Face::reset() {
- return ndk::ScopedAStatus::ok();
-}
-
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Face.h b/biometrics/face/aidl/default/Face.h
index 809b856..786b4f8 100644
--- a/biometrics/face/aidl/default/Face.h
+++ b/biometrics/face/aidl/default/Face.h
@@ -27,8 +27,6 @@
ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* _aidl_return) override;
-
- ndk::ScopedAStatus reset() override;
};
} // namespace aidl::android::hardware::biometrics::face
diff --git a/biometrics/face/aidl/default/Session.cpp b/biometrics/face/aidl/default/Session.cpp
index a7130e6..ce6c557 100644
--- a/biometrics/face/aidl/default/Session.cpp
+++ b/biometrics/face/aidl/default/Session.cpp
@@ -37,7 +37,7 @@
Session::Session(std::shared_ptr<ISessionCallback> cb) : cb_(std::move(cb)) {}
-ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/, int32_t /*timeoutSec*/) {
+ndk::ScopedAStatus Session::generateChallenge(int32_t /*cookie*/) {
LOG(INFO) << "generateChallenge";
if (cb_) {
cb_->onStateChanged(0, SessionState::GENERATING_CHALLENGE);
diff --git a/biometrics/face/aidl/default/Session.h b/biometrics/face/aidl/default/Session.h
index 0651726..eb9ae83 100644
--- a/biometrics/face/aidl/default/Session.h
+++ b/biometrics/face/aidl/default/Session.h
@@ -30,7 +30,7 @@
public:
explicit Session(std::shared_ptr<ISessionCallback> cb);
- ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override;
+ ndk::ScopedAStatus generateChallenge(int32_t cookie) override;
ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override;
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 07777c9..5d3df6f 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -36,5 +36,4 @@
interface IFingerprint {
android.hardware.biometrics.fingerprint.SensorProps[] getSensorProps();
android.hardware.biometrics.fingerprint.ISession createSession(in int sensorId, in int userId, in android.hardware.biometrics.fingerprint.ISessionCallback cb);
- void reset();
}
diff --git a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
index cade76d..87eaf96 100644
--- a/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/aidl_api/android.hardware.biometrics.fingerprint/current/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -34,7 +34,7 @@
package android.hardware.biometrics.fingerprint;
@VintfStability
interface ISession {
- void generateChallenge(in int cookie, in int timeoutSec);
+ void generateChallenge(in int cookie);
void revokeChallenge(in int cookie, in long challenge);
android.hardware.biometrics.common.ICancellationSignal enroll(in int cookie, in android.hardware.keymaster.HardwareAuthToken hat);
android.hardware.biometrics.common.ICancellationSignal authenticate(in int cookie, in long operationId);
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
index 37062ba..98a4530 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/IFingerprint.aidl
@@ -65,14 +65,4 @@
* @return A new session
*/
ISession createSession(in int sensorId, in int userId, in ISessionCallback cb);
-
- /**
- * Resets the HAL into a clean state, forcing it to cancel all of the pending operations, close
- * its current session, and release all of the acquired resources.
- *
- * This should be used as a last resort to recover the HAL if the current session becomes
- * unresponsive. The implementation might choose to restart the HAL process to get back into a
- * good state.
- */
- void reset();
}
diff --git a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
index ab7930d..ef2e6fc 100644
--- a/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
+++ b/biometrics/fingerprint/aidl/android/hardware/biometrics/fingerprint/ISession.aidl
@@ -61,7 +61,7 @@
* to allow addition of biometric enrollments.
* To secure this path, the following path is taken:
* 1) Upon user requesting fingerprint enroll, the framework requests
- * IFingerprint#generateChallenge
+ * ISession#generateChallenge
* 2) Framework sends the challenge to the credential subsystem, and upon credential
* confirmation, a HAT is created, containing the challenge in the "challenge" field.
* 3) Framework sends the HAT to the HAL, e.g. ISession#enroll.
@@ -69,10 +69,9 @@
* 5) Implementation now has confidence that the user entered their credential to allow
* biometric enrollment.
*
- * Note that the interface allows multiple in-flight challenges. For example, invoking
- * generateChallenge(0, 0, timeoutSec, cb) twice does not invalidate the first challenge. The
- * challenge is invalidated only when:
- * 1) The provided timeout expires, or
+ * Note that this interface allows multiple in-flight challenges. Invoking generateChallenge
+ * twice does not invalidate the first challenge. The challenge is invalidated only when:
+ * 1) Its lifespan exceeds the HAL's internal challenge timeout
* 2) IFingerprint#revokeChallenge is invoked
*
* For example, the following is a possible table of valid challenges:
@@ -86,9 +85,8 @@
* ----------------------------------------------
*
* @param cookie A unique number identifying this operation
- * @param timeoutSec Duration for which the challenge is valid for
*/
- void generateChallenge(in int cookie, in int timeoutSec);
+ void generateChallenge(in int cookie);
/**
* revokeChallenge:
@@ -117,7 +115,7 @@
*
* Before capturing fingerprint data, the implementation must first verify the authenticity and
* integrity of the provided HardwareAuthToken. In addition, it must check that the challenge
- * within the provided HardwareAuthToken is valid. See IFingerprint#generateChallenge. If any of
+ * within the provided HardwareAuthToken is valid. See ISession#generateChallenge. If any of
* the above checks fail, the framework must be notified via ISessionCallback#onError and the
* HAL must notify the framework when it returns to the idle state. See
* Error::UNABLE_TO_PROCESS.
diff --git a/biometrics/fingerprint/aidl/default/Fingerprint.cpp b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
index 206f518..79f48fe 100644
--- a/biometrics/fingerprint/aidl/default/Fingerprint.cpp
+++ b/biometrics/fingerprint/aidl/default/Fingerprint.cpp
@@ -63,10 +63,4 @@
return ndk::ScopedAStatus::ok();
}
-ndk::ScopedAStatus Fingerprint::reset() {
- // Crash. The system will start a fresh instance of the HAL.
- CHECK(false) << "Unable to reset. Crashing.";
- return ndk::ScopedAStatus::ok();
-}
-
} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/Session.cpp b/biometrics/fingerprint/aidl/default/Session.cpp
index 8db3205..c035407 100644
--- a/biometrics/fingerprint/aidl/default/Session.cpp
+++ b/biometrics/fingerprint/aidl/default/Session.cpp
@@ -60,13 +60,13 @@
return mCurrentState == SessionState::CLOSED;
}
-ndk::ScopedAStatus Session::generateChallenge(int32_t cookie, int32_t timeoutSec) {
+ndk::ScopedAStatus Session::generateChallenge(int32_t cookie) {
LOG(INFO) << "generateChallenge";
scheduleStateOrCrash(SessionState::GENERATING_CHALLENGE);
- mWorker->schedule(Callable::from([this, cookie, timeoutSec] {
+ mWorker->schedule(Callable::from([this, cookie] {
enterStateOrCrash(cookie, SessionState::GENERATING_CHALLENGE);
- mEngine->generateChallengeImpl(mCb.get(), timeoutSec);
+ mEngine->generateChallengeImpl(mCb.get());
enterIdling(cookie);
}));
diff --git a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
index 9343316..42e1aa5 100644
--- a/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
+++ b/biometrics/fingerprint/aidl/default/include/FakeFingerprintEngine.h
@@ -22,7 +22,7 @@
class FakeFingerprintEngine {
public:
- void generateChallengeImpl(ISessionCallback* cb, int32_t /*timeoutSec*/) {
+ void generateChallengeImpl(ISessionCallback* cb) {
LOG(INFO) << "generateChallengeImpl";
cb->onChallengeGenerated(0 /* challenge */);
}
@@ -73,4 +73,4 @@
}
};
-} // namespace aidl::android::hardware::biometrics::fingerprint
\ No newline at end of file
+} // namespace aidl::android::hardware::biometrics::fingerprint
diff --git a/biometrics/fingerprint/aidl/default/include/Fingerprint.h b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
index 9b43419..7bd3d6d 100644
--- a/biometrics/fingerprint/aidl/default/include/Fingerprint.h
+++ b/biometrics/fingerprint/aidl/default/include/Fingerprint.h
@@ -34,8 +34,6 @@
const std::shared_ptr<ISessionCallback>& cb,
std::shared_ptr<ISession>* out) override;
- ndk::ScopedAStatus reset() override;
-
private:
std::unique_ptr<FakeFingerprintEngine> mEngine;
WorkerThread mWorker;
diff --git a/biometrics/fingerprint/aidl/default/include/Session.h b/biometrics/fingerprint/aidl/default/include/Session.h
index b5e55b3..97d5645 100644
--- a/biometrics/fingerprint/aidl/default/include/Session.h
+++ b/biometrics/fingerprint/aidl/default/include/Session.h
@@ -32,7 +32,7 @@
Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
FakeFingerprintEngine* engine, WorkerThread* worker);
- ndk::ScopedAStatus generateChallenge(int32_t cookie, int32_t timeoutSec) override;
+ ndk::ScopedAStatus generateChallenge(int32_t cookie) override;
ndk::ScopedAStatus revokeChallenge(int32_t cookie, int64_t challenge) override;
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 5ba7a76..362ab41 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -495,7 +495,7 @@
* invoked carrying a proper selector;
* - program changes exactly to what was requested.
*/
-TEST_F(BroadcastRadioHalTest, DabTune) {
+TEST_P(BroadcastRadioHalTest, DabTune) {
ASSERT_TRUE(openSession());
ProgramSelector sel = {};
diff --git a/compatibility_matrices/compatibility_matrix.5.xml b/compatibility_matrices/compatibility_matrix.5.xml
index 96a3692..8e175f0 100644
--- a/compatibility_matrices/compatibility_matrix.5.xml
+++ b/compatibility_matrices/compatibility_matrix.5.xml
@@ -256,6 +256,13 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.identity</name>
+ <!--
+ b/178458001: identity V2 is introduced in R, but Android R VINTF does not support AIDL
+ versions. Hence, we only specify identity V2 in compatibility_matrix.5.xml in Android S+
+ branches. In Android R branches, the matrix implicitly specifies V1.
+ SingleManifestTest.ManifestAidlHalsServed has an exemption for this.
+ -->
+ <version>1-2</version>
<interface>
<name>IIdentityCredentialStore</name>
<instance>default</instance>
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 1f9cdb9..9e99c48 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -387,14 +387,6 @@
</interface>
</hal>
<hal format="hidl" optional="true">
- <name>android.hardware.memtrack</name>
- <version>1.0</version>
- <interface>
- <name>IMemtrack</name>
- <instance>default</instance>
- </interface>
- </hal>
- <hal format="hidl" optional="true">
<name>android.hardware.neuralnetworks</name>
<version>1.0-3</version>
<interface>
diff --git a/current.txt b/current.txt
index af50841..6c576ca 100644
--- a/current.txt
+++ b/current.txt
@@ -780,8 +780,8 @@
dabe23dde7c9e3ad65c61def7392f186d7efe7f4216f9b6f9cf0863745b1a9f4 android.hardware.keymaster@4.1::IKeymasterDevice
cd84ab19c590e0e73dd2307b591a3093ee18147ef95e6d5418644463a6620076 android.hardware.neuralnetworks@1.2::IDevice
f729ee6a5f136b25d79ea6895d24700fce413df555baaecf2c39e4440d15d043 android.hardware.neuralnetworks@1.0::types
-ba84f3a750b1cc43ac51074e8b8e22df924f3e6d9068fac50d95bcf57b2b1d61 android.hardware.neuralnetworks@1.2::types
-9fe5a4093043c2b5da4e9491aed1646c388a5d3059b8fd77d5b6a9807e6d3a3e android.hardware.neuralnetworks@1.3::types
+a84f8dac7a9b75de1cc2936a9b429b9b62b32a31ea88ca52c29f98f5ddc0fa95 android.hardware.neuralnetworks@1.2::types
+cd331b92312d16ab89f475c39296abbf539efc4114a8c5c2b136ad99b904ef33 android.hardware.neuralnetworks@1.3::types
e8c86c69c438da8d1549856c1bb3e2d1b8da52722f8235ff49a30f2cce91742c android.hardware.soundtrigger@2.1::ISoundTriggerHwCallback
b9fbb6e2e061ed0960939d48b785e9700210add1f13ed32ecd688d0f1ca20ef7 android.hardware.renderscript@1.0::types
0f53d70e1eadf8d987766db4bf6ae2048004682168f4cab118da576787def3fa android.hardware.radio@1.0::types
diff --git a/drm/1.4/types.hal b/drm/1.4/types.hal
index 17eba8a..a4490a5 100644
--- a/drm/1.4/types.hal
+++ b/drm/1.4/types.hal
@@ -119,6 +119,10 @@
*/
PROVISIONING_PARSE_ERROR,
/**
+ * The provisioning server detected an error in the provisioning request.
+ */
+ PROVISIONING_REQUEST_REJECTED,
+ /**
* Provisioning failed in a way that is likely to succeed on a subsequent
* attempt.
*/
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
index 2d21748..9c9a241 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/CorrelationVector.aidl
@@ -33,7 +33,7 @@
package android.hardware.gnss;
@VintfStability
parcelable CorrelationVector {
- int frequencyOffsetMps;
+ double frequencyOffsetMps;
double samplingWidthM;
double samplingStartM;
int[] magnitude;
diff --git a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
index 22a80ce..6fbabbc 100644
--- a/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
+++ b/gnss/aidl/android/hardware/gnss/CorrelationVector.aidl
@@ -22,11 +22,10 @@
*/
@VintfStability
parcelable CorrelationVector {
-
/**
* Frequency offset from reported pseudorange rate for this Correlation Vector.
*/
- int frequencyOffsetMps;
+ double frequencyOffsetMps;
/**
* Space between correlation samples in meters.
@@ -48,4 +47,4 @@
* The length of the array is defined by the GNSS chipset.
*/
int[] magnitude;
-}
\ No newline at end of file
+}
diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
index 9477997..c8ee0dd 100644
--- a/identity/aidl/default/common/IdentityCredential.cpp
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -253,14 +253,17 @@
}
}
- // Feed the auth token to secure hardware.
- if (!hwProxy_->setAuthToken(authToken.challenge, authToken.userId, authToken.authenticatorId,
- int(authToken.authenticatorType), authToken.timestamp.milliSeconds,
- authToken.mac, verificationToken_.challenge,
- verificationToken_.timestamp.milliSeconds,
- int(verificationToken_.securityLevel), verificationToken_.mac)) {
- return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
- IIdentityCredentialStore::STATUS_INVALID_DATA, "Invalid Auth Token"));
+ // Feed the auth token to secure hardware only if they're valid.
+ if (authToken.timestamp.milliSeconds != 0) {
+ if (!hwProxy_->setAuthToken(
+ authToken.challenge, authToken.userId, authToken.authenticatorId,
+ int(authToken.authenticatorType), authToken.timestamp.milliSeconds,
+ authToken.mac, verificationToken_.challenge,
+ verificationToken_.timestamp.milliSeconds,
+ int(verificationToken_.securityLevel), verificationToken_.mac)) {
+ return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+ IIdentityCredentialStore::STATUS_INVALID_DATA, "Invalid Auth Token"));
+ }
}
// We'll be feeding ACPs interleaved with certificates from the reader
diff --git a/identity/aidl/default/libeic/EicPresentation.c b/identity/aidl/default/libeic/EicPresentation.c
index 5e9a280..9e033b3 100644
--- a/identity/aidl/default/libeic/EicPresentation.c
+++ b/identity/aidl/default/libeic/EicPresentation.c
@@ -336,6 +336,18 @@
int verificationTokenSecurityLevel,
const uint8_t* verificationTokenMac,
size_t verificationTokenMacSize) {
+ // It doesn't make sense to accept any tokens if eicPresentationCreateAuthChallenge()
+ // was never called.
+ if (ctx->authChallenge == 0) {
+ eicDebug("Trying validate tokens when no auth-challenge was previously generated");
+ return false;
+ }
+ // At least the verification-token must have the same challenge as what was generated.
+ if (verificationTokenChallenge != ctx->authChallenge) {
+ eicDebug("Challenge in verification token does not match the challenge "
+ "previously generated");
+ return false;
+ }
if (!eicOpsValidateAuthToken(
challenge, secureUserId, authenticatorId, hardwareAuthenticatorType, timeStamp, mac,
macSize, verificationTokenChallenge, verificationTokenTimestamp,
@@ -360,18 +372,9 @@
return false;
}
+ // Only ACP with auth-on-every-presentation - those with timeout == 0 - need the
+ // challenge to match...
if (timeoutMillis == 0) {
- if (ctx->authTokenChallenge == 0) {
- eicDebug("No challenge in authToken");
- return false;
- }
-
- // If we didn't create a challenge, too bad but user auth with
- // timeoutMillis set to 0 needs it.
- if (ctx->authChallenge == 0) {
- eicDebug("No challenge was created for this session");
- return false;
- }
if (ctx->authTokenChallenge != ctx->authChallenge) {
eicDebug("Challenge in authToken (%" PRIu64
") doesn't match the challenge "
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index 5f81394..e0d60fc 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -136,48 +136,53 @@
return retval;
}
-string rsa_2048_key =
- hex2str("308204a50201000282010100caa620db7bbadfd351153a804e05a3115a0"
- "eea067316c7d6ae010086cc4d636edcc50b725c495027e79d7c6d65ec50"
- "5ab84107b0ca9f8389d0d812d42df3af0c1c50f1083b1eedd18921283e3"
- "9ebe95bd56795c9ba129afc63d60fb020b300c44861a73845508a992c54"
- "7cf4ce7694955c684bc130fe9a0478285d686da954989a7be3cd970de7e"
- "5eca8574c0617fed74717f7035655f65af7b5f9b982feca8eed643b96d8"
- "f1c4e6dcd96a9ccfcca3366d8f1c95f83a83ab785f997b78918ceca567d"
- "91cf2ea85c340c0d4462f31f8a31e648cd26e1116a97d17dcfec51e4336"
- "fa0725ff49216005911966748f94789c055795da023362091c977bdc0bd"
- "8e31902030100010282010100ca562da0785e1275d013be21b5c5731834"
- "2f8803808e52624bc2bc5fdb45b9ee4b8882f160abe2d8b52e4dba7d760"
- "295523bbc0e0d824fb81f4a5f2273ef47ec73a96dc0a6272f9573b22398"
- "5e04eb2fc25876fac04b2b6cadd2623f9da69d315e84028ef0c6865c822"
- "2a9d15504993eb8d17a321f55573af72e76757a690408c36909eb44a555"
- "4b571007edde150b47952287d942559e7f8cbcb2c47086aa291515f55c4"
- "deba6d1ebde0cca5ee899b3b0c4c21123bbf92feac53db515fe02d03b83"
- "2154e31122abcbb6fc80b49e1c8fc5528605935f8f6ead1237b16e83d23"
- "ad73e82ee008c3ff7b4666f4c137c20f52ae6fea5b54ed104c1c1bf75fc"
- "3c020102818100efa6b29bb0f6b81c8fecf3e73c3e5a59b71ffd31075c4"
- "0282269ee245367c2e54f0244301dad0b90dcce73f25c1caca2f4ef1774"
- "42a5d9e98a354bcd5ddae129bea2c0771d1ad51341f44ddf0c5c0f22252"
- "414e2de7af6c67754dba610ee2743f21789a89829ad91efc02c7c5588fe"
- "84b64df12dc5cee90df2e7dd4a1ca2886902818100d87937f039df50054"
- "7c7d5435ec8e89789b36a0e5c4004d4612a6ef2dce39ee4f24fb5d2da38"
- "dbf5f3d639681a11fc416618554b1ff51a8215446b676363f6a5e91ea6c"
- "957483e0a47ae36582bde9fba45c00e6e3fadc651cc87c170171d7fef6d"
- "0dc1f0ddb6eca2674064925b78542b32f2821605c29b6d0b65485081f5a"
- "f3102818100ee21453ee153f6d422cb7ffc586758dde6d239835b5df63e"
- "2b1bf94f4d35407b1ccc12b780f56f15ade2d36192d7c74f5174b66886c"
- "5484800563f113cde7e783d7e7922a2e003b3d4088ecc40fac4ead7df07"
- "85fb2e524219574fbeaefa063844b9d0c69f1462ed2d3f56b4e145742aa"
- "8ffbfd40cc731daf37023fa3d83df6902818055dc2e8dbfc68d2caafddd"
- "deacd7af397bca87c44e5eae0bb6c667df3831a83252d1bee274df9c8ef"
- "f39f6e70d8018b7afd0f2f3ab27426e5a151b2c94c56f6cfafbc75790a0"
- "fcca8307dc5238844282556c09cd3cc0a62a879f48e036aae2b58a61ac8"
- "ce6c3c933d914374fbdac0a665ffcc4100c14d624f82221fe9cad5fe102"
- "818100964193ee55581c9a82fe03f8eb018cdce8965f30745cc6e68154c"
- "b6618ef3cc57ae4798ff2a509306a135f7cf705ceb215fda6939c7a6353"
- "0c86a5ba02f491a64f6079e62b1b00b86859899febf3ed300edcc0b8b35"
- "1855a90d9d39a279be963f0972a256084a3c46575f796ad27dc801f67a3"
- "7a59e62e076b996f025a9c9042");
+/*
+ * DER-encoded PKCS#8 format RSA key. Generated using:
+ *
+ * openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | hexdump -e '30/1 "%02X" "\n"'
+ */
+string rsa_2048_key = hex2str(
+ "308204BD020100300D06092A864886F70D0101010500048204A7308204A3"
+ "0201000282010100BEBC342B56D443B1299F9A6A7056E80A897E318476A5"
+ "A18029E63B2ED739A61791D339F58DC763D9D14911F2EDEC383DEE11F631"
+ "9B44510E7A3ECD9B79B97382E49500ACF8117DC89CAF0E621F77756554A2"
+ "FD4664BFE7AB8B59AB48340DBFA27B93B5A81F6ECDEB02D0759307128DF3"
+ "E3BAD4055C8B840216DFAA5700670E6C5126F0962FCB70FF308F25049164"
+ "CCF76CC2DA66A7DD9A81A714C2809D69186133D29D84568E892B6FFBF319"
+ "9BDB14383EE224407F190358F111A949552ABA6714227D1BD7F6B20DD0CB"
+ "88F9467B719339F33BFF35B3870B3F62204E4286B0948EA348B524544B5F"
+ "9838F29EE643B079EEF8A713B220D7806924CDF7295070C5020301000102"
+ "82010069F377F35F2F584EF075353CCD1CA99738DB3DBC7C7FF35F9366CE"
+ "176DFD1B135AB10030344ABF5FBECF1D4659FDEF1C0FC430834BE1BE3911"
+ "951377BB3D563A2EA9CA8F4AD9C48A8CE6FD516A735C662686C7B4B3C09A"
+ "7B8354133E6F93F790D59EAEB92E84C9A4339302CCE28FDF04CCCAFA7DE3"
+ "F3A827D4F6F7D38E68B0EC6AB706645BF074A4E4090D06FB163124365FD5"
+ "EE7A20D350E9958CC30D91326E1B292E9EF5DB408EC42DAF737D20149704"
+ "D0A678A0FB5B5446863B099228A352D604BA8091A164D01D5AB05397C71E"
+ "AD20BE2A08FC528FE442817809C787FEE4AB97F97B9130D022153EDC6EB6"
+ "CBE7B0F8E3473F2E901209B5DB10F93604DB0102818100E83C0998214941"
+ "EA4F9293F1B77E2E99E6CF305FAF358238E126124FEAF2EB9724B2EA7B78"
+ "E6032343821A80E55D1D88FB12D220C3F41A56142FEC85796D1917F1E8C7"
+ "74F142B67D3D6E7B7E6B4383E94DB5929089DBB346D5BDAB40CC2D96EE04"
+ "09475E175C63BF78CFD744136740838127EA723FF3FE7FA368C1311B4A4E"
+ "0502818100D240FCC0F5D7715CDE21CB2DC86EA146132EA3B06F61FF2AF5"
+ "4BF38473F59DADCCE32B5F4CC32DD0BA6F509347B4B5B1B58C39F95E4798"
+ "CCBB43E83D0119ACF532F359CA743C85199F0286610E200997D731291717"
+ "9AC9B67558773212EC961E8BCE7A3CC809BC5486A96E4B0E6AF394D94E06"
+ "6A0900B7B70E82A44FB30053C102818100AD15DA1CBD6A492B66851BA8C3"
+ "16D38AB700E2CFDDD926A658003513C54BAA152B30021D667D20078F500F"
+ "8AD3E7F3945D74A891ED1A28EAD0FEEAEC8C14A8E834CF46A13D1378C99D"
+ "18940823CFDD27EC5810D59339E0C34198AC638E09C87CBB1B634A9864AE"
+ "9F4D5EB2D53514F67B4CAEC048C8AB849A02E397618F3271350281801FA2"
+ "C1A5331880A92D8F3E281C617108BF38244F16E352E69ED417C7153F9EC3"
+ "18F211839C643DCF8B4DD67CE2AC312E95178D5D952F06B1BF779F491692"
+ "4B70F582A23F11304E02A5E7565AE22A35E74FECC8B6FDC93F92A1A37703"
+ "E4CF0E63783BD02EB716A7ECBBFA606B10B74D01579522E7EF84D91FC522"
+ "292108D902C1028180796FE3825F9DCC85DF22D58690065D93898ACD65C0"
+ "87BEA8DA3A63BF4549B795E2CD0E3BE08CDEBD9FCF1720D9CDC5070D74F4"
+ "0DED8E1102C52152A31B6165F83A6722AECFCC35A493D7634664B888A08D"
+ "3EB034F12EA28BFEE346E205D334827F778B16ED40872BD29FCB36536B6E"
+ "93FFB06778696B4A9D81BB0A9423E63DE5");
string rsa_key = hex2str(
"30820275020100300d06092a864886f70d01010105000482025f3082025b"
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index e3cee93..03aed86 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -4895,25 +4895,25 @@
* Additional parameters specific to a particular operand type.
*/
safe_union ExtraParams {
- /**
- * No additional parameters.
- */
- Monostate none;
+ /**
+ * No additional parameters.
+ */
+ Monostate none;
- /**
- * Symmetric per-channel quantization parameters.
- *
- * Only applicable to operands of type TENSOR_QUANT8_SYMM_PER_CHANNEL.
- */
- SymmPerChannelQuantParams channelQuant;
+ /**
+ * Symmetric per-channel quantization parameters.
+ *
+ * Only applicable to operands of type TENSOR_QUANT8_SYMM_PER_CHANNEL.
+ */
+ SymmPerChannelQuantParams channelQuant;
- /**
- * Extension operand parameters.
- *
- * The framework treats this as an opaque data blob.
- * The format is up to individual extensions.
- */
- vec<uint8_t> extension;
+ /**
+ * Extension operand parameters.
+ *
+ * The framework treats this as an opaque data blob.
+ * The format is up to individual extensions.
+ */
+ vec<uint8_t> extension;
} extraParams;
};
diff --git a/neuralnetworks/1.2/types.t b/neuralnetworks/1.2/types.t
index 054d516..4c9fd02 100644
--- a/neuralnetworks/1.2/types.t
+++ b/neuralnetworks/1.2/types.t
@@ -291,25 +291,25 @@
* Additional parameters specific to a particular operand type.
*/
safe_union ExtraParams {
- /**
- * No additional parameters.
- */
- Monostate none;
+ /**
+ * No additional parameters.
+ */
+ Monostate none;
- /**
- * Symmetric per-channel quantization parameters.
- *
- * Only applicable to operands of type TENSOR_QUANT8_SYMM_PER_CHANNEL.
- */
- SymmPerChannelQuantParams channelQuant;
+ /**
+ * Symmetric per-channel quantization parameters.
+ *
+ * Only applicable to operands of type TENSOR_QUANT8_SYMM_PER_CHANNEL.
+ */
+ SymmPerChannelQuantParams channelQuant;
- /**
- * Extension operand parameters.
- *
- * The framework treats this as an opaque data blob.
- * The format is up to individual extensions.
- */
- vec<uint8_t> extension;
+ /**
+ * Extension operand parameters.
+ *
+ * The framework treats this as an opaque data blob.
+ * The format is up to individual extensions.
+ */
+ vec<uint8_t> extension;
} extraParams;
};
diff --git a/neuralnetworks/1.3/types.hal b/neuralnetworks/1.3/types.hal
index 51837fe..a5dbd5e 100644
--- a/neuralnetworks/1.3/types.hal
+++ b/neuralnetworks/1.3/types.hal
@@ -5340,7 +5340,6 @@
HIGH,
};
-
/**
* The capabilities of a driver.
*
diff --git a/neuralnetworks/1.3/types.t b/neuralnetworks/1.3/types.t
index 2901d18..9f69c9e 100644
--- a/neuralnetworks/1.3/types.t
+++ b/neuralnetworks/1.3/types.t
@@ -99,7 +99,6 @@
HIGH,
};
-
/**
* The capabilities of a driver.
*
diff --git a/power/stats/aidl/OWNERS b/power/stats/aidl/OWNERS
new file mode 100644
index 0000000..b290b49
--- /dev/null
+++ b/power/stats/aidl/OWNERS
@@ -0,0 +1,3 @@
+bsschwar@google.com
+krossmo@google.com
+tstrudel@google.com
diff --git a/power/stats/aidl/default/FakeEnergyConsumer.h b/power/stats/aidl/default/FakeEnergyConsumer.h
new file mode 100644
index 0000000..f41aa6e
--- /dev/null
+++ b/power/stats/aidl/default/FakeEnergyConsumer.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <PowerStats.h>
+
+#include <android-base/chrono_utils.h>
+
+#include <chrono>
+#include <random>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace stats {
+
+class FakeEnergyConsumer : public PowerStats::IEnergyConsumer {
+ public:
+ FakeEnergyConsumer(EnergyConsumerType type, std::string name) : mType(type), mName(name) {
+ mResult.timestampMs = 0;
+ mResult.energyUWs = 0;
+ mResult.attribution = {};
+ }
+
+ ~FakeEnergyConsumer() = default;
+
+ std::string getName() override { return mName; }
+
+ EnergyConsumerType getType() override { return mType; }
+
+ std::optional<EnergyConsumerResult> getEnergyConsumed() override {
+ mFakeEnergyConsumerResult.update(&mResult);
+ return mResult;
+ }
+
+ private:
+ class FakeEnergyConsumerResult {
+ public:
+ FakeEnergyConsumerResult() : mDistribution(1, 100) {}
+ void update(EnergyConsumerResult* result) {
+ // generates number in the range 1..100
+ auto randNum = std::bind(mDistribution, mGenerator);
+
+ // Get current time since boot in milliseconds
+ uint64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>(
+ ::android::base::boot_clock::now())
+ .time_since_epoch()
+ .count();
+ result->timestampMs = now;
+ result->energyUWs += randNum() * 100;
+ }
+
+ private:
+ std::default_random_engine mGenerator;
+ std::uniform_int_distribution<int> mDistribution;
+ };
+
+ EnergyConsumerType mType;
+ std::string mName;
+ FakeEnergyConsumerResult mFakeEnergyConsumerResult;
+ EnergyConsumerResult mResult;
+};
+
+} // namespace stats
+} // namespace power
+} // namespace hardware
+} // namespace android
+} // namespace aidl
\ No newline at end of file
diff --git a/power/stats/aidl/default/FakeEnergyMeter.h b/power/stats/aidl/default/FakeEnergyMeter.h
new file mode 100644
index 0000000..f0d4ee7
--- /dev/null
+++ b/power/stats/aidl/default/FakeEnergyMeter.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <PowerStats.h>
+
+#include <android-base/chrono_utils.h>
+
+#include <chrono>
+#include <random>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace stats {
+
+class FakeEnergyMeter : public PowerStats::IEnergyMeter {
+ public:
+ FakeEnergyMeter(std::vector<std::pair<std::string, std::string>> channelNames) {
+ int32_t channelId = 0;
+ for (const auto& [name, subsystem] : channelNames) {
+ Channel c;
+ c.id = channelId++;
+ c.name = name;
+ c.subsystem = subsystem;
+
+ EnergyMeasurement m;
+ m.id = c.id;
+ m.timestampMs = 0;
+ m.durationMs = 0;
+ m.energyUWs = 0;
+
+ mChannels.push_back(c);
+ mEnergyMeasurements.push_back(m);
+ }
+ }
+ ~FakeEnergyMeter() = default;
+ ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds,
+ std::vector<EnergyMeasurement>* _aidl_return) override {
+ for (auto& measurement : mEnergyMeasurements) {
+ mFakeEnergyMeasurement.update(&measurement);
+ }
+
+ if (in_channelIds.empty()) {
+ *_aidl_return = mEnergyMeasurements;
+ } else {
+ for (int32_t id : in_channelIds) {
+ if (id >= 0 && id < mEnergyMeasurements.size()) {
+ _aidl_return->push_back(mEnergyMeasurements[id]);
+ }
+ }
+ }
+
+ return ndk::ScopedAStatus::ok();
+ }
+
+ ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override {
+ *_aidl_return = mChannels;
+ return ndk::ScopedAStatus::ok();
+ }
+
+ private:
+ class FakeEnergyMeasurement {
+ public:
+ FakeEnergyMeasurement() : mDistribution(1, 100) {}
+ void update(EnergyMeasurement* measurement) {
+ // generates number in the range 1..100
+ auto randNum = std::bind(mDistribution, mGenerator);
+
+ // Get current time since boot in milliseconds
+ uint64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>(
+ ::android::base::boot_clock::now())
+ .time_since_epoch()
+ .count();
+ measurement->timestampMs = now;
+ measurement->durationMs = now;
+ measurement->energyUWs += randNum() * 100;
+ }
+
+ private:
+ std::default_random_engine mGenerator;
+ std::uniform_int_distribution<int> mDistribution;
+ };
+
+ std::vector<Channel> mChannels;
+ FakeEnergyMeasurement mFakeEnergyMeasurement;
+ std::vector<EnergyMeasurement> mEnergyMeasurements;
+};
+
+} // namespace stats
+} // namespace power
+} // namespace hardware
+} // namespace android
+} // namespace aidl
\ No newline at end of file
diff --git a/power/stats/aidl/default/FakeStateResidencyDataProvider.h b/power/stats/aidl/default/FakeStateResidencyDataProvider.h
new file mode 100644
index 0000000..2eeab61
--- /dev/null
+++ b/power/stats/aidl/default/FakeStateResidencyDataProvider.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <PowerStats.h>
+
+#include <random>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace power {
+namespace stats {
+
+class FakeStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
+ public:
+ FakeStateResidencyDataProvider(const std::string& name, std::vector<State> states)
+ : mName(name), mStates(states) {
+ for (const auto& state : mStates) {
+ StateResidency r;
+ r.id = state.id;
+ r.totalTimeInStateMs = 0;
+ r.totalStateEntryCount = 0;
+ r.lastEntryTimestampMs = 0;
+ mResidencies.push_back(r);
+ }
+ }
+ ~FakeStateResidencyDataProvider() = default;
+
+ // Methods from PowerStats::IStateResidencyDataProvider
+ bool getStateResidencies(
+ std::unordered_map<std::string, std::vector<StateResidency>>* residencies) override {
+ for (auto& residency : mResidencies) {
+ mFakeStateResidency.update(&residency);
+ }
+
+ residencies->emplace(mName, mResidencies);
+ return true;
+ }
+
+ std::unordered_map<std::string, std::vector<State>> getInfo() override {
+ return {{mName, mStates}};
+ }
+
+ private:
+ class FakeStateResidency {
+ public:
+ FakeStateResidency() : mDistribution(1, 100) {}
+ void update(StateResidency* residency) {
+ // generates number in the range 1..100
+ auto randNum = std::bind(mDistribution, mGenerator);
+
+ residency->totalTimeInStateMs += randNum() * 100;
+ residency->totalStateEntryCount += randNum();
+ residency->lastEntryTimestampMs += randNum() * 100;
+ }
+
+ private:
+ std::default_random_engine mGenerator;
+ std::uniform_int_distribution<int> mDistribution;
+ };
+
+ const std::string mName;
+ const std::vector<State> mStates;
+ FakeStateResidency mFakeStateResidency;
+ std::vector<StateResidency> mResidencies;
+};
+
+} // namespace stats
+} // namespace power
+} // namespace hardware
+} // namespace android
+} // namespace aidl
\ No newline at end of file
diff --git a/power/stats/aidl/default/PowerStats.cpp b/power/stats/aidl/default/PowerStats.cpp
index 0ffbd08..1373502 100644
--- a/power/stats/aidl/default/PowerStats.cpp
+++ b/power/stats/aidl/default/PowerStats.cpp
@@ -18,46 +18,157 @@
#include <android-base/logging.h>
+#include <numeric>
+
namespace aidl {
namespace android {
namespace hardware {
namespace power {
namespace stats {
+void PowerStats::addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p) {
+ if (!p) {
+ return;
+ }
+
+ int32_t id = mPowerEntityInfos.size();
+
+ for (const auto& [entityName, states] : p->getInfo()) {
+ PowerEntity i = {
+ .id = id++,
+ .name = entityName,
+ .states = states,
+ };
+ mPowerEntityInfos.emplace_back(i);
+ mStateResidencyDataProviders.emplace_back(std::move(p));
+ }
+}
+
+void PowerStats::addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p) {
+ if (!p) {
+ return;
+ }
+
+ EnergyConsumerType type = p->getType();
+ std::string name = p->getName();
+ int32_t count = count_if(mEnergyConsumerInfos.begin(), mEnergyConsumerInfos.end(),
+ [&type](const EnergyConsumer& c) { return type == c.type; });
+ int32_t id = mEnergyConsumers.size();
+ mEnergyConsumerInfos.emplace_back(
+ EnergyConsumer{.id = id, .ordinal = count, .type = type, .name = name});
+ mEnergyConsumers.emplace_back(std::move(p));
+}
+
+void PowerStats::setEnergyMeter(std::unique_ptr<IEnergyMeter> p) {
+ mEnergyMeter = std::move(p);
+}
+
ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) {
- (void)_aidl_return;
+ *_aidl_return = mPowerEntityInfos;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector<int32_t>& in_powerEntityIds,
std::vector<StateResidencyResult>* _aidl_return) {
- (void)in_powerEntityIds;
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
+ if (mPowerEntityInfos.empty()) {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ // If in_powerEntityIds is empty then return data for all supported entities
+ if (in_powerEntityIds.empty()) {
+ std::vector<int32_t> v(mPowerEntityInfos.size());
+ std::iota(std::begin(v), std::end(v), 0);
+ return getStateResidency(v, _aidl_return);
+ }
+
+ binder_status_t err = STATUS_OK;
+
+ std::unordered_map<std::string, std::vector<StateResidency>> stateResidencies;
+
+ for (const int32_t id : in_powerEntityIds) {
+ // skip any invalid ids
+ if (id < 0 || id >= mPowerEntityInfos.size()) {
+ continue;
+ }
+
+ // Check to see if we already have data for the given id
+ std::string powerEntityName = mPowerEntityInfos[id].name;
+ if (stateResidencies.find(powerEntityName) == stateResidencies.end()) {
+ mStateResidencyDataProviders[id]->getStateResidencies(&stateResidencies);
+ }
+
+ // Append results if we have them
+ auto stateResidency = stateResidencies.find(powerEntityName);
+ if (stateResidency != stateResidencies.end()) {
+ StateResidencyResult res = {
+ .id = id,
+ .stateResidencyData = stateResidency->second,
+ };
+ _aidl_return->emplace_back(res);
+ } else {
+ // Failed to retrieve results for the given id.
+ err = STATUS_FAILED_TRANSACTION;
+ }
+ }
+
+ return ndk::ScopedAStatus::fromStatus(err);
}
ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector<EnergyConsumer>* _aidl_return) {
- (void)_aidl_return;
+ *_aidl_return = mEnergyConsumerInfos;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus PowerStats::getEnergyConsumed(const std::vector<int32_t>& in_energyConsumerIds,
std::vector<EnergyConsumerResult>* _aidl_return) {
- (void)in_energyConsumerIds;
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
+ if (mEnergyConsumers.empty()) {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ // If in_powerEntityIds is empty then return data for all supported energy consumers
+ if (in_energyConsumerIds.empty()) {
+ std::vector<int32_t> v(mEnergyConsumerInfos.size());
+ std::iota(std::begin(v), std::end(v), 0);
+ return getEnergyConsumed(v, _aidl_return);
+ }
+
+ binder_status_t err = STATUS_OK;
+
+ for (const auto id : in_energyConsumerIds) {
+ // skip any invalid ids
+ if (id < 0 || id >= mEnergyConsumers.size()) {
+ continue;
+ }
+
+ auto optionalResult = mEnergyConsumers[id]->getEnergyConsumed();
+ if (optionalResult) {
+ EnergyConsumerResult result = optionalResult.value();
+ result.id = id;
+ _aidl_return->emplace_back(result);
+ } else {
+ // Failed to retrieve results for the given id.
+ err = STATUS_FAILED_TRANSACTION;
+ }
+ }
+
+ return ndk::ScopedAStatus::fromStatus(err);
}
ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector<Channel>* _aidl_return) {
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
+ if (!mEnergyMeter) {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ return mEnergyMeter->getEnergyMeterInfo(_aidl_return);
}
ndk::ScopedAStatus PowerStats::readEnergyMeter(const std::vector<int32_t>& in_channelIds,
std::vector<EnergyMeasurement>* _aidl_return) {
- (void)in_channelIds;
- (void)_aidl_return;
- return ndk::ScopedAStatus::ok();
+ if (!mEnergyMeter) {
+ return ndk::ScopedAStatus::ok();
+ }
+
+ return mEnergyMeter->readEnergyMeter(in_channelIds, _aidl_return);
}
} // namespace stats
diff --git a/power/stats/aidl/default/PowerStats.h b/power/stats/aidl/default/PowerStats.h
index cb98e55..f4c5e69 100644
--- a/power/stats/aidl/default/PowerStats.h
+++ b/power/stats/aidl/default/PowerStats.h
@@ -18,6 +18,8 @@
#include <aidl/android/hardware/power/stats/BnPowerStats.h>
+#include <unordered_map>
+
namespace aidl {
namespace android {
namespace hardware {
@@ -26,7 +28,37 @@
class PowerStats : public BnPowerStats {
public:
+ class IStateResidencyDataProvider {
+ public:
+ virtual ~IStateResidencyDataProvider() = default;
+ virtual bool getStateResidencies(
+ std::unordered_map<std::string, std::vector<StateResidency>>* residencies) = 0;
+ virtual std::unordered_map<std::string, std::vector<State>> getInfo() = 0;
+ };
+
+ class IEnergyConsumer {
+ public:
+ virtual ~IEnergyConsumer() = default;
+ virtual std::string getName() = 0;
+ virtual EnergyConsumerType getType() = 0;
+ virtual std::optional<EnergyConsumerResult> getEnergyConsumed() = 0;
+ };
+
+ class IEnergyMeter {
+ public:
+ virtual ~IEnergyMeter() = default;
+ virtual ndk::ScopedAStatus readEnergyMeter(
+ const std::vector<int32_t>& in_channelIds,
+ std::vector<EnergyMeasurement>* _aidl_return) = 0;
+ virtual ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) = 0;
+ };
+
PowerStats() = default;
+
+ void addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p);
+ void addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p);
+ void setEnergyMeter(std::unique_ptr<IEnergyMeter> p);
+
// Methods from aidl::android::hardware::power::stats::IPowerStats
ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) override;
ndk::ScopedAStatus getStateResidency(const std::vector<int32_t>& in_powerEntityIds,
@@ -37,6 +69,15 @@
ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override;
ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds,
std::vector<EnergyMeasurement>* _aidl_return) override;
+
+ private:
+ std::vector<std::unique_ptr<IStateResidencyDataProvider>> mStateResidencyDataProviders;
+ std::vector<PowerEntity> mPowerEntityInfos;
+
+ std::vector<std::unique_ptr<IEnergyConsumer>> mEnergyConsumers;
+ std::vector<EnergyConsumer> mEnergyConsumerInfos;
+
+ std::unique_ptr<IEnergyMeter> mEnergyMeter;
};
} // namespace stats
diff --git a/power/stats/aidl/default/main.cpp b/power/stats/aidl/default/main.cpp
index 0469b4c..2fe3d2e 100644
--- a/power/stats/aidl/default/main.cpp
+++ b/power/stats/aidl/default/main.cpp
@@ -16,16 +16,61 @@
#include "PowerStats.h"
+#include "FakeEnergyConsumer.h"
+#include "FakeEnergyMeter.h"
+#include "FakeStateResidencyDataProvider.h"
+
#include <android-base/logging.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
+using aidl::android::hardware::power::stats::EnergyConsumerType;
+using aidl::android::hardware::power::stats::FakeEnergyConsumer;
+using aidl::android::hardware::power::stats::FakeEnergyMeter;
+using aidl::android::hardware::power::stats::FakeStateResidencyDataProvider;
using aidl::android::hardware::power::stats::PowerStats;
+using aidl::android::hardware::power::stats::State;
+
+void setFakeEnergyMeter(std::shared_ptr<PowerStats> p) {
+ p->setEnergyMeter(
+ std::make_unique<FakeEnergyMeter>(std::vector<std::pair<std::string, std::string>>{
+ {"Rail1", "Display"},
+ {"Rail2", "CPU"},
+ {"Rail3", "Modem"},
+ }));
+}
+
+void addFakeStateResidencyDataProvider1(std::shared_ptr<PowerStats> p) {
+ p->addStateResidencyDataProvider(std::make_unique<FakeStateResidencyDataProvider>(
+ "CPU", std::vector<State>{{0, "Idle"}, {1, "Active"}}));
+}
+
+void addFakeStateResidencyDataProvider2(std::shared_ptr<PowerStats> p) {
+ p->addStateResidencyDataProvider(std::make_unique<FakeStateResidencyDataProvider>(
+ "Display", std::vector<State>{{0, "Off"}, {1, "On"}}));
+}
+
+void addFakeEnergyConsumer1(std::shared_ptr<PowerStats> p) {
+ p->addEnergyConsumer(std::make_unique<FakeEnergyConsumer>(EnergyConsumerType::OTHER, "GPU"));
+}
+
+void addFakeEnergyConsumer2(std::shared_ptr<PowerStats> p) {
+ p->addEnergyConsumer(
+ std::make_unique<FakeEnergyConsumer>(EnergyConsumerType::MOBILE_RADIO, "MODEM"));
+}
int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0);
std::shared_ptr<PowerStats> p = ndk::SharedRefBase::make<PowerStats>();
+ setFakeEnergyMeter(p);
+
+ addFakeStateResidencyDataProvider1(p);
+ addFakeStateResidencyDataProvider2(p);
+
+ addFakeEnergyConsumer1(p);
+ addFakeEnergyConsumer2(p);
+
const std::string instance = std::string() + PowerStats::descriptor + "/default";
binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
CHECK(status == STATUS_OK);
diff --git a/radio/1.0/vts/functional/Android.bp b/radio/1.0/vts/functional/Android.bp
index 9e92d93..2c0e70a 100644
--- a/radio/1.0/vts/functional/Android.bp
+++ b/radio/1.0/vts/functional/Android.bp
@@ -43,6 +43,8 @@
],
static_libs: [
"android.hardware.radio@1.0",
+ "android.hardware.radio@1.1",
+ "android.hardware.radio@1.2",
],
test_config: "vts_hal_radio_target_test.xml",
test_suites: [
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
index e3ee9d4..655b869 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_data.cpp
@@ -15,6 +15,7 @@
*/
#include <android-base/logging.h>
+#include <android/hardware/radio/1.2/IRadio.h>
#include <radio_hidl_hal_utils_v1_0.h>
using namespace ::android::hardware::radio::V1_0;
@@ -139,6 +140,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+ // setupDataCall is deprecated on radio::V1_2 with setupDataCall_1_2
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
{RadioError::NONE, RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW,
@@ -164,6 +168,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+ // deactivateDataCall is deprecated on radio::V1_2 with deactiveDataCall_1_2
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
{RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
index 3f96473..624d003 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
+++ b/radio/1.0/vts/functional/radio_hidl_hal_misc.cpp
@@ -15,6 +15,7 @@
*/
#include <android-base/logging.h>
+#include <android/hardware/radio/1.2/IRadio.h>
#include <radio_hidl_hal_utils_v1_0.h>
/*
@@ -771,6 +772,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+ // HAL 1.2 and later use the always-on LCE that relies on indications.
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(CheckAnyOfErrors(
radioRsp->rspInfo.error,
@@ -792,6 +796,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+ // HAL 1.2 and later use the always-on LCE that relies on indications.
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
{RadioError::NONE, RadioError::LCE_NOT_SUPPORTED,
@@ -812,6 +819,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+ // HAL 1.2 and later use the always-on LCE that relies on indications.
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
{RadioError::NONE, RadioError::INTERNAL_ERR,
@@ -971,6 +981,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+ // setIndicationFilter is deprecated on radio::V1_2 with setIndicationFilter_1_2
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
std::cout << static_cast<int>(radioRsp->rspInfo.error) << std::endl;
if (cardStatus.cardState == CardState::ABSENT) {
@@ -992,6 +1005,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp->rspInfo.type);
EXPECT_EQ(serial, radioRsp->rspInfo.serial);
+ // setSimCardPower is deprecated on radio::V1_1 with setSimCardPower_1_1
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_1);
+
if (cardStatus.cardState == CardState::ABSENT) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp->rspInfo.error,
{RadioError::NONE, RadioError::REQUEST_NOT_SUPPORTED}));
diff --git a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
index 8a551f7..e3e9473 100644
--- a/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
+++ b/radio/1.0/vts/functional/radio_hidl_hal_utils_v1_0.h
@@ -38,6 +38,8 @@
#define TIMEOUT_PERIOD 75
#define RADIO_SERVICE_NAME "slot1"
+#define SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(__ver__) \
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL(__ver__, radio, radioRsp)
class RadioHidlTest;
extern CardStatus cardStatus;
diff --git a/radio/1.0/vts/functional/vts_test_util.cpp b/radio/1.0/vts/functional/vts_test_util.cpp
index 9a2d089..fc37201 100644
--- a/radio/1.0/vts/functional/vts_test_util.cpp
+++ b/radio/1.0/vts/functional/vts_test_util.cpp
@@ -19,6 +19,8 @@
#include <iostream>
#include "VtsCoreUtil.h"
+#define WAIT_TIMEOUT_PERIOD 75
+
int GetRandomSerialNumber() {
return rand();
}
@@ -99,4 +101,33 @@
::android::hardware::radio::V1_0::RegState::NOT_REG_MT_SEARCHING_OP_EM == state ||
::android::hardware::radio::V1_0::RegState::REG_DENIED_EM == state ||
::android::hardware::radio::V1_0::RegState::UNKNOWN_EM == state;
-}
\ No newline at end of file
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioResponseWaiter::notify(int receivedSerial) {
+ std::unique_lock<std::mutex> lock(mtx_);
+ if (serial == receivedSerial) {
+ count_++;
+ cv_.notify_one();
+ }
+}
+
+/*
+ * Wait till the response message is notified or till WAIT_TIMEOUT_PERIOD.
+ */
+std::cv_status RadioResponseWaiter::wait() {
+ std::unique_lock<std::mutex> lock(mtx_);
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock, now + std::chrono::seconds(WAIT_TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) {
+ return status;
+ }
+ }
+ count_--;
+ return status;
+}
diff --git a/radio/1.0/vts/functional/vts_test_util.h b/radio/1.0/vts/functional/vts_test_util.h
index 218e823..eeb1d29 100644
--- a/radio/1.0/vts/functional/vts_test_util.h
+++ b/radio/1.0/vts/functional/vts_test_util.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#pragma once
+
#include <android-base/logging.h>
#include <android/hardware/radio/1.0/types.h>
@@ -25,6 +27,20 @@
using ::android::hardware::radio::V1_0::SapResultCode;
using namespace std;
+/*
+ * MACRO used to skip test case when radio response return error REQUEST_NOT_SUPPORTED
+ * on HAL versions which has deprecated the request interfaces. The MACRO can only be used
+ * AFTER receiving radio response.
+ */
+#define SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL(__ver__, __radio__, __radioRsp__) \
+ do { \
+ sp<::android::hardware::radio::V##__ver__::IRadio> __radio = \
+ ::android::hardware::radio::V##__ver__::IRadio::castFrom(__radio__); \
+ if (__radio && __radioRsp__->rspInfo.error == RadioError::REQUEST_NOT_SUPPORTED) { \
+ GTEST_SKIP() << "REQUEST_NOT_SUPPORTED"; \
+ } \
+ } while (0)
+
enum CheckFlag {
CHECK_DEFAULT = 0,
CHECK_GENERAL_ERROR = 1,
@@ -81,4 +97,24 @@
/*
* Check if voice status is in service.
*/
-bool isVoiceInService(RegState state);
\ No newline at end of file
+bool isVoiceInService(RegState state);
+
+/**
+ * Used when waiting for an asynchronous response from the HAL.
+ */
+class RadioResponseWaiter {
+ protected:
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_;
+
+ public:
+ /* Serial number for radio request */
+ int serial;
+
+ /* Used as a mechanism to inform the test about data/event callback */
+ void notify(int receivedSerial);
+
+ /* Test code calls this function to wait for response */
+ std::cv_status wait();
+};
diff --git a/radio/1.1/vts/functional/Android.bp b/radio/1.1/vts/functional/Android.bp
index 3ada6ff..b3def8e 100644
--- a/radio/1.1/vts/functional/Android.bp
+++ b/radio/1.1/vts/functional/Android.bp
@@ -35,6 +35,7 @@
],
static_libs: [
"RadioVtsTestUtilBase",
+ "android.hardware.radio@1.2",
"android.hardware.radio@1.1",
"android.hardware.radio@1.0",
],
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
index 08121fd..389944b 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.1/vts/functional/radio_hidl_hal_api.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android/hardware/radio/1.2/IRadio.h>
#include <radio_hidl_hal_utils_v1_1.h>
#include <vector>
@@ -107,6 +108,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+ // startNetworkScan is deprecated on radio::V1_2 with startNetworkScan_1_2
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
if (cardStatus.cardState == CardState::ABSENT) {
ALOGI("startNetworkScan, rspInfo.error = %d\n", (int32_t)radioRsp_v1_1->rspInfo.error);
ASSERT_TRUE(CheckAnyOfErrors(
@@ -131,6 +135,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_1->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_1->rspInfo.serial);
+ // startNetworkScan is deprecated on radio::V1_2 with startNetworkScan_1_2
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_2);
+
if (cardStatus.cardState == CardState::ABSENT) {
ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %d\n",
(int32_t)radioRsp_v1_1->rspInfo.error);
diff --git a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
index b81ee13..bafde77 100644
--- a/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
+++ b/radio/1.1/vts/functional/radio_hidl_hal_utils_v1_1.h
@@ -40,6 +40,8 @@
#define TIMEOUT_PERIOD 75
#define RADIO_SERVICE_NAME "slot1"
+#define SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(__ver__) \
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL(__ver__, radio_v1_1, radioRsp_v1_1)
class RadioHidlTest_v1_1;
extern CardStatus cardStatus;
diff --git a/radio/1.2/vts/functional/Android.bp b/radio/1.2/vts/functional/Android.bp
index 1447ade..a62000f 100644
--- a/radio/1.2/vts/functional/Android.bp
+++ b/radio/1.2/vts/functional/Android.bp
@@ -36,6 +36,8 @@
],
static_libs: [
"RadioVtsTestUtilBase",
+ "android.hardware.radio@1.4",
+ "android.hardware.radio@1.3",
"android.hardware.radio@1.2",
"android.hardware.radio@1.1",
"android.hardware.radio@1.0",
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
index acb1b0e..2400bde 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.2/vts/functional/radio_hidl_hal_api.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android/hardware/radio/1.4/IRadio.h>
#include <radio_hidl_hal_utils_v1_2.h>
#include <vector>
@@ -57,6 +58,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan, rspInfo.error = %s\n", toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_2->rspInfo.error, {RadioError::SIM_ABSENT}));
@@ -94,6 +98,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -126,6 +133,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -158,6 +168,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -190,6 +203,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -222,6 +238,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -254,6 +273,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -286,6 +308,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -322,6 +347,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
@@ -359,6 +387,9 @@
EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_2->rspInfo.type);
EXPECT_EQ(serial, radioRsp_v1_2->rspInfo.serial);
+ // startNetworkScan_1_2 is deprecated in radio::V1_4 with startNetworkScan_1_4
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(1_4);
+
ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
toString(radioRsp_v1_2->rspInfo.error).c_str());
if (cardStatus.base.cardState == CardState::ABSENT) {
diff --git a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
index 479340c..81286d2 100644
--- a/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
+++ b/radio/1.2/vts/functional/radio_hidl_hal_utils_v1_2.h
@@ -50,6 +50,8 @@
#define TIMEOUT_PERIOD 75
#define RADIO_SERVICE_NAME "slot1"
+#define SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL_VERSION_AT_LEAST(__ver__) \
+ SKIP_TEST_IF_REQUEST_NOT_SUPPORTED_WITH_HAL(__ver__, radio_v1_2, radioRsp_v1_2)
class RadioHidlTest_v1_2;
extern ::android::hardware::radio::V1_2::CardStatus cardStatus;
@@ -682,4 +684,4 @@
/* radio config service handle */
sp<IRadioConfig> radioConfig;
-};
\ No newline at end of file
+};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 6400c63..95eba69 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -813,6 +813,11 @@
* see: 3GPP TS 24.501 Section 9.11.2.8.
*/
int32_t mappedHplmnSD;
+
+ /**
+ * Field to indicate the current status of the slice.
+ */
+ SliceStatus status;
};
/**
@@ -986,9 +991,9 @@
*/
vec<UrspRule> urspRules;
/**
- * Struct containing all NSSAIs (list of slice info).
+ * List of all slices.
*/
- Nssais nssais;
+ vec<SliceInfo> sliceInfo;
};
/**
@@ -1011,7 +1016,6 @@
vec<RouteSelectionDescriptor> routeSelectionDescriptor;
};
-
/**
* This struct represents a single route selection descriptor as defined in
* 3GPP TS 24.526.
@@ -1067,47 +1071,13 @@
SscMode value;
};
-/**
- * This struct contains all NSSAIs (lists of slices).
- */
-struct Nssais {
- /**
- * These are all the slices configured by the network. This includes allowed
- * and rejected slices, as well as slices that are neither allowed nor rejected
- * yet. Empty vector indicates that no slices are configured, and in that case
- * allowed and rejected vectors must be empty as well.
- */
- vec<SliceInfo> configured;
- /**
- * These are all the slices that the UE is allowed to use. All these slices
- * must be configured as well. Empty vector indicates that no slices are
- * allowed yet.
- */
- vec<SliceInfo> allowed;
- /**
- * These are all the slices that the UE is not allowed to use. All these slices
- * must be configured as well. Empty vector indicates that no slices are
- * rejected yet.
- */
- vec<RejectedSliceInfo> rejected;
- /**
- * Default configured NSSAI
- */
- vec<SliceInfo> defaultConfigured;
-};
-
-/**
- * This struct represents a network slice rejected by the network. It contains a
- * rejectionCause corresponding to a rejected network slice.
- */
-struct RejectedSliceInfo {
- SliceInfo sliceInfo;
- SliceRejectionCause rejectionCause;
-};
-
-enum SliceRejectionCause : int32_t {
- NOT_AVAILABLE_IN_PLMN,
- NOT_AVAILABLE_IN_REG_AREA,
+enum SliceStatus : int32_t {
+ UNKNOWN,
+ CONFIGURED, // Configured but not allowed or rejected yet
+ ALLOWED, // Allowed to be used
+ REJECTED_NOT_AVAILABLE_IN_PLMN, // Rejected because not available in PLMN
+ REJECTED_NOT_AVAILABLE_IN_REG_AREA, // Rejected because not available in reg area
+ DEFAULT_CONFIGURED, // Considered valid when configured/allowed slices are not available
};
/**
diff --git a/radio/1.6/vts/functional/Android.bp b/radio/1.6/vts/functional/Android.bp
index dde718b..65b0dd0 100644
--- a/radio/1.6/vts/functional/Android.bp
+++ b/radio/1.6/vts/functional/Android.bp
@@ -36,6 +36,7 @@
],
static_libs: [
"RadioVtsTestUtilBase",
+ "RadioConfigVtsTestResponse",
"android.hardware.radio@1.6",
"android.hardware.radio@1.5",
"android.hardware.radio@1.4",
@@ -45,8 +46,13 @@
"android.hardware.radio@1.0",
"android.hardware.radio.config@1.0",
"android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
],
- header_libs: ["radio.util.header@1.0"],
+ header_libs: [
+ "radio.util.header@1.0",
+ "radio.config.util.header@1.3",
+ ],
test_suites: [
"general-tests",
"vts",
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index 59f7682..6255f66 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -45,35 +45,6 @@
EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.base.cardState);
}
-/*
- * Notify that the response message is received.
- */
-void RadioHidlTest_v1_6::notify(int receivedSerial) {
- std::unique_lock<std::mutex> lock(mtx_);
- if (serial == receivedSerial) {
- count_++;
- cv_.notify_one();
- }
-}
-
-/*
- * Wait till the response message is notified or till TIMEOUT_PERIOD.
- */
-std::cv_status RadioHidlTest_v1_6::wait() {
- std::unique_lock<std::mutex> lock(mtx_);
-
- std::cv_status status = std::cv_status::no_timeout;
- auto now = std::chrono::system_clock::now();
- while (count_ == 0) {
- status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
- if (status == std::cv_status::timeout) {
- return status;
- }
- }
- count_--;
- return status;
-}
-
void RadioHidlTest_v1_6::clearPotentialEstablishedCalls() {
// Get the current call Id to hangup the established emergency call.
serial = GetRandomSerialNumber();
@@ -108,3 +79,31 @@
radio_v1_6->getDataCallList_1_6(serial);
EXPECT_EQ(std::cv_status::no_timeout, wait());
}
+
+/**
+ * Specific features on the Radio Hal rely on Radio Hal Capabilities. The VTS
+ * tests related to that features must not run if the related capability is
+ * disabled.
+ * <p/>
+ * Typical usage within VTS:
+ * if (getRadioHalCapabilities().modemReducedFeatureSet) return;
+ */
+HalDeviceCapabilities RadioHidlTest_v1_6::getRadioHalCapabilities() {
+ sp<::android::hardware::radio::config::V1_3::IRadioConfig> radioConfig_v1_3 =
+ ::android::hardware::radio::config::V1_3::IRadioConfig::getService();
+ if (radioConfig_v1_3.get() == nullptr) {
+ // If v1_3 isn't present, the values are initialized to false
+ HalDeviceCapabilities radioHalCapabilities;
+ memset(&radioHalCapabilities, 0, sizeof(radioHalCapabilities));
+ return radioHalCapabilities;
+ } else {
+ // Get radioHalDeviceCapabilities from the radio config
+ sp<RadioConfigResponse> radioConfigRsp = new (std::nothrow) RadioConfigResponse(*this);
+ radioConfig_v1_3->setResponseFunctions(radioConfigRsp, nullptr);
+ serial = GetRandomSerialNumber();
+
+ radioConfig_v1_3->getHalDeviceCapabilities(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ return radioConfigRsp->halDeviceCapabilities;
+ }
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index f610f2a..23378b5 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -18,16 +18,12 @@
#include <android-base/logging.h>
-#include <gtest/gtest.h>
-#include <hidl/GtestPrinter.h>
-#include <hidl/ServiceManagement.h>
-#include <utils/Log.h>
+#include "radio_config_hidl_hal_utils.h"
+
#include <chrono>
#include <condition_variable>
#include <mutex>
-#include <android/hardware/radio/config/1.1/IRadioConfig.h>
-
#include <android/hardware/radio/1.6/IRadio.h>
#include <android/hardware/radio/1.6/IRadioIndication.h>
#include <android/hardware/radio/1.6/IRadioResponse.h>
@@ -42,14 +38,15 @@
using namespace ::android::hardware::radio::V1_2;
using namespace ::android::hardware::radio::V1_1;
using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config::V1_3;
using ::android::sp;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ::android::hardware::radio::config::V1_3::HalDeviceCapabilities;
-#define TIMEOUT_PERIOD 75
#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
@@ -61,7 +58,7 @@
/* Callback class for radio response v1_6 */
class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioResponse {
protected:
- RadioHidlTest_v1_6& parent_v1_6;
+ RadioResponseWaiter& parent_v1_6;
public:
hidl_vec<RadioBandMode> radioBandModes;
@@ -105,7 +102,7 @@
::android::hardware::radio::V1_5::CellIdentity barringCellIdentity;
::android::hardware::hidl_vec<::android::hardware::radio::V1_5::BarringInfo> barringInfos;
- RadioResponse_v1_6(RadioHidlTest_v1_6& parent_v1_6);
+ RadioResponse_v1_6(RadioResponseWaiter& parent_v1_6);
virtual ~RadioResponse_v1_6() = default;
Return<void> getIccCardStatusResponse(
@@ -1079,15 +1076,9 @@
};
// The main test class for Radio HIDL.
-class RadioHidlTest_v1_6 : public ::testing::TestWithParam<std::string> {
+class RadioHidlTest_v1_6 : public ::testing::TestWithParam<std::string>,
+ public RadioResponseWaiter {
protected:
- std::mutex mtx_;
- std::condition_variable cv_;
- int count_;
-
- /* Serial number for radio request */
- int serial;
-
/* Clear Potential Established Calls */
void clearPotentialEstablishedCalls();
@@ -1100,11 +1091,7 @@
public:
virtual void SetUp() override;
- /* Used as a mechanism to inform the test about data/event callback */
- void notify(int receivedSerial);
-
- /* Test code calls this function to wait for response */
- std::cv_status wait();
+ HalDeviceCapabilities getRadioHalCapabilities();
/* radio service handle */
sp<::android::hardware::radio::V1_6::IRadio> radio_v1_6;
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index d9da40a..8034fd2 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -18,7 +18,7 @@
::android::hardware::radio::V1_5::CardStatus cardStatus;
-RadioResponse_v1_6::RadioResponse_v1_6(RadioHidlTest_v1_6& parent) : parent_v1_6(parent) {}
+RadioResponse_v1_6::RadioResponse_v1_6(RadioResponseWaiter& parent) : parent_v1_6(parent) {}
/* 1.0 Apis */
Return<void> RadioResponse_v1_6::getIccCardStatusResponse(
diff --git a/radio/config/1.3/vts/functional/Android.bp b/radio/config/1.3/vts/functional/Android.bp
index aa3522d..20c480f 100644
--- a/radio/config/1.3/vts/functional/Android.bp
+++ b/radio/config/1.3/vts/functional/Android.bp
@@ -46,3 +46,26 @@
"vts",
],
}
+
+cc_library_static {
+ name: "RadioConfigVtsTestResponse",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs : [
+ "radio_config_response.cpp",
+ "radio_config_hidl_hal_test.cpp",
+ ],
+ header_libs: ["radio.util.header@1.0"],
+ static_libs: ["RadioVtsTestUtilBase"],
+ shared_libs: [
+ "android.hardware.radio@1.0",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ "android.hardware.radio.config@1.2",
+ "android.hardware.radio.config@1.3",
+ ],
+}
+
+cc_library_headers {
+ name: "radio.config.util.header@1.3",
+ export_include_dirs: ["."],
+}
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
index de8365a..da61464 100644
--- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_test.cpp
@@ -31,32 +31,3 @@
radioConfig->setResponseFunctions(radioConfigRsp, nullptr);
}
-
-/*
- * Notify that the response message is received.
- */
-void RadioConfigHidlTest::notify(int receivedSerial) {
- std::unique_lock<std::mutex> lock(mtx_);
- if (serial == receivedSerial) {
- count_++;
- cv_.notify_one();
- }
-}
-
-/*
- * Wait till the response message is notified or till TIMEOUT_PERIOD.
- */
-std::cv_status RadioConfigHidlTest::wait() {
- std::unique_lock<std::mutex> lock(mtx_);
-
- std::cv_status status = std::cv_status::no_timeout;
- auto now = std::chrono::system_clock::now();
- while (count_ == 0) {
- status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
- if (status == std::cv_status::timeout) {
- return status;
- }
- }
- count_--;
- return status;
-}
diff --git a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
index 439eb70..895ae08 100644
--- a/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
+++ b/radio/config/1.3/vts/functional/radio_config_hidl_hal_utils.h
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#pragma once
+
#include <android-base/logging.h>
#include <chrono>
@@ -49,7 +51,6 @@
using ::android::hardware::radio::config::V1_3::IRadioConfig;
using ::android::hardware::radio::V1_0::RadioResponseInfo;
-#define TIMEOUT_PERIOD 75
#define RADIO_SERVICE_NAME "slot1"
class RadioConfigHidlTest;
@@ -57,13 +58,14 @@
/* Callback class for radio config response */
class RadioConfigResponse : public IRadioConfigResponse {
protected:
- RadioConfigHidlTest& parent;
+ RadioResponseWaiter& parent;
public:
RadioResponseInfo rspInfo;
PhoneCapability phoneCap;
+ HalDeviceCapabilities halDeviceCapabilities;
- RadioConfigResponse(RadioConfigHidlTest& parent);
+ RadioConfigResponse(RadioResponseWaiter& parent);
virtual ~RadioConfigResponse() = default;
Return<void> getSimSlotsStatusResponse(
@@ -107,26 +109,13 @@
};
// The main test class for Radio config HIDL.
-class RadioConfigHidlTest : public ::testing::TestWithParam<std::string> {
- protected:
- std::mutex mtx_;
- std::condition_variable cv_;
- int count_;
-
+class RadioConfigHidlTest : public ::testing::TestWithParam<std::string>,
+ public RadioResponseWaiter {
public:
virtual void SetUp() override;
- /* Used as a mechanism to inform the test about data/event callback */
- void notify(int receivedSerial);
-
- /* Test code calls this function to wait for response */
- std::cv_status wait();
-
void updateSimCardStatus();
- /* Serial number for radio request */
- int serial;
-
/* radio config service handle */
sp<IRadioConfig> radioConfig;
diff --git a/radio/config/1.3/vts/functional/radio_config_response.cpp b/radio/config/1.3/vts/functional/radio_config_response.cpp
index 2a8b28b..11e3cce 100644
--- a/radio/config/1.3/vts/functional/radio_config_response.cpp
+++ b/radio/config/1.3/vts/functional/radio_config_response.cpp
@@ -18,7 +18,7 @@
// SimSlotStatus slotStatus;
-RadioConfigResponse::RadioConfigResponse(RadioConfigHidlTest& parent) : parent(parent) {}
+RadioConfigResponse::RadioConfigResponse(RadioResponseWaiter& parent) : parent(parent) {}
Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
const ::android::hardware::radio::V1_0::RadioResponseInfo& /* info */,
@@ -65,6 +65,7 @@
Return<void> RadioConfigResponse::getHalDeviceCapabilitiesResponse(
const ::android::hardware::radio::V1_6::RadioResponseInfo& /* info */,
- const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& /* capabilities */) {
+ const ::android::hardware::radio::config::V1_3::HalDeviceCapabilities& capabilities) {
+ halDeviceCapabilities = capabilities;
return Void();
-}
\ No newline at end of file
+}
diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp
index c85fbdf..ae15b6c 100644
--- a/tv/tuner/1.0/default/Android.bp
+++ b/tv/tuner/1.0/default/Android.bp
@@ -33,7 +33,7 @@
"libfmq",
"libhidlbase",
"libhidlmemory",
- "libion",
+ "libdmabufheap",
"liblog",
"libstagefright_foundation",
"libutils",
diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp
index ce748e5..7b50f8c 100644
--- a/tv/tuner/1.0/default/Filter.cpp
+++ b/tv/tuner/1.0/default/Filter.cpp
@@ -16,9 +16,11 @@
#define LOG_TAG "android.hardware.tv.tuner@1.0-Filter"
-#include "Filter.h"
+#include <BufferAllocator/BufferAllocator.h>
#include <utils/Log.h>
+#include "Filter.h"
+
namespace android {
namespace hardware {
namespace tv {
@@ -622,15 +624,15 @@
}
int Filter::createAvIonFd(int size) {
- // Create an ion fd and allocate an av fd mapped to a buffer to it.
- int ion_fd = ion_open();
- if (ion_fd == -1) {
- ALOGE("[Filter] Failed to open ion fd %d", errno);
+ // Create an DMA-BUF fd and allocate an av fd mapped to a buffer to it.
+ auto buffer_allocator = std::make_unique<BufferAllocator>();
+ if (!buffer_allocator) {
+ ALOGE("[Filter] Unable to create BufferAllocator object");
return -1;
}
int av_fd = -1;
- ion_alloc_fd(dup(ion_fd), size, 0 /*align*/, ION_HEAP_SYSTEM_MASK, 0 /*flags*/, &av_fd);
- if (av_fd == -1) {
+ av_fd = buffer_allocator->Alloc("system-uncached", size);
+ if (av_fd < 0) {
ALOGE("[Filter] Failed to create av fd %d", errno);
return -1;
}
diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp
index 86025cf..a612802 100644
--- a/tv/tuner/1.1/default/Android.bp
+++ b/tv/tuner/1.1/default/Android.bp
@@ -31,6 +31,7 @@
"android.hardware.tv.tuner@1.1",
"android.hidl.memory@1.0",
"libcutils",
+ "libdmabufheap",
"libfmq",
"libhidlbase",
"libhidlmemory",
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index aec1fd0..7d609ea 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -16,9 +16,11 @@
#define LOG_TAG "android.hardware.tv.tuner@1.1-Filter"
-#include "Filter.h"
+#include <BufferAllocator/BufferAllocator.h>
#include <utils/Log.h>
+#include "Filter.h"
+
namespace android {
namespace hardware {
namespace tv {
@@ -259,11 +261,14 @@
int av_fd = createAvIonFd(BUFFER_SIZE_16M);
if (av_fd == -1) {
_hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
+ return Void();
}
native_handle_t* nativeHandle = createNativeHandle(av_fd);
if (nativeHandle == NULL) {
+ ::close(av_fd);
_hidl_cb(Result::UNKNOWN_ERROR, NULL, 0);
+ return Void();
}
mSharedAvMemHandle.setTo(nativeHandle, /*shouldOwn=*/true);
::close(av_fd);
@@ -826,15 +831,15 @@
}
int Filter::createAvIonFd(int size) {
- // Create an ion fd and allocate an av fd mapped to a buffer to it.
- int ion_fd = ion_open();
- if (ion_fd == -1) {
- ALOGE("[Filter] Failed to open ion fd %d", errno);
+ // Create an DMA-BUF fd and allocate an av fd mapped to a buffer to it.
+ auto buffer_allocator = std::make_unique<BufferAllocator>();
+ if (!buffer_allocator) {
+ ALOGE("[Filter] Unable to create BufferAllocator object");
return -1;
}
int av_fd = -1;
- ion_alloc_fd(dup(ion_fd), size, 0 /*align*/, ION_HEAP_SYSTEM_MASK, 0 /*flags*/, &av_fd);
- if (av_fd == -1) {
+ av_fd = buffer_allocator->Alloc("system-uncached", size);
+ if (av_fd < 0) {
ALOGE("[Filter] Failed to create av fd %d", errno);
return -1;
}
diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp
index cd0edbe..baa898e 100644
--- a/wifi/1.5/default/hidl_struct_util.cpp
+++ b/wifi/1.5/default/hidl_struct_util.cpp
@@ -1077,6 +1077,17 @@
legacy_stats.iface.ac[legacy_hal::WIFI_AC_VO].contention_num_samples;
hidl_stats->iface.timeSliceDutyCycleInPercent =
legacy_stats.iface.info.time_slicing_duty_cycle_percent;
+ // peer info legacy_stats conversion.
+ std::vector<StaPeerInfo> hidl_peers_info_stats;
+ for (const auto& legacy_peer_info_stats : legacy_stats.peers) {
+ StaPeerInfo hidl_peer_info_stats;
+ if (!convertLegacyPeerInfoStatsToHidl(legacy_peer_info_stats,
+ &hidl_peer_info_stats)) {
+ return false;
+ }
+ hidl_peers_info_stats.push_back(hidl_peer_info_stats);
+ }
+ hidl_stats->iface.peers = hidl_peers_info_stats;
// radio legacy_stats conversion.
std::vector<V1_3::StaLinkLayerRadioStats> hidl_radios_stats;
for (const auto& legacy_radio_stats : legacy_stats.radios) {
@@ -1094,6 +1105,35 @@
return true;
}
+bool convertLegacyPeerInfoStatsToHidl(
+ const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+ StaPeerInfo* hidl_peer_info_stats) {
+ if (!hidl_peer_info_stats) {
+ return false;
+ }
+ *hidl_peer_info_stats = {};
+ hidl_peer_info_stats->staCount =
+ legacy_peer_info_stats.peer_info.bssload.sta_count;
+ hidl_peer_info_stats->chanUtil =
+ legacy_peer_info_stats.peer_info.bssload.chan_util;
+
+ std::vector<StaRateStat> hidlRateStats;
+ for (const auto& legacy_rate_stats : legacy_peer_info_stats.rate_stats) {
+ StaRateStat rateStat;
+ if (!convertLegacyWifiRateInfoToHidl(legacy_rate_stats.rate,
+ &rateStat.rateInfo)) {
+ return false;
+ }
+ rateStat.txMpdu = legacy_rate_stats.tx_mpdu;
+ rateStat.rxMpdu = legacy_rate_stats.rx_mpdu;
+ rateStat.mpduLost = legacy_rate_stats.mpdu_lost;
+ rateStat.retries = legacy_rate_stats.retries;
+ hidlRateStats.push_back(rateStat);
+ }
+ hidl_peer_info_stats->rateStats = hidlRateStats;
+ return true;
+}
+
bool convertLegacyRoamingCapabilitiesToHidl(
const legacy_hal::wifi_roaming_capabilities& legacy_caps,
StaRoamingCapabilities* hidl_caps) {
diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h
index 8b81033..352f213 100644
--- a/wifi/1.5/default/hidl_struct_util.h
+++ b/wifi/1.5/default/hidl_struct_util.h
@@ -212,6 +212,11 @@
bool convertLegacyWifiUsableChannelsToHidl(
const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels);
+bool convertLegacyPeerInfoStatsToHidl(
+ const legacy_hal::WifiPeerInfo& legacy_peer_info_stats,
+ StaPeerInfo* hidl_peer_info_stats);
+bool convertLegacyWifiRateInfoToHidl(const legacy_hal::wifi_rate& legacy_rate,
+ V1_4::WifiRateInfo* hidl_rate);
} // namespace hidl_struct_util
} // namespace implementation
} // namespace V1_5
diff --git a/wifi/1.5/default/service.cpp b/wifi/1.5/default/service.cpp
index 23e2b47..3de49b2 100644
--- a/wifi/1.5/default/service.cpp
+++ b/wifi/1.5/default/service.cpp
@@ -32,7 +32,6 @@
using android::hardware::LazyServiceRegistrar;
using android::hardware::wifi::V1_5::implementation::feature_flags::
WifiFeatureFlags;
-using android::hardware::wifi::V1_5::implementation::iface_util::WifiIfaceUtil;
using android::hardware::wifi::V1_5::implementation::legacy_hal::WifiLegacyHal;
using android::hardware::wifi::V1_5::implementation::legacy_hal::
WifiLegacyHalFactory;
@@ -63,7 +62,6 @@
new android::hardware::wifi::V1_5::implementation::Wifi(
iface_tool, legacy_hal_factory,
std::make_shared<WifiModeController>(),
- std::make_shared<WifiIfaceUtil>(iface_tool),
std::make_shared<WifiFeatureFlags>());
if (kLazyService) {
auto registrar = LazyServiceRegistrar::getInstance();
diff --git a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp
index 6391a6a..e70d7ba 100644
--- a/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp
+++ b/wifi/1.5/default/tests/hidl_struct_util_unit_tests.cpp
@@ -132,6 +132,8 @@
legacy_hal::LinkLayerStats legacy_stats{};
legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
legacy_stats.radios.push_back(legacy_hal::LinkLayerRadioStats{});
+ legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
+ legacy_stats.peers.push_back(legacy_hal::WifiPeerInfo{});
legacy_stats.iface.beacon_rx = rand();
legacy_stats.iface.rssi_mgmt = rand();
legacy_stats.iface.ac[legacy_hal::WIFI_AC_BE].rx_mpdu = rand();
@@ -175,6 +177,7 @@
rand();
legacy_stats.iface.info.time_slicing_duty_cycle_percent = rand();
+ legacy_stats.iface.num_peers = 1;
for (auto& radio : legacy_stats.radios) {
radio.stats.on_time = rand();
@@ -204,6 +207,31 @@
radio.channel_stats.push_back(channel_stat2);
}
+ for (auto& peer : legacy_stats.peers) {
+ peer.peer_info.bssload.sta_count = rand();
+ peer.peer_info.bssload.chan_util = rand();
+ wifi_rate_stat rate_stat1 = {
+ .rate = {3, 1, 2, 5, 0, 0},
+ .tx_mpdu = 0,
+ .rx_mpdu = 1,
+ .mpdu_lost = 2,
+ .retries = 3,
+ .retries_short = 4,
+ .retries_long = 5,
+ };
+ wifi_rate_stat rate_stat2 = {
+ .rate = {2, 2, 1, 6, 0, 1},
+ .tx_mpdu = 6,
+ .rx_mpdu = 7,
+ .mpdu_lost = 8,
+ .retries = 9,
+ .retries_short = 10,
+ .retries_long = 11,
+ };
+ peer.rate_stats.push_back(rate_stat1);
+ peer.rate_stats.push_back(rate_stat2);
+ }
+
V1_5::StaLinkLayerStats converted{};
hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
&converted);
@@ -330,6 +358,37 @@
converted.radios[i].channelStats[k].onTimeInMs);
}
}
+
+ EXPECT_EQ(legacy_stats.peers.size(), converted.iface.peers.size());
+ for (size_t i = 0; i < legacy_stats.peers.size(); i++) {
+ EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.sta_count,
+ converted.iface.peers[i].staCount);
+ EXPECT_EQ(legacy_stats.peers[i].peer_info.bssload.chan_util,
+ converted.iface.peers[i].chanUtil);
+ for (size_t j = 0; j < legacy_stats.peers[i].rate_stats.size(); j++) {
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rate.preamble,
+ (uint32_t)converted.iface.peers[i]
+ .rateStats[j]
+ .rateInfo.preamble);
+ EXPECT_EQ(
+ legacy_stats.peers[i].rate_stats[j].rate.nss,
+ (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.nss);
+ EXPECT_EQ(
+ legacy_stats.peers[i].rate_stats[j].rate.bw,
+ (uint32_t)converted.iface.peers[i].rateStats[j].rateInfo.bw);
+ EXPECT_EQ(
+ legacy_stats.peers[i].rate_stats[j].rate.rateMcsIdx,
+ converted.iface.peers[i].rateStats[j].rateInfo.rateMcsIdx);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].tx_mpdu,
+ converted.iface.peers[i].rateStats[j].txMpdu);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].rx_mpdu,
+ converted.iface.peers[i].rateStats[j].rxMpdu);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].mpdu_lost,
+ converted.iface.peers[i].rateStats[j].mpduLost);
+ EXPECT_EQ(legacy_stats.peers[i].rate_stats[j].retries,
+ converted.iface.peers[i].rateStats[j].retries);
+ }
+ }
}
TEST_F(HidlStructUtilTest, CanConvertLegacyFeaturesToHidl) {
diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp
index fe6e9e2..b101c4a 100644
--- a/wifi/1.5/default/tests/mock_wifi_iface_util.cpp
+++ b/wifi/1.5/default/tests/mock_wifi_iface_util.cpp
@@ -29,8 +29,9 @@
namespace iface_util {
MockWifiIfaceUtil::MockWifiIfaceUtil(
- const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
- : WifiIfaceUtil(iface_tool) {}
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
+ : WifiIfaceUtil(iface_tool, legacy_hal) {}
} // namespace iface_util
} // namespace implementation
} // namespace V1_5
diff --git a/wifi/1.5/default/tests/mock_wifi_iface_util.h b/wifi/1.5/default/tests/mock_wifi_iface_util.h
index a719fec..6d5f59c 100644
--- a/wifi/1.5/default/tests/mock_wifi_iface_util.h
+++ b/wifi/1.5/default/tests/mock_wifi_iface_util.h
@@ -31,7 +31,8 @@
class MockWifiIfaceUtil : public WifiIfaceUtil {
public:
MockWifiIfaceUtil(
- const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
MOCK_METHOD1(getFactoryMacAddress,
std::array<uint8_t, 6>(const std::string&));
MOCK_METHOD2(setMacAddress,
diff --git a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
index 9ab2fd5..826b35f 100644
--- a/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
+++ b/wifi/1.5/default/tests/mock_wifi_legacy_hal.h
@@ -62,6 +62,7 @@
wifi_error(const std::string& ifname,
wifi_interface_type iftype));
MOCK_METHOD1(deleteVirtualInterface, wifi_error(const std::string& ifname));
+ MOCK_METHOD0(waitForDriverReady, wifi_error());
};
} // namespace legacy_hal
} // namespace implementation
diff --git a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
index d99bfbd..0ad6f3e 100644
--- a/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.5/default/tests/wifi_chip_unit_tests.cpp
@@ -276,7 +276,7 @@
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>(iface_tool_)};
+ new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
std::shared_ptr<NiceMock<feature_flags::MockWifiFeatureFlags>>
feature_flags_{new NiceMock<feature_flags::MockWifiFeatureFlags>};
diff --git a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
index d70e42f..8b67bb8 100644
--- a/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
+++ b/wifi/1.5/default/tests/wifi_iface_util_unit_tests.cpp
@@ -22,6 +22,7 @@
#include "wifi_iface_util.h"
#include "mock_interface_tool.h"
+#include "mock_wifi_legacy_hal.h"
using testing::NiceMock;
using testing::Test;
@@ -48,7 +49,11 @@
protected:
std::shared_ptr<NiceMock<wifi_system::MockInterfaceTool>> iface_tool_{
new NiceMock<wifi_system::MockInterfaceTool>};
- WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_);
+ legacy_hal::wifi_hal_fn fake_func_table_;
+ std::shared_ptr<NiceMock<legacy_hal::MockWifiLegacyHal>> legacy_hal_{
+ new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_,
+ fake_func_table_, true)};
+ WifiIfaceUtil* iface_util_ = new WifiIfaceUtil(iface_tool_, legacy_hal_);
};
TEST_F(WifiIfaceUtilTest, GetOrCreateRandomMacAddress) {
diff --git a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
index 52f0c2b..32da55e 100644
--- a/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
+++ b/wifi/1.5/default/tests/wifi_nan_iface_unit_tests.cpp
@@ -122,7 +122,7 @@
new NiceMock<legacy_hal::MockWifiLegacyHal>(iface_tool_,
fake_func_table_, true)};
std::shared_ptr<NiceMock<iface_util::MockWifiIfaceUtil>> iface_util_{
- new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_)};
+ new NiceMock<iface_util::MockWifiIfaceUtil>(iface_tool_, legacy_hal_)};
};
TEST_F(WifiNanIfaceTest, IfacEventHandlers_OnStateToggleOffOn) {
diff --git a/wifi/1.5/default/wifi.cpp b/wifi/1.5/default/wifi.cpp
index 17db51d..da98db8 100644
--- a/wifi/1.5/default/wifi.cpp
+++ b/wifi/1.5/default/wifi.cpp
@@ -37,12 +37,10 @@
const std::shared_ptr<wifi_system::InterfaceTool> iface_tool,
const std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory,
const std::shared_ptr<mode_controller::WifiModeController> mode_controller,
- const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags)
: iface_tool_(iface_tool),
legacy_hal_factory_(legacy_hal_factory),
mode_controller_(mode_controller),
- iface_util_(iface_util),
feature_flags_(feature_flags),
run_state_(RunState::STOPPED) {}
@@ -130,7 +128,8 @@
for (auto& hal : legacy_hals_) {
chips_.push_back(new WifiChip(
chipId, chipId == kPrimaryChipId, hal, mode_controller_,
- iface_util_, feature_flags_, on_subsystem_restart_callback));
+ std::make_shared<iface_util::WifiIfaceUtil>(iface_tool_, hal),
+ feature_flags_, on_subsystem_restart_callback));
chipId++;
}
run_state_ = RunState::STARTED;
diff --git a/wifi/1.5/default/wifi.h b/wifi/1.5/default/wifi.h
index 9f5a1b0..825c0bc 100644
--- a/wifi/1.5/default/wifi.h
+++ b/wifi/1.5/default/wifi.h
@@ -46,7 +46,6 @@
legacy_hal_factory,
const std::shared_ptr<mode_controller::WifiModeController>
mode_controller,
- const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
const std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags);
bool isValid();
@@ -85,7 +84,6 @@
std::shared_ptr<legacy_hal::WifiLegacyHalFactory> legacy_hal_factory_;
std::shared_ptr<mode_controller::WifiModeController> mode_controller_;
std::vector<std::shared_ptr<legacy_hal::WifiLegacyHal>> legacy_hals_;
- std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
std::shared_ptr<feature_flags::WifiFeatureFlags> feature_flags_;
RunState run_state_;
std::vector<sp<WifiChip>> chips_;
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index 0450a7b..0499f45 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -353,7 +353,7 @@
ChipId chip_id, bool is_primary,
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
- const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
const std::function<void(const std::string&)>& handler)
: chip_id_(chip_id),
@@ -986,14 +986,14 @@
}
}
br_ifaces_ap_instances_[br_ifname] = ap_instances;
- if (!iface_util_.lock()->createBridge(br_ifname)) {
+ if (!iface_util_->createBridge(br_ifname)) {
LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
invalidateAndClearBridgedAp(br_ifname);
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
for (auto const& instance : ap_instances) {
// Bind ap instance interface to AP bridge
- if (!iface_util_.lock()->addIfaceToBridge(br_ifname, instance)) {
+ if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
LOG(ERROR) << "Failed add if to Bridge - if_name="
<< instance.c_str();
invalidateAndClearBridgedAp(br_ifname);
@@ -1054,8 +1054,7 @@
if (it.first == ifname) {
for (auto const& iface : it.second) {
if (iface == ifInstanceName) {
- if (!iface_util_.lock()->removeIfaceFromBridge(it.first,
- iface)) {
+ if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
LOG(ERROR)
<< "Failed to remove interface: " << ifInstanceName
<< " from " << ifname;
@@ -1086,7 +1085,7 @@
}
bool is_dedicated_iface = true;
std::string ifname = getPredefinedNanIfaceName();
- if (ifname.empty() || !iface_util_.lock()->ifNameToIndex(ifname)) {
+ if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
// Use the first shared STA iface (wlan0) if a dedicated aware iface is
// not defined.
ifname = getFirstActiveWlanIfaceName();
@@ -1968,10 +1967,10 @@
void WifiChip::invalidateAndClearBridgedApAll() {
for (auto const& it : br_ifaces_ap_instances_) {
for (auto const& iface : it.second) {
- iface_util_.lock()->removeIfaceFromBridge(it.first, iface);
+ iface_util_->removeIfaceFromBridge(it.first, iface);
legacy_hal_.lock()->deleteVirtualInterface(iface);
}
- iface_util_.lock()->deleteBridge(it.first);
+ iface_util_->deleteBridge(it.first);
}
br_ifaces_ap_instances_.clear();
}
@@ -1982,10 +1981,10 @@
for (auto const& it : br_ifaces_ap_instances_) {
if (it.first == br_name) {
for (auto const& iface : it.second) {
- iface_util_.lock()->removeIfaceFromBridge(br_name, iface);
+ iface_util_->removeIfaceFromBridge(br_name, iface);
legacy_hal_.lock()->deleteVirtualInterface(iface);
}
- iface_util_.lock()->deleteBridge(br_name);
+ iface_util_->deleteBridge(br_name);
br_ifaces_ap_instances_.erase(br_name);
break;
}
diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h
index b4ed30e..92d639f 100644
--- a/wifi/1.5/default/wifi_chip.h
+++ b/wifi/1.5/default/wifi_chip.h
@@ -54,7 +54,7 @@
const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
const std::weak_ptr<mode_controller::WifiModeController>
mode_controller,
- const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
+ const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
const std::function<void(const std::string&)>&
subsystemCallbackHandler);
@@ -307,7 +307,7 @@
ChipId chip_id_;
std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
- std::weak_ptr<iface_util::WifiIfaceUtil> iface_util_;
+ std::shared_ptr<iface_util::WifiIfaceUtil> iface_util_;
std::vector<sp<WifiApIface>> ap_ifaces_;
std::vector<sp<WifiNanIface>> nan_ifaces_;
std::vector<sp<WifiP2pIface>> p2p_ifaces_;
diff --git a/wifi/1.5/default/wifi_iface_util.cpp b/wifi/1.5/default/wifi_iface_util.cpp
index 2a0aef8..d1434e3 100644
--- a/wifi/1.5/default/wifi_iface_util.cpp
+++ b/wifi/1.5/default/wifi_iface_util.cpp
@@ -41,8 +41,10 @@
namespace iface_util {
WifiIfaceUtil::WifiIfaceUtil(
- const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
+ const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
: iface_tool_(iface_tool),
+ legacy_hal_(legacy_hal),
random_mac_address_(nullptr),
event_handlers_map_() {}
@@ -59,14 +61,20 @@
return false;
}
#endif
- if (!iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac)) {
- LOG(ERROR) << "SetMacAddress failed.";
- return false;
- }
+ bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
#ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
- LOG(ERROR) << "SetUpState(true) failed.";
- return false;
+ LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
+ // Wait for driver ready and try to set iface UP again
+ if (legacy_hal_.lock()->waitForDriverReady() !=
+ legacy_hal::WIFI_SUCCESS) {
+ LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
+ return false;
+ }
+ if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
+ LOG(ERROR) << "SetUpState(true) failed after retry.";
+ return false;
+ }
}
#endif
IfaceEventHandlers event_handlers = {};
@@ -77,8 +85,12 @@
if (event_handlers.on_state_toggle_off_on != nullptr) {
event_handlers.on_state_toggle_off_on(iface_name);
}
- LOG(DEBUG) << "Successfully SetMacAddress.";
- return true;
+ if (!success) {
+ LOG(ERROR) << "SetMacAddress failed.";
+ } else {
+ LOG(DEBUG) << "SetMacAddress succeeded.";
+ }
+ return success;
}
std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
diff --git a/wifi/1.5/default/wifi_iface_util.h b/wifi/1.5/default/wifi_iface_util.h
index 296d182..b449077 100644
--- a/wifi/1.5/default/wifi_iface_util.h
+++ b/wifi/1.5/default/wifi_iface_util.h
@@ -21,6 +21,8 @@
#include <android/hardware/wifi/1.0/IWifi.h>
+#include "wifi_legacy_hal.h"
+
namespace android {
namespace hardware {
namespace wifi {
@@ -40,7 +42,8 @@
*/
class WifiIfaceUtil {
public:
- WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool);
+ WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
+ const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal);
virtual ~WifiIfaceUtil() = default;
virtual std::array<uint8_t, 6> getFactoryMacAddress(
@@ -73,6 +76,7 @@
std::array<uint8_t, 6> createRandomMacAddress();
std::weak_ptr<wifi_system::InterfaceTool> iface_tool_;
+ std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
std::unique_ptr<std::array<uint8_t, 6>> random_mac_address_;
std::map<std::string, IfaceEventHandlers> event_handlers_map_;
};
diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp
index f5ca753..45ad84b 100644
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal.cpp
@@ -476,6 +476,10 @@
bool WifiLegacyHal::isStarted() { return is_started_; }
+wifi_error WifiLegacyHal::waitForDriverReady() {
+ return global_func_table_.wifi_wait_for_driver_ready();
+}
+
std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(
const std::string& iface_name) {
std::array<char, kMaxVersionStringLength> buffer;
@@ -715,9 +719,29 @@
wifi_iface_stat* iface_stats_ptr, int num_radios,
wifi_radio_stat* radio_stats_ptr) {
wifi_radio_stat* l_radio_stats_ptr;
+ wifi_peer_info* l_peer_info_stats_ptr;
if (iface_stats_ptr != nullptr) {
link_stats_ptr->iface = *iface_stats_ptr;
+ l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
+ for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
+ WifiPeerInfo peer;
+ peer.peer_info = *l_peer_info_stats_ptr;
+ if (l_peer_info_stats_ptr->num_rate > 0) {
+ /* Copy the rate stats */
+ peer.rate_stats.assign(
+ l_peer_info_stats_ptr->rate_stats,
+ l_peer_info_stats_ptr->rate_stats +
+ l_peer_info_stats_ptr->num_rate);
+ }
+ peer.peer_info.num_rate = 0;
+ link_stats_ptr->peers.push_back(peer);
+ l_peer_info_stats_ptr =
+ (wifi_peer_info*)((u8*)l_peer_info_stats_ptr +
+ sizeof(wifi_peer_info) +
+ (sizeof(wifi_rate_stat) *
+ l_peer_info_stats_ptr->num_rate));
+ }
link_stats_ptr->iface.num_peers = 0;
} else {
LOG(ERROR) << "Invalid iface stats in link layer stats";
diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h
index 03ca841..8ebc66a 100644
--- a/wifi/1.5/default/wifi_legacy_hal.h
+++ b/wifi/1.5/default/wifi_legacy_hal.h
@@ -340,9 +340,15 @@
std::vector<wifi_channel_stat> channel_stats;
};
+struct WifiPeerInfo {
+ wifi_peer_info peer_info;
+ std::vector<wifi_rate_stat> rate_stats;
+};
+
struct LinkLayerStats {
wifi_iface_stat iface;
std::vector<LinkLayerRadioStats> radios;
+ std::vector<WifiPeerInfo> peers;
};
#pragma GCC diagnostic pop
@@ -473,6 +479,7 @@
// using a predefined timeout.
virtual wifi_error stop(std::unique_lock<std::recursive_mutex>* lock,
const std::function<void()>& on_complete_callback);
+ virtual wifi_error waitForDriverReady();
// Checks if legacy HAL has successfully started
bool isStarted();
// Wrappers for all the functions in the legacy HAL function table.
diff --git a/wifi/1.5/types.hal b/wifi/1.5/types.hal
index e1c0d32..0543004 100644
--- a/wifi/1.5/types.hal
+++ b/wifi/1.5/types.hal
@@ -26,6 +26,7 @@
import @1.3::StaLinkLayerRadioStats;
import @1.0::WifiChannelInMhz;
import @1.0::WifiChannelWidthInMhz;
+import @1.4::WifiRateInfo;
/**
* Wifi bands defined in 80211 spec.
@@ -162,6 +163,54 @@
};
/**
+ * Per rate statistics. The rate is characterized by the combination of preamble, number of spatial
+ * streams, transmission bandwidth, and modulation and coding scheme (MCS).
+ */
+struct StaRateStat{
+ /**
+ * Wifi rate information: preamble, number of spatial streams, bandwidth, MCS, etc.
+ */
+ WifiRateInfo rateInfo;
+ /**
+ * Number of successfully transmitted data packets (ACK received)
+ */
+ uint32_t txMpdu;
+ /**
+ * Number of received data packets
+ */
+ uint32_t rxMpdu;
+ /**
+ * Number of data packet losses (no ACK)
+ */
+ uint32_t mpduLost;
+ /**
+ * Number of data packet retries
+ */
+ uint32_t retries;
+};
+
+/**
+ * Per peer statistics. The types of peer include the Access Point (AP), the Tunneled Direct Link
+ * Setup (TDLS), the Group Owner (GO), the Neighbor Awareness Networking (NAN), etc.
+ */
+struct StaPeerInfo {
+ /**
+ * Station count: The total number of stations currently associated with the peer.
+ */
+ uint16_t staCount;
+ /**
+ * Channel utilization: The percentage of time (normalized to 255, i.e., x% corresponds to
+ * (int) x * 255 / 100) that the medium is sensed as busy measured by either physical or
+ * virtual carrier sense (CS) mechanism.
+ */
+ uint16_t chanUtil;
+ /**
+ * Per rate statistics
+ */
+ vec<StaRateStat> rateStats;
+};
+
+/**
* Iface statistics for the current connection.
*/
struct StaLinkLayerIfaceStats {
@@ -197,6 +246,11 @@
* WME Voice (VO) Access Category (AC) contention time statistics.
*/
StaLinkLayerIfaceContentionTimeStats wmeVoContentionTimeStats;
+
+ /**
+ * Per peer statistics.
+ */
+ vec<StaPeerInfo> peers;
};
/**
diff --git a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
index 6bed5ab..4f95213 100644
--- a/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.4/ISupplicantStaNetwork.hal
@@ -55,6 +55,24 @@
};
/**
+ * SAE Hash-to-Element mode.
+ */
+ enum SaeH2eMode : uint8_t {
+ /**
+ * Hash-to-Element is disabled, only Hunting & Pecking is allowed.
+ */
+ DISABLED,
+ /**
+ * Both Hash-to-Element and Hunting & Pecking are allowed.
+ */
+ H2E_OPTIONAL,
+ /**
+ * Only Hash-to-Element is allowed.
+ */
+ H2E_MANDATORY,
+ };
+
+ /**
* Set group cipher mask for the network.
*
* @param groupCipherMask value to set.
@@ -154,22 +172,16 @@
generates (SupplicantStatus status);
/**
- * Set whether to enable SAE H2E (Hash-to-Element) only mode.
+ * Set SAE H2E (Hash-to-Element) mode.
*
- * When enabled, only SAE H2E network is allowed; othewise
- * H&P (Hunting and Pecking) and H2E are both allowed.
- * H&P only mode is not supported.
- * If this API is not called before connecting to a SAE
- * network, the behavior is undefined.
- *
- * @param enable true to set, false otherwise.
+ * @param mode SAE H2E supporting mode.
* @return status Status of the operation.
* Possible status codes:
* |SupplicantStatusCode.SUCCESS|,
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
*/
- enableSaeH2eOnlyMode(bool enable) generates (SupplicantStatus status);
+ setSaeH2eMode(SaeH2eMode mode) generates (SupplicantStatus status);
/**
* Set whether to enable SAE PK (Public Key) only mode to enable public AP validation.
diff --git a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
index 0e38c4b..e3fbaf3 100644
--- a/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
+++ b/wifi/supplicant/1.4/vts/functional/supplicant_sta_network_hidl_test.cpp
@@ -42,6 +42,8 @@
using ::android::hardware::wifi::supplicant::V1_4::
ISupplicantStaNetworkCallback;
using ::android::hardware::wifi::V1_0::IWifi;
+using ISupplicantStaNetworkV1_4 =
+ ::android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork;
using SupplicantStatusV1_4 =
::android::hardware::wifi::supplicant::V1_4::SupplicantStatus;
using SupplicantStatusCodeV1_4 =
@@ -110,15 +112,24 @@
}
/*
- * enable SAE H2E (Hash-to-Element) only mode
+ * set SAE H2E (Hash-to-Element) mode
*/
-TEST_P(SupplicantStaNetworkHidlTest, EnableSaeH2eOnlyMode) {
- v1_4->enableSaeH2eOnlyMode(true, [&](const SupplicantStatusV1_4& status) {
- EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
- });
- v1_4->enableSaeH2eOnlyMode(false, [&](const SupplicantStatusV1_4& status) {
- EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS, status.code);
- });
+TEST_P(SupplicantStaNetworkHidlTest, SetSaeH2eMode) {
+ v1_4->setSaeH2eMode(ISupplicantStaNetworkV1_4::SaeH2eMode::DISABLED,
+ [&](const SupplicantStatusV1_4& status) {
+ EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS,
+ status.code);
+ });
+ v1_4->setSaeH2eMode(ISupplicantStaNetworkV1_4::SaeH2eMode::H2E_MANDATORY,
+ [&](const SupplicantStatusV1_4& status) {
+ EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS,
+ status.code);
+ });
+ v1_4->setSaeH2eMode(ISupplicantStaNetworkV1_4::SaeH2eMode::H2E_OPTIONAL,
+ [&](const SupplicantStatusV1_4& status) {
+ EXPECT_EQ(SupplicantStatusCodeV1_4::SUCCESS,
+ status.code);
+ });
}
/*