Merge "Creates OWNERS for evs interface"
diff --git a/audio/common/5.0/types.hal b/audio/common/5.0/types.hal
index ffe4506..8f8a888 100644
--- a/audio/common/5.0/types.hal
+++ b/audio/common/5.0/types.hal
@@ -643,8 +643,10 @@
int32_t device;
} alsa; // used for USB_*
} address;
- string busAddress; // used for BUS
- string rSubmixAddress; // used for REMOTE_SUBMIX
+ /** Arbitrary BUS device unique address. Should not be interpreted by the framework. */
+ string busAddress;
+ /** Arbitrary REMOTE_SUBMIX device unique address. Should not be interpreted by the HAL. */
+ string rSubmixAddress;
};
/**
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index a22cc1c..7f8b6a0 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -142,14 +142,13 @@
android::DeviceVector availableOutputDevices;
android::DeviceVector availableInputDevices;
sp<android::DeviceDescriptor> defaultOutputDevice;
- android::VolumeCurvesCollection volumes;
};
class PolicyConfig : private PolicyConfigData, public AudioPolicyConfig {
public:
PolicyConfig()
: AudioPolicyConfig(hwModules, availableOutputDevices, availableInputDevices,
- defaultOutputDevice, &volumes) {
+ defaultOutputDevice) {
for (const char* location : kConfigLocations) {
std::string path = std::string(location) + '/' + kConfigFileName;
if (access(path.c_str(), F_OK) == 0) {
diff --git a/audio/effect/5.0/xml/api/current.txt b/audio/effect/5.0/xml/api/current.txt
index 473bb10..ef467c9 100644
--- a/audio/effect/5.0/xml/api/current.txt
+++ b/audio/effect/5.0/xml/api/current.txt
@@ -1,27 +1,27 @@
// Signature format: 2.0
package audio.effects.V5_0 {
- public class Audioeffectsconf {
- ctor public Audioeffectsconf();
+ public class AudioEffectsConf {
+ ctor public AudioEffectsConf();
method public audio.effects.V5_0.EffectsType getEffects();
method public audio.effects.V5_0.LibrariesType getLibraries();
- method public audio.effects.V5_0.Audioeffectsconf.Postprocess getPostprocess();
- method public audio.effects.V5_0.Audioeffectsconf.Preprocess getPreprocess();
+ method public audio.effects.V5_0.AudioEffectsConf.Postprocess getPostprocess();
+ method public audio.effects.V5_0.AudioEffectsConf.Preprocess getPreprocess();
method public audio.effects.V5_0.VersionType getVersion();
method public void setEffects(audio.effects.V5_0.EffectsType);
method public void setLibraries(audio.effects.V5_0.LibrariesType);
- method public void setPostprocess(audio.effects.V5_0.Audioeffectsconf.Postprocess);
- method public void setPreprocess(audio.effects.V5_0.Audioeffectsconf.Preprocess);
+ method public void setPostprocess(audio.effects.V5_0.AudioEffectsConf.Postprocess);
+ method public void setPreprocess(audio.effects.V5_0.AudioEffectsConf.Preprocess);
method public void setVersion(audio.effects.V5_0.VersionType);
}
- public static class Audioeffectsconf.Postprocess {
- ctor public Audioeffectsconf.Postprocess();
+ public static class AudioEffectsConf.Postprocess {
+ ctor public AudioEffectsConf.Postprocess();
method public java.util.List<audio.effects.V5_0.StreamPostprocessType> getStream();
}
- public static class Audioeffectsconf.Preprocess {
- ctor public Audioeffectsconf.Preprocess();
+ public static class AudioEffectsConf.Preprocess {
+ ctor public AudioEffectsConf.Preprocess();
method public java.util.List<audio.effects.V5_0.StreamPreprocessType> getStream();
}
@@ -123,7 +123,7 @@
public class XmlParser {
ctor public XmlParser();
- method public static audio.effects.V5_0.Audioeffectsconf read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static audio.effects.V5_0.AudioEffectsConf read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
}
diff --git a/automotive/evs/1.0/IEvsEnumerator.hal b/automotive/evs/1.0/IEvsEnumerator.hal
index e1193d0..ee51e7e 100644
--- a/automotive/evs/1.0/IEvsEnumerator.hal
+++ b/automotive/evs/1.0/IEvsEnumerator.hal
@@ -57,7 +57,8 @@
*
* There can be at most one EVS display object for the system and this function
* requests access to it. If the EVS display is not available or is already in use,
- * a null pointer is returned.
+ * the old instance shall be closed and give the new caller exclusive
+ * access.
* When done using the display, the caller may release it by calling closeDisplay().
* TODO(b/36122635) Reliance on the sp<> going out of scope is not recommended because the
* resources may not be released right away due to asynchronos behavior in the hardware binder.
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index c937834..e00b3f8 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -128,7 +128,9 @@
}
camera3_stream_configuration_t stream_list{};
- stream_list.stream_configuration_counter = streamConfigCounter;
+ // Block reading mStreamConfigCounter until configureStream returns
+ Mutex::Autolock _sccl(mStreamConfigCounterLock);
+ mStreamConfigCounter = streamConfigCounter;
hidl_vec<camera3_stream_t*> streams;
stream_list.session_parameters = paramBuffer;
if (!preProcessConfigurationLocked_3_4(requestedConfiguration, &stream_list, &streams)) {
diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
index 00500b1..1db7b41 100644
--- a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
+++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
@@ -123,6 +123,10 @@
// Physical camera ids for the logical multi-camera. Empty if this
// is not a logical multi-camera.
std::unordered_set<std::string> mPhysicalCameraIds;
+
+ Mutex mStreamConfigCounterLock;
+ uint32_t mStreamConfigCounter = 1;
+
private:
struct TrampolineSessionInterface_3_4 : public ICameraDeviceSession {
diff --git a/camera/device/3.5/default/CameraDeviceSession.cpp b/camera/device/3.5/default/CameraDeviceSession.cpp
index d9c6eef..bea1be6 100644
--- a/camera/device/3.5/default/CameraDeviceSession.cpp
+++ b/camera/device/3.5/default/CameraDeviceSession.cpp
@@ -72,6 +72,22 @@
Return<void> CameraDeviceSession::signalStreamFlush(
const hidl_vec<int32_t>& streamIds, uint32_t streamConfigCounter) {
+ if (mDevice->ops->signal_stream_flush == nullptr) {
+ return Void();
+ }
+
+ uint32_t currentCounter = 0;
+ {
+ Mutex::Autolock _l(mStreamConfigCounterLock);
+ currentCounter = mStreamConfigCounter;
+ }
+
+ if (streamConfigCounter < currentCounter) {
+ ALOGV("%s: streamConfigCounter %d is stale (current %d), skipping signal_stream_flush call",
+ __FUNCTION__, streamConfigCounter, mStreamConfigCounter);
+ return Void();
+ }
+
std::vector<camera3_stream_t*> streams(streamIds.size());
{
Mutex::Autolock _l(mInflightLock);
@@ -84,10 +100,8 @@
streams[i] = &mStreamMap[id];
}
}
- if (mDevice->ops->signal_stream_flush != nullptr) {
- mDevice->ops->signal_stream_flush(mDevice,
- streamConfigCounter, streams.size(), streams.data());
- }
+
+ mDevice->ops->signal_stream_flush(mDevice, streams.size(), streams.data());
return Void();
}
@@ -186,111 +200,118 @@
}
ATRACE_END();
- if (status == BufferRequestStatus::OK || status == BufferRequestStatus::FAILED_PARTIAL) {
- if (bufRets.size() != num_buffer_reqs) {
- ALOGE("%s: expect %d buffer requests returned, only got %zu",
- __FUNCTION__, num_buffer_reqs, bufRets.size());
- return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
- }
-
- for (size_t i = 0; i < num_buffer_reqs; i++) {
- // maybe we can query all streams in one call to avoid frequent locking device here?
- Camera3Stream* stream = getStreamPointer(bufRets[i].streamId);
- if (stream == nullptr) {
- ALOGE("%s: unknown streamId %d", __FUNCTION__, bufRets[i].streamId);
- return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
- }
- returned_buf_reqs[i].stream = stream;
- }
-
- std::vector<int> importedFences;
- std::vector<std::pair<buffer_handle_t, int>> importedBuffers;
- for (size_t i = 0; i < num_buffer_reqs; i++) {
- int streamId = bufRets[i].streamId;
- switch (bufRets[i].val.getDiscriminator()) {
- case StreamBuffersVal::hidl_discriminator::error:
- returned_buf_reqs[i].num_output_buffers = 0;
- switch (bufRets[i].val.error()) {
- case StreamBufferRequestError::NO_BUFFER_AVAILABLE:
- returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE;
- break;
- case StreamBufferRequestError::MAX_BUFFER_EXCEEDED:
- returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED;
- break;
- case StreamBufferRequestError::STREAM_DISCONNECTED:
- returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED;
- break;
- case StreamBufferRequestError::UNKNOWN_ERROR:
- returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR;
- break;
- default:
- ALOGE("%s: Unknown StreamBufferRequestError %d",
- __FUNCTION__, bufRets[i].val.error());
- cleanupInflightBufferFences(importedFences, importedBuffers);
- return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
- }
- break;
- case StreamBuffersVal::hidl_discriminator::buffers: {
- const hidl_vec<StreamBuffer>& hBufs = bufRets[i].val.buffers();
- camera3_stream_buffer_t* outBufs = returned_buf_reqs[i].output_buffers;
- for (size_t b = 0; b < hBufs.size(); b++) {
- const StreamBuffer& hBuf = hBufs[b];
- camera3_stream_buffer_t& outBuf = outBufs[b];
- // maybe add importBuffers API to avoid frequent locking device?
- Status s = importBuffer(streamId,
- hBuf.bufferId, hBuf.buffer.getNativeHandle(),
- /*out*/&(outBuf.buffer),
- /*allowEmptyBuf*/false);
- if (s != Status::OK) {
- ALOGE("%s: import stream %d bufferId %" PRIu64 " failed!",
- __FUNCTION__, streamId, hBuf.bufferId);
- cleanupInflightBufferFences(importedFences, importedBuffers);
- // Buffer import should never fail - restart HAL since something is very
- // wrong.
- assert(false);
- return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
- }
-
- pushBufferId(*(outBuf.buffer), hBuf.bufferId, streamId);
- importedBuffers.push_back(std::make_pair(*(outBuf.buffer), streamId));
-
- if (!sHandleImporter.importFence(
- hBuf.acquireFence,
- outBuf.acquire_fence)) {
- ALOGE("%s: stream %d bufferId %" PRIu64 "acquire fence is invalid",
- __FUNCTION__, streamId, hBuf.bufferId);
- cleanupInflightBufferFences(importedFences, importedBuffers);
- return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
- }
- importedFences.push_back(outBuf.acquire_fence);
- outBuf.stream = returned_buf_reqs[i].stream;
- outBuf.status = CAMERA3_BUFFER_STATUS_OK;
- outBuf.release_fence = -1;
- }
- returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_OK;
- } break;
- default:
- ALOGE("%s: unknown StreamBuffersVal discrimator!", __FUNCTION__);
- cleanupInflightBufferFences(importedFences, importedBuffers);
- return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
- }
- }
-
- *num_returned_buf_reqs = num_buffer_reqs;
-
- return (status == BufferRequestStatus::OK) ?
- CAMERA3_BUF_REQ_OK : CAMERA3_BUF_REQ_FAILED_PARTIAL;
- }
-
switch (status) {
case BufferRequestStatus::FAILED_CONFIGURING:
return CAMERA3_BUF_REQ_FAILED_CONFIGURING;
case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS:
return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS;
- case BufferRequestStatus::FAILED_UNKNOWN:
default:
- return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ break; // Other status Handled by following code
}
+
+ if (status != BufferRequestStatus::OK && status != BufferRequestStatus::FAILED_PARTIAL &&
+ status != BufferRequestStatus::FAILED_UNKNOWN) {
+ ALOGE("%s: unknown buffer request error code %d", __FUNCTION__, status);
+ return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ }
+
+ // Only OK, FAILED_PARTIAL and FAILED_UNKNOWN reaches here
+ if (bufRets.size() != num_buffer_reqs) {
+ ALOGE("%s: expect %d buffer requests returned, only got %zu",
+ __FUNCTION__, num_buffer_reqs, bufRets.size());
+ return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ }
+
+ *num_returned_buf_reqs = num_buffer_reqs;
+ for (size_t i = 0; i < num_buffer_reqs; i++) {
+ // maybe we can query all streams in one call to avoid frequent locking device here?
+ Camera3Stream* stream = getStreamPointer(bufRets[i].streamId);
+ if (stream == nullptr) {
+ ALOGE("%s: unknown streamId %d", __FUNCTION__, bufRets[i].streamId);
+ return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ }
+ returned_buf_reqs[i].stream = stream;
+ }
+
+ // Handle failed streams
+ for (size_t i = 0; i < num_buffer_reqs; i++) {
+ if (bufRets[i].val.getDiscriminator() == StreamBuffersVal::hidl_discriminator::error) {
+ returned_buf_reqs[i].num_output_buffers = 0;
+ switch (bufRets[i].val.error()) {
+ case StreamBufferRequestError::NO_BUFFER_AVAILABLE:
+ returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE;
+ break;
+ case StreamBufferRequestError::MAX_BUFFER_EXCEEDED:
+ returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED;
+ break;
+ case StreamBufferRequestError::STREAM_DISCONNECTED:
+ returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED;
+ break;
+ case StreamBufferRequestError::UNKNOWN_ERROR:
+ returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR;
+ break;
+ default:
+ ALOGE("%s: Unknown StreamBufferRequestError %d",
+ __FUNCTION__, bufRets[i].val.error());
+ return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ }
+ }
+ }
+
+ if (status == BufferRequestStatus::FAILED_UNKNOWN) {
+ return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ }
+
+ // Only BufferRequestStatus::OK and BufferRequestStatus::FAILED_PARTIAL reaches here
+ std::vector<int> importedFences;
+ std::vector<std::pair<buffer_handle_t, int>> importedBuffers;
+ for (size_t i = 0; i < num_buffer_reqs; i++) {
+ if (bufRets[i].val.getDiscriminator() !=
+ StreamBuffersVal::hidl_discriminator::buffers) {
+ continue;
+ }
+ int streamId = bufRets[i].streamId;
+ const hidl_vec<StreamBuffer>& hBufs = bufRets[i].val.buffers();
+ camera3_stream_buffer_t* outBufs = returned_buf_reqs[i].output_buffers;
+ for (size_t b = 0; b < hBufs.size(); b++) {
+ const StreamBuffer& hBuf = hBufs[b];
+ camera3_stream_buffer_t& outBuf = outBufs[b];
+ // maybe add importBuffers API to avoid frequent locking device?
+ Status s = importBuffer(streamId,
+ hBuf.bufferId, hBuf.buffer.getNativeHandle(),
+ /*out*/&(outBuf.buffer),
+ /*allowEmptyBuf*/false);
+ if (s != Status::OK) {
+ ALOGE("%s: import stream %d bufferId %" PRIu64 " failed!",
+ __FUNCTION__, streamId, hBuf.bufferId);
+ cleanupInflightBufferFences(importedFences, importedBuffers);
+ // Buffer import should never fail - restart HAL since something is very
+ // wrong.
+ assert(false);
+ return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ }
+
+ pushBufferId(*(outBuf.buffer), hBuf.bufferId, streamId);
+ importedBuffers.push_back(std::make_pair(*(outBuf.buffer), streamId));
+
+ if (!sHandleImporter.importFence(
+ hBuf.acquireFence,
+ outBuf.acquire_fence)) {
+ ALOGE("%s: stream %d bufferId %" PRIu64 "acquire fence is invalid",
+ __FUNCTION__, streamId, hBuf.bufferId);
+ cleanupInflightBufferFences(importedFences, importedBuffers);
+ return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
+ }
+ importedFences.push_back(outBuf.acquire_fence);
+ outBuf.stream = returned_buf_reqs[i].stream;
+ outBuf.status = CAMERA3_BUFFER_STATUS_OK;
+ outBuf.release_fence = -1;
+ }
+ returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_OK;
+ }
+
+ return (status == BufferRequestStatus::OK) ?
+ CAMERA3_BUF_REQ_OK : CAMERA3_BUF_REQ_FAILED_PARTIAL;
}
void CameraDeviceSession::returnStreamBuffers(
diff --git a/camera/device/3.5/types.hal b/camera/device/3.5/types.hal
index 7cb9727..e3c2350 100644
--- a/camera/device/3.5/types.hal
+++ b/camera/device/3.5/types.hal
@@ -120,7 +120,9 @@
/**
* Method call failed for all streams and no buffers are returned at all.
- * Failure due to unknown reason.
+ * Failure due to unknown reason, or all streams has individual failing
+ * reason. For the latter case, check per stream status for each returned
+ * StreamBufferRet.
*/
FAILED_UNKNOWN = 4,
};
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index b9828fb..244d7a0 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -113,7 +113,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.camera.provider</name>
- <version>2.5</version>
+ <version>2.4-5</version>
<interface>
<name>ICameraProvider</name>
<regex-instance>[^/]+/[0-9]+</regex-instance>
@@ -121,7 +121,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.cas</name>
- <version>1.0-1</version>
+ <version>1.1</version>
<interface>
<name>IMediaCasService</name>
<instance>default</instance>
diff --git a/current.txt b/current.txt
index 796e0ff..ce8e05f 100644
--- a/current.txt
+++ b/current.txt
@@ -418,7 +418,7 @@
9471b12b1c255bb530695720bc4174bd74987b75b1f820854af8944bc8c215c9 android.hardware.audio@5.0::IStreamOut
1b0500367ed2b32a841667ac3200edf3d3a164e8004aca445ff1b085ac831e93 android.hardware.audio@5.0::IStreamOutCallback
83e365479cc77d8717c155e1787ee668cd2ae4c557b467cf75b8e7cd53697ad8 android.hardware.audio@5.0::types
-edda213e520f387a3e367834b0772978b308a0f59b54479990aa9411aee9bcc4 android.hardware.audio.common@5.0::types
+894af04bebfe7da5b6791eefeb6eb3627da63d5efea735f16876d11d8ca4f61d android.hardware.audio.common@5.0::types
f269297866765b95ddd1825676cc8a772f0c7c9863286df596fc302781a42ff5 android.hardware.audio.effect@5.0::IAcousticEchoCancelerEffect
fa187b602d8939644ef708ed7627f2e3deac97899a4bda1de07f2ff126abe243 android.hardware.audio.effect@5.0::IAutomaticGainControlEffect
e1bf864ccb8458c0da1dcc74a2e748b1dca8ac360df590591cf82d98292d7981 android.hardware.audio.effect@5.0::IBassBoostEffect
@@ -444,7 +444,7 @@
09ab9b24994429d9bb32a3fb420b6f6be3e47eb655139a2c08c4e80d3f33ff95 android.hardware.camera.device@3.5::ICameraDevice
06237de53c42890029e3f8fe7d1480d078469c0d07608e51c37b4d485d342992 android.hardware.camera.device@3.5::ICameraDeviceCallback
08c68b196e2fc4e5ba67ba0d0917bde828a87cbe2cffec19d04733972da9eb49 android.hardware.camera.device@3.5::ICameraDeviceSession
-d487ab209944df8987eeca70cf09307fc1429cedf64b0ea9e77c61d8caeb8c15 android.hardware.camera.device@3.5::types
+acaba39216973e58949f50978762bcda1c29f5f7e0bca3e08db21f0767356130 android.hardware.camera.device@3.5::types
74ec7732fdacb22292c907b49f8f933510851ea1b3ed195c4dcdff35a20387f5 android.hardware.camera.metadata@3.4::types
0fb39a7809ad1c52b3efbbed5ef4749b06c2a4f1f19cdc3efa2e3d9b28f1205c android.hardware.camera.provider@2.5::ICameraProvider
f5777403d65135a5407723671bc7a864cdca83aea13ee3ce2894b95e6588ca3a android.hardware.camera.provider@2.5::types
@@ -464,12 +464,12 @@
7f460e795f5d1ed5e378935f98c6db4d39497de988aef1b4c2a4a07a6c400392 android.hardware.gnss@2.0::IAGnss
2e5ad983734069e84a760004b32da0d09e4170c05380abe27e6eb80e4aa70d5a android.hardware.gnss@2.0::IAGnssCallback
1f4ac068a88a72360280d94a7f6fd7c63813c1eea4891a0eb01394d3e7e775f2 android.hardware.gnss@2.0::IAGnssRil
-52e56490d35b4214d68c44f013e22bdf681fd6f8e5947c643dbb8453f9a03dcd android.hardware.gnss@2.0::IGnss
-0676e99eda39ff32f6891bcb56ea27df17007c439b9f900aa9a3919776920c23 android.hardware.gnss@2.0::IGnssCallback
+6e2f9a44375a0ae0b49ca7d711cb88945189d398535078408269e1e85889061d android.hardware.gnss@2.0::IGnss
+54d253b10c7da2a4a708d11acda3118b283df1540bc10323a5a3773c94cc8e71 android.hardware.gnss@2.0::IGnssCallback
ecc966c68bddbd95c8dae782b84204cf01c75734675e8769963f3b5106ec128b android.hardware.gnss@2.0::IGnssConfiguration
c67759f5d6387d273b66729180d03690e827f0b6b8d4e13ce2ff42d31b224065 android.hardware.gnss@2.0::IGnssMeasurement
-08615296d42451856f82c4953b45c4257d0a7b935fd98557c2ee2812c79fe0c3 android.hardware.gnss@2.0::IGnssMeasurementCallback
-141269652bcf30a7557edc4cd4311aa3e2ac67a252a7e8d3959b956d35793344 android.hardware.gnss@2.0::types
+089338944c45f66f25ba4ee958c161c42fefeb73ec60e4451f3535a1b3fd10c7 android.hardware.gnss@2.0::IGnssMeasurementCallback
+9e66234e65bcde75733d75d8b5d5cc094c2a5e14b074a25cd3f9ad141dc56f60 android.hardware.gnss@2.0::types
50623a69a88b1c8a05738e4af7d5f78e905f415ccb0e84c99d0a71ea182e9393 android.hardware.gnss.measurement_corrections@1.0::IMeasurementCorrections
6ef12cd95df73f8f80c25eb035d98ca4594f9cee571fdabea838a0b6016dd908 android.hardware.gnss.measurement_corrections@1.0::types
0d278956d7fc6fdf9ca9c42962ff2d73967bbb1c9f0b3e0b58d71b7095c286bc android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControl
@@ -487,7 +487,7 @@
dd1ec219f5d2e2b33c6c0bcb92e63bbedb36f7c716413462848f6b6ae74fc864 android.hardware.health.storage@1.0::IStorage
2b4a14661e6a38617b7dd0c6ebb66a56a90e564674ac7697a14cb8a0cab92b2f android.hardware.health.storage@1.0::types
30006fde4cb1f255f2530208728bff692100411b20af5b66fa31a9196d51f00b android.hardware.input.classifier@1.0::IInputClassifier
-97d8757bb05eb23d6a218bda374e095dfbb064c47714e2f859963c11f433e822 android.hardware.input.common@1.0::types
+0300c7667030da36c3de585f176ce18ff4b0d2615446d4930f331097378c06ef android.hardware.input.common@1.0::types
24ae089981d58bc4cc74d75a6055bf357338ae6744ce1b467c5b4a9c470aba6d android.hardware.media.bufferpool@2.0::IAccessor
897f45ee7db24ef227dea83ca3e4de72d53ff6bb7adc7983c90a650a1a6ff576 android.hardware.media.bufferpool@2.0::IClientManager
aee53b2865b4f7939fb3df6fae758d9750c14f93dd454b479fc74aa7978fda4f android.hardware.media.bufferpool@2.0::IConnection
@@ -508,16 +508,16 @@
92714960d1a53fc2ec557302b41c7cc93d2636d8364a44bd0f85be0c92927ff8 android.hardware.neuralnetworks@1.2::IExecutionCallback
83885d366f22ada42c00d8854f0b7e7ba4cf73ddf80bb0d8e168ce132cec57ea android.hardware.neuralnetworks@1.2::IPreparedModel
e1c734d1545e1a4ae749ff1dd9704a8e594c59aea7c8363159dc258e93e0df3b android.hardware.neuralnetworks@1.2::IPreparedModelCallback
-313b341f1f6196a48cf304eaf067f67510c1ebc04df8c7cd536db5611df5c5c2 android.hardware.neuralnetworks@1.2::types
+769f8650631eef7a3ceedc8cf130f4b99eb52fe698a11609d55de32985a3dddf android.hardware.neuralnetworks@1.2::types
cf7a4ba516a638f9b82a249c91fb603042c2d9ca43fd5aad9cf6c0401ed2a5d7 android.hardware.nfc@1.2::INfc
abf98c2ae08bf765db54edc8068e36d52eb558cff6706b6fd7c18c65a1f3fc18 android.hardware.nfc@1.2::types
4cb252dc6372a874aef666b92a6e9529915aa187521a700f0789065c3c702ead android.hardware.power.stats@1.0::IPowerStats
-69c394e7fe3236beb6231a709865e8a882aac7a612c8dddf64f5a66028fa2c68 android.hardware.power.stats@1.0::types
+2043037d5baaff604805757d06979aa861013a1e87430db745265339a8681f79 android.hardware.power.stats@1.0::types
11620ce020b6ef8f5b63eb2a39390de4a2fbbccc0a5e558b5b1a0e22e33f63cf android.hardware.radio@1.3::IRadio
e9d0f11a52715f5a29d89e2d8e2e21db1e16a43174af6b9d51a62d705cda1455 android.hardware.radio@1.3::IRadioIndication
d233f0da44f55fdef0a95db5229231412787bb67695cd1ea197ce89a3c2908b9 android.hardware.radio@1.3::IRadioResponse
750a363c8cec70baa1aac19e275c15233c5898e93c6bb5155fa2ca7f365490dc android.hardware.radio@1.3::types
-b2dfa12706a1633c387f2ae0a911021b98fe0ecacf5e14a3776053a27d606050 android.hardware.radio@1.4::IRadio
+4ac73ec1e4cfa535209e5e22547f08beb20ef812b4a29d0824780f52cbe2324d android.hardware.radio@1.4::IRadio
33d9e6895cca98aa56296bb01720d18b8acd0e4de4960beb712e63ad147438a5 android.hardware.radio@1.4::IRadioIndication
0cc0dd87c634aad36d7df22b2832839ef7ded71909dbcde11cfdd69dc0dc52b8 android.hardware.radio@1.4::IRadioResponse
29d34232cc3974626b08759e039fe788bded7695cdeb098458e3e11e4c7d3603 android.hardware.radio@1.4::types
@@ -534,7 +534,7 @@
ae5faa38538a9f50eb71eb7f9b998271124d2c64b761cb11c4d820c7732b4ddc android.hardware.sensors@2.0::ISensorsCallback
3a98242a57d0820dacaca0f7db52bec433eae1f21c498763c6f1ece611c3967b android.hardware.sensors@2.0::types
ce4b98211959449361146d4b1e5554dc841ceb4d4577154d7b2fb6d1eb504f76 android.hardware.soundtrigger@2.2::ISoundTriggerHw
-5cc81d517c5f3fef12e719b0f5683c7c99e3e8895fcb80e6f6653b454f463320 android.hardware.thermal@2.0::IThermal
+bd88b48639cae30982021024e22371076c76faa8466e38ca598529452b618eae android.hardware.thermal@2.0::IThermal
cc4d2ef36da776c475ad054f0f3416d8a8865def9d9e2129f10074b28e36d203 android.hardware.thermal@2.0::IThermalChangedCallback
b47f90302595874dfddb19bd05a054727bf18b3a930bc810ea14957b859ae8bf android.hardware.thermal@2.0::types
61bc302e7c974c59b25898c585c6e9685e8a81021b1bed3eedf5224198f2785a android.hardware.usb@1.2::IUsb
@@ -550,6 +550,6 @@
067b22efc50529a88d650fe7400603429d1164a47ee96a17476fdb0aadd6b4d3 android.hardware.wifi.supplicant@1.2::ISupplicant
120211371fdd29fb134837071d432a302d7b60e9b95af611dd8dde86bd1f77ee android.hardware.wifi.supplicant@1.2::ISupplicantP2pIface
7efe2b057e9f9387b3500e67af97942aa7c8008e6ee7d8dcaae4107fda84016b android.hardware.wifi.supplicant@1.2::ISupplicantStaIface
-eb569df2e80f8e276a91a510c75e83fbf957ff1988691726418d44c2be01c520 android.hardware.wifi.supplicant@1.2::ISupplicantStaIfaceCallback
+09e08b5d12b109562ecdd8882532fd1f2c4639588e07769d5c7396b7c5b9f34f android.hardware.wifi.supplicant@1.2::ISupplicantStaIfaceCallback
efbb061c969fa9553d243da6ee23b83fe5d4aa663a7b8896adc52e2b015bc2f3 android.hardware.wifi.supplicant@1.2::ISupplicantStaNetwork
-4851210036650ce6c86498c012db5ff618afce8508a2b06a0e9b902d1840f4bd android.hardware.wifi.supplicant@1.2::types
+cfa81f229b69f9011c58f48264fcb552447430fe68610eac514e811e65bc306a android.hardware.wifi.supplicant@1.2::types
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 44aed2b..8c3aac4 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -18,4 +18,7 @@
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
],
+ static_libs: [
+ "android.hardware.gnss@common-default-lib",
+ ],
}
diff --git a/gnss/1.1/default/Gnss.cpp b/gnss/1.1/default/Gnss.cpp
index bbf1cd3..4abe707 100644
--- a/gnss/1.1/default/Gnss.cpp
+++ b/gnss/1.1/default/Gnss.cpp
@@ -4,9 +4,9 @@
#include <log/log.h>
#include "Gnss.h"
-#include "GnssConstants.h"
#include "GnssDebug.h"
#include "GnssMeasurement.h"
+#include "Utils.h"
namespace android {
namespace hardware {
@@ -14,6 +14,7 @@
namespace V1_1 {
namespace implementation {
+using ::android::hardware::gnss::common::Utils;
using GnssSvFlags = IGnssCallback::GnssSvFlags;
const uint32_t MIN_INTERVAL_MILLIS = 100;
@@ -43,7 +44,7 @@
auto svStatus = this->getMockSvStatus();
this->reportSvStatus(svStatus);
- auto location = this->getMockLocation();
+ auto location = Utils::getMockLocation();
this->reportLocation(location);
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
@@ -193,44 +194,17 @@
return true;
}
-Return<GnssLocation> Gnss::getMockLocation() const {
- GnssLocation location = {.gnssLocationFlags = 0xFF,
- .latitudeDegrees = kMockLatitudeDegrees,
- .longitudeDegrees = kMockLongitudeDegrees,
- .altitudeMeters = kMockAltitudeMeters,
- .speedMetersPerSec = kMockSpeedMetersPerSec,
- .bearingDegrees = kMockBearingDegrees,
- .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
- .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
- .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
- .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
- .timestamp = kMockTimestamp};
- return location;
-}
-
-Return<GnssSvInfo> Gnss::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
- float elevationDegrees, float azimuthDegrees) const {
- GnssSvInfo svInfo = {.svid = svid,
- .constellation = type,
- .cN0Dbhz = cN0DbHz,
- .elevationDegrees = elevationDegrees,
- .azimuthDegrees = azimuthDegrees,
- .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
- GnssSvFlags::HAS_ALMANAC_DATA};
- return svInfo;
-}
-
Return<GnssSvStatus> Gnss::getMockSvStatus() const {
std::unique_lock<std::recursive_mutex> lock(mGnssConfiguration->getMutex());
GnssSvInfo mockGnssSvInfoList[] = {
- getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
- getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
- getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
- getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
- getSvInfo(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
- getSvInfo(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
- getSvInfo(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
- getSvInfo(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
+ Utils::getSvInfo(3, GnssConstellationType::GPS, 32.5, 59.1, 166.5),
+ Utils::getSvInfo(5, GnssConstellationType::GPS, 27.0, 29.0, 56.5),
+ Utils::getSvInfo(17, GnssConstellationType::GPS, 30.5, 71.0, 77.0),
+ Utils::getSvInfo(26, GnssConstellationType::GPS, 24.1, 28.0, 253.0),
+ Utils::getSvInfo(5, GnssConstellationType::GLONASS, 20.5, 11.5, 116.0),
+ Utils::getSvInfo(17, GnssConstellationType::GLONASS, 21.5, 28.5, 186.0),
+ Utils::getSvInfo(18, GnssConstellationType::GLONASS, 28.3, 38.8, 69.0),
+ Utils::getSvInfo(10, GnssConstellationType::GLONASS, 25.0, 66.0, 247.0)};
GnssSvStatus svStatus = {.numSvs = sizeof(mockGnssSvInfoList) / sizeof(GnssSvInfo)};
for (uint32_t i = 0; i < svStatus.numSvs; i++) {
diff --git a/gnss/1.1/default/Gnss.h b/gnss/1.1/default/Gnss.h
index 99af34c..21b66a2 100644
--- a/gnss/1.1/default/Gnss.h
+++ b/gnss/1.1/default/Gnss.h
@@ -84,10 +84,7 @@
// Methods from ::android::hidl::base::V1_0::IBase follow.
private:
- Return<GnssLocation> getMockLocation() const;
Return<GnssSvStatus> getMockSvStatus() const;
- Return<GnssSvInfo> getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
- float elevationDegress, float azimuthDegress) const;
Return<void> reportLocation(const GnssLocation&) const;
Return<void> reportSvStatus(const GnssSvStatus&) const;
diff --git a/gnss/1.1/default/GnssDebug.cpp b/gnss/1.1/default/GnssDebug.cpp
index 62870e4..471ed24 100644
--- a/gnss/1.1/default/GnssDebug.cpp
+++ b/gnss/1.1/default/GnssDebug.cpp
@@ -18,9 +18,11 @@
#include <log/log.h>
-#include "GnssConstants.h"
+#include "Constants.h"
#include "GnssDebug.h"
+using namespace ::android::hardware::gnss::common;
+
namespace android {
namespace hardware {
namespace gnss {
diff --git a/gnss/1.1/vts/functional/Android.bp b/gnss/1.1/vts/functional/Android.bp
index 9892eca..147a470 100644
--- a/gnss/1.1/vts/functional/Android.bp
+++ b/gnss/1.1/vts/functional/Android.bp
@@ -25,6 +25,7 @@
static_libs: [
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
+ "android.hardware.gnss@common-vts-lib",
],
test_suites: ["general-tests"],
}
diff --git a/gnss/1.1/vts/functional/gnss_hal_test.cpp b/gnss/1.1/vts/functional/gnss_hal_test.cpp
index 433f5cb..381ac1d 100644
--- a/gnss/1.1/vts/functional/gnss_hal_test.cpp
+++ b/gnss/1.1/vts/functional/gnss_hal_test.cpp
@@ -17,8 +17,10 @@
#define LOG_TAG "GnssHalTest"
#include <gnss_hal_test.h>
-
#include <chrono>
+#include "Utils.h"
+
+using ::android::hardware::gnss::common::Utils;
// Implementations for the main test class for GNSS HAL
GnssHalTest::GnssHalTest()
@@ -124,69 +126,7 @@
void GnssHalTest::CheckLocation(GnssLocation& location, bool check_speed) {
bool check_more_accuracies = (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
- if (check_speed) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
- }
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
- // New uncertainties available in O must be provided,
- // at least when paired with modern hardware (2017+)
- if (check_more_accuracies) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
- if (check_speed) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY);
- }
- }
- }
- EXPECT_GE(location.latitudeDegrees, -90.0);
- EXPECT_LE(location.latitudeDegrees, 90.0);
- EXPECT_GE(location.longitudeDegrees, -180.0);
- EXPECT_LE(location.longitudeDegrees, 180.0);
- EXPECT_GE(location.altitudeMeters, -1000.0);
- EXPECT_LE(location.altitudeMeters, 30000.0);
- if (check_speed) {
- EXPECT_GE(location.speedMetersPerSec, 0.0);
- EXPECT_LE(location.speedMetersPerSec, 5.0); // VTS tests are stationary.
-
- // Non-zero speeds must be reported with an associated bearing
- if (location.speedMetersPerSec > 0.0) {
- EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
- }
- }
-
- /*
- * Tolerating some especially high values for accuracy estimate, in case of
- * first fix with especially poor geometry (happens occasionally)
- */
- EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
- EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
-
- /*
- * Some devices may define bearing as -180 to +180, others as 0 to 360.
- * Both are okay & understandable.
- */
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
- EXPECT_GE(location.bearingDegrees, -180.0);
- EXPECT_LE(location.bearingDegrees, 360.0);
- }
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
- EXPECT_GT(location.verticalAccuracyMeters, 0.0);
- EXPECT_LE(location.verticalAccuracyMeters, 500.0);
- }
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
- EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
- EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
- }
- if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
- EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
- EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
- }
-
- // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
- EXPECT_GT(location.timestamp, 1.48e12);
+ Utils::checkLocation(location, check_speed, check_more_accuracies);
}
void GnssHalTest::StartAndCheckLocations(int count) {
diff --git a/gnss/2.0/Android.bp b/gnss/2.0/Android.bp
index 9b04be0..230dd90 100644
--- a/gnss/2.0/Android.bp
+++ b/gnss/2.0/Android.bp
@@ -25,6 +25,9 @@
"android.hidl.base@1.0",
],
types: [
+ "ElapsedRealtime",
+ "ElapsedRealtimeFlags",
+ "GnssLocation",
],
gen_java: true,
gen_java_constants: true,
diff --git a/gnss/2.0/IGnss.hal b/gnss/2.0/IGnss.hal
index 1f1858e..2c149b7 100644
--- a/gnss/2.0/IGnss.hal
+++ b/gnss/2.0/IGnss.hal
@@ -20,6 +20,7 @@
import android.hardware.gnss.visibility_control@1.0::IGnssVisibilityControl;
import @1.1::IGnss;
+import GnssLocation;
import IGnssCallback;
import IGnssConfiguration;
import IGnssMeasurement;
@@ -94,4 +95,16 @@
* @return visibilityControlIface Handle to the IGnssVisibilityControl interface.
*/
getExtensionVisibilityControl() generates (IGnssVisibilityControl visibilityControlIface);
+
+ /**
+ * Injects current location from the best available location provider.
+ *
+ * Unlike injectLocation, this method may inject a recent GNSS location from the HAL
+ * implementation, if that is the best available location known to the framework.
+ *
+ * @param location Location information from the best available location provider.
+ *
+ * @return success Returns true if successful.
+ */
+ injectBestLocation_2_0(GnssLocation location) generates (bool success);
};
\ No newline at end of file
diff --git a/gnss/2.0/IGnssCallback.hal b/gnss/2.0/IGnssCallback.hal
index 6baff91..e2ac02a 100644
--- a/gnss/2.0/IGnssCallback.hal
+++ b/gnss/2.0/IGnssCallback.hal
@@ -18,6 +18,7 @@
import @1.0::IGnssCallback;
import @1.1::IGnssCallback;
+import GnssLocation;
/**
* The interface is required for the HAL to communicate certain information
@@ -44,4 +45,11 @@
*/
gnssSetCapabilitiesCb_2_0(bitfield<Capabilities> capabilities);
+ /**
+ * Called when a GNSS location is available.
+ *
+ * @param location Location information from HAL.
+ */
+ gnssLocationCb_2_0(GnssLocation location);
+
};
\ No newline at end of file
diff --git a/gnss/2.0/IGnssMeasurementCallback.hal b/gnss/2.0/IGnssMeasurementCallback.hal
index fc44465..d5dc038 100644
--- a/gnss/2.0/IGnssMeasurementCallback.hal
+++ b/gnss/2.0/IGnssMeasurementCallback.hal
@@ -18,6 +18,7 @@
import @1.0::IGnssMeasurementCallback;
import @1.1::IGnssMeasurementCallback;
+import ElapsedRealtime;
/** The callback interface to report measurements from the HAL. */
interface IGnssMeasurementCallback extends @1.1::IGnssMeasurementCallback {
@@ -492,6 +493,12 @@
/** The GNSS clock time reading. */
GnssClock clock;
+
+ /**
+ * Timing information of the GNSS data synchronized with SystemClock.elapsedRealtimeNanos()
+ * clock.
+ */
+ ElapsedRealtime elapsedRealtime;
};
/**
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 985aa2b..f327197 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -40,4 +40,7 @@
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
],
+ static_libs: [
+ "android.hardware.gnss@common-default-lib",
+ ],
}
diff --git a/gnss/2.0/default/Gnss.cpp b/gnss/2.0/default/Gnss.cpp
index 217f0f3..599681b 100644
--- a/gnss/2.0/default/Gnss.cpp
+++ b/gnss/2.0/default/Gnss.cpp
@@ -17,14 +17,19 @@
#define LOG_TAG "Gnss"
#include "Gnss.h"
+
#include <log/log.h>
+#include <utils/SystemClock.h>
+
#include "AGnss.h"
#include "AGnssRil.h"
#include "GnssConfiguration.h"
#include "GnssMeasurement.h"
#include "GnssVisibilityControl.h"
+#include "Utils.h"
using ::android::hardware::Status;
+using ::android::hardware::gnss::common::Utils;
using ::android::hardware::gnss::visibility_control::V1_0::implementation::GnssVisibilityControl;
namespace android {
@@ -33,64 +38,106 @@
namespace V2_0 {
namespace implementation {
+using GnssSvFlags = IGnssCallback::GnssSvFlags;
+
sp<V2_0::IGnssCallback> Gnss::sGnssCallback_2_0 = nullptr;
sp<V1_1::IGnssCallback> Gnss::sGnssCallback_1_1 = nullptr;
+namespace {
+
+V2_0::GnssLocation getMockLocationV2_0() {
+ const ElapsedRealtime timestamp = {
+ .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+ ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1000000};
+
+ V2_0::GnssLocation location = {.v1_0 = Utils::getMockLocation(), .elapsedRealtime = timestamp};
+ return location;
+}
+
+} // namespace
+
+Gnss::Gnss() : mMinIntervalMs(1000) {}
+
+Gnss::~Gnss() {
+ stop();
+}
+
// Methods from V1_0::IGnss follow.
Return<bool> Gnss::setCallback(const sp<V1_0::IGnssCallback>&) {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return bool{};
}
Return<bool> Gnss::start() {
- // TODO implement
- return bool{};
+ if (mIsActive) {
+ ALOGW("Gnss has started. Restarting...");
+ stop();
+ }
+
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ const auto location = getMockLocationV2_0();
+ this->reportLocation(location);
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+ }
+ });
+ return true;
}
Return<bool> Gnss::stop() {
- // TODO implement
- return bool{};
+ mIsActive = false;
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+ return true;
}
Return<void> Gnss::cleanup() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return Void();
}
Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return bool{};
}
Return<bool> Gnss::injectLocation(double, double, float) {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return bool{};
}
Return<void> Gnss::deleteAidingData(V1_0::IGnss::GnssAidingData) {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return Void();
}
Return<bool> Gnss::setPositionMode(V1_0::IGnss::GnssPositionMode,
V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
uint32_t) {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return bool{};
}
Return<sp<V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IAGnssRil>{};
}
Return<sp<V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IGnssGeofencing>{};
}
Return<sp<V1_0::IAGnss>> Gnss::getExtensionAGnss() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IAGnss>{};
}
@@ -105,27 +152,27 @@
}
Return<sp<V1_0::IGnssNavigationMessage>> Gnss::getExtensionGnssNavigationMessage() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IGnssNavigationMessage>{};
}
Return<sp<V1_0::IGnssXtra>> Gnss::getExtensionXtra() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IGnssXtra>{};
}
Return<sp<V1_0::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IGnssConfiguration>{};
}
Return<sp<V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IGnssDebug>{};
}
Return<sp<V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_0::IGnssBatching>{};
}
@@ -164,12 +211,11 @@
Return<bool> Gnss::setPositionMode_1_1(V1_0::IGnss::GnssPositionMode,
V1_0::IGnss::GnssPositionRecurrence, uint32_t, uint32_t,
uint32_t, bool) {
- // TODO implement
- return bool{};
+ return true;
}
Return<sp<V1_1::IGnssConfiguration>> Gnss::getExtensionGnssConfiguration_1_1() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<V1_1::IGnssConfiguration>{};
}
@@ -179,7 +225,7 @@
}
Return<bool> Gnss::injectBestLocation(const V1_0::GnssLocation&) {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return bool{};
}
@@ -203,7 +249,7 @@
Return<sp<measurement_corrections::V1_0::IMeasurementCorrections>>
Gnss::getExtensionMeasurementCorrections() {
- // TODO implement
+ // TODO(b/124012850): Implement function.
return sp<measurement_corrections::V1_0::IMeasurementCorrections>{};
}
@@ -243,6 +289,21 @@
return true;
}
+Return<void> Gnss::reportLocation(const V2_0::GnssLocation& location) const {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (sGnssCallback_2_0 == nullptr) {
+ ALOGE("%s: sGnssCallback 2.0 is null.", __func__);
+ return Void();
+ }
+ sGnssCallback_2_0->gnssLocationCb_2_0(location);
+ return Void();
+}
+
+Return<bool> Gnss::injectBestLocation_2_0(const V2_0::GnssLocation&) {
+ // TODO(b/124012850): Implement function.
+ return bool{};
+}
+
} // namespace implementation
} // namespace V2_0
} // namespace gnss
diff --git a/gnss/2.0/default/Gnss.h b/gnss/2.0/default/Gnss.h
index 890b026..f02ab0a 100644
--- a/gnss/2.0/default/Gnss.h
+++ b/gnss/2.0/default/Gnss.h
@@ -20,6 +20,9 @@
#include <android/hardware/gnss/2.0/IGnss.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
+#include <atomic>
+#include <mutex>
+#include <thread>
namespace android {
namespace hardware {
@@ -35,7 +38,14 @@
using ::android::hardware::Return;
using ::android::hardware::Void;
+using GnssConstellationType = V1_0::GnssConstellationType;
+using GnssLocation = V1_0::GnssLocation;
+using GnssSvInfo = V1_0::IGnssCallback::GnssSvInfo;
+using GnssSvStatus = V1_0::IGnssCallback::GnssSvStatus;
+
struct Gnss : public IGnss {
+ Gnss();
+ ~Gnss();
// Methods from V1_0::IGnss follow.
Return<bool> setCallback(const sp<V1_0::IGnssCallback>& callback) override;
Return<bool> start() override;
@@ -69,7 +79,7 @@
uint32_t preferredTimeMs, bool lowPowerMode) override;
Return<sp<V1_1::IGnssConfiguration>> getExtensionGnssConfiguration_1_1() override;
Return<sp<V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() override;
- Return<bool> injectBestLocation(const V1_0::GnssLocation& location) override;
+ Return<bool> injectBestLocation(const GnssLocation& location) override;
// Methods from V2_0::IGnss follow.
Return<sp<V2_0::IGnssConfiguration>> getExtensionGnssConfiguration_2_0() override;
@@ -81,10 +91,16 @@
getExtensionMeasurementCorrections() override;
Return<sp<visibility_control::V1_0::IGnssVisibilityControl>> getExtensionVisibilityControl()
override;
+ Return<bool> injectBestLocation_2_0(const V2_0::GnssLocation& location) override;
- private:
+ private:
+ Return<void> reportLocation(const V2_0::GnssLocation&) const;
static sp<V2_0::IGnssCallback> sGnssCallback_2_0;
static sp<V1_1::IGnssCallback> sGnssCallback_1_1;
+ std::atomic<long> mMinIntervalMs;
+ std::atomic<bool> mIsActive;
+ std::thread mThread;
+ mutable std::mutex mMutex;
};
} // namespace implementation
diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp
index 0f707b4..702c9e2 100644
--- a/gnss/2.0/default/GnssMeasurement.cpp
+++ b/gnss/2.0/default/GnssMeasurement.cpp
@@ -16,7 +16,9 @@
#define LOG_TAG "GnssMeasurement"
#include "GnssMeasurement.h"
+
#include <log/log.h>
+#include <utils/SystemClock.h>
namespace android {
namespace hardware {
@@ -129,7 +131,18 @@
.driftNsps = -51.757811607455452,
.driftUncertaintyNsps = 310.64968328491528,
.hwClockDiscontinuityCount = 1};
- GnssData gnssData = {.measurements = measurements, .clock = clock};
+
+ ElapsedRealtime timestamp = {
+ .flags = ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
+ ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1000000};
+
+ GnssData gnssData = {
+ .measurements = measurements, .clock = clock, .elapsedRealtime = timestamp};
return gnssData;
}
diff --git a/gnss/2.0/types.hal b/gnss/2.0/types.hal
index 97c178f..4abb604 100644
--- a/gnss/2.0/types.hal
+++ b/gnss/2.0/types.hal
@@ -16,5 +16,60 @@
package android.hardware.gnss@2.0;
+import @1.0::GnssLocation;
+
/** Network handle type. */
typedef uint64_t net_handle_t;
+
+/**
+ * Flags indicating the validity of the fields in ElapsedRealtime.
+ */
+@export(name="", value_prefix="ELAPSED_REALTIME_")
+enum ElapsedRealtimeFlags : uint16_t {
+ /** A valid timestampNs is stored in the data structure. */
+ HAS_TIMESTAMP_NS = 1 << 0,
+ /** A valid timeUncertaintyNs is stored in the data structure. */
+ HAS_TIME_UNCERTAINTY_NS = 1 << 1,
+};
+
+/**
+ * Represents an estimate of elapsed time since boot of Android for a given event.
+ *
+ * This timestamp MUST represent the time the event happened and MUST be synchronized
+ * with the SystemClock.elapsedRealtimeNanos() clock.
+ */
+struct ElapsedRealtime {
+ /**
+ * A set of flags indicating the validity of each field in this data structure.
+ *
+ * Fields may have invalid information in them, if not marked as valid by the
+ * corresponding bit in flags.
+ */
+ bitfield<ElapsedRealtimeFlags> flags;
+
+ /**
+ * Estimate of the elapsed time since boot value for the corresponding event in nanoseconds.
+ */
+ uint64_t timestampNs;
+
+ /**
+ * Estimate of the relative precision of the alignment of this SystemClock
+ * timestamp, with the reported measurements in nanoseconds (68% confidence).
+ */
+ uint64_t timeUncertaintyNs;
+};
+
+/** Represents a location. */
+struct GnssLocation {
+ @1.0::GnssLocation v1_0;
+
+ /**
+ * Timing information of the GNSS location synchronized with SystemClock.elapsedRealtimeNanos()
+ * clock.
+ *
+ * This clock information can be obtained from SystemClock.elapsedRealtimeNanos(), when the GNSS
+ * is attached straight to the AP/SOC. When it is attached to a separate module the timestamp
+ * needs to be estimatedd by syncing the notion of time via PTP or some other mechanism.
+ */
+ ElapsedRealtime elapsedRealtime;
+};
\ No newline at end of file
diff --git a/gnss/2.0/vts/functional/Android.bp b/gnss/2.0/vts/functional/Android.bp
index 684b381..278d87b 100644
--- a/gnss/2.0/vts/functional/Android.bp
+++ b/gnss/2.0/vts/functional/Android.bp
@@ -28,5 +28,6 @@
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
+ "android.hardware.gnss@common-vts-lib",
],
}
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.cpp b/gnss/2.0/vts/functional/gnss_hal_test.cpp
index 3a48c9e..c564f41 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test.cpp
@@ -17,8 +17,10 @@
#define LOG_TAG "GnssHalTest"
#include <gnss_hal_test.h>
-
#include <chrono>
+#include "Utils.h"
+
+using ::android::hardware::gnss::common::Utils;
// Implementations for the main test class for GNSS HAL
GnssHalTest::GnssHalTest()
@@ -77,9 +79,88 @@
EXPECT_EQ(name_called_count_, 1);
}
+void GnssHalTest::StopAndClearLocations() {
+ const auto result = gnss_hal_->stop();
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ /*
+ * Clear notify/waiting counter, allowing up till the timeout after
+ * the last reply for final startup messages to arrive (esp. system
+ * info.)
+ */
+ while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
+ }
+ location_called_count_ = 0;
+}
+
+void GnssHalTest::SetPositionMode(const int min_interval_msec, const bool low_power_mode) {
+ const int kPreferredAccuracy = 0; // Ideally perfect (matches GnssLocationProvider)
+ const int kPreferredTimeMsec = 0; // Ideally immediate
+
+ const auto result = gnss_hal_->setPositionMode_1_1(
+ IGnss::GnssPositionMode::MS_BASED, IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC,
+ min_interval_msec, kPreferredAccuracy, kPreferredTimeMsec, low_power_mode);
+
+ ASSERT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+}
+
+bool GnssHalTest::StartAndCheckFirstLocation() {
+ const auto result = gnss_hal_->start();
+
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(result);
+
+ /*
+ * GnssLocationProvider support of AGPS SUPL & XtraDownloader is not available in VTS,
+ * so allow time to demodulate ephemeris over the air.
+ */
+ const int kFirstGnssLocationTimeoutSeconds = 75;
+
+ wait(kFirstGnssLocationTimeoutSeconds);
+ EXPECT_EQ(location_called_count_, 1);
+
+ if (location_called_count_ > 0) {
+ // don't require speed on first fix
+ CheckLocation(last_location_, false);
+ return true;
+ }
+ return false;
+}
+
+void GnssHalTest::CheckLocation(const GnssLocation_2_0& location, bool check_speed) {
+ const bool check_more_accuracies = (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
+
+ Utils::checkLocation(location.v1_0, check_speed, check_more_accuracies);
+}
+
+void GnssHalTest::StartAndCheckLocations(int count) {
+ const int kMinIntervalMsec = 500;
+ const int kLocationTimeoutSubsequentSec = 2;
+ const bool kLowPowerMode = false;
+
+ SetPositionMode(kMinIntervalMsec, kLowPowerMode);
+
+ EXPECT_TRUE(StartAndCheckFirstLocation());
+
+ for (int i = 1; i < count; i++) {
+ EXPECT_EQ(std::cv_status::no_timeout, wait(kLocationTimeoutSubsequentSec));
+ EXPECT_EQ(location_called_count_, i + 1);
+ // Don't cause confusion by checking details if no location yet
+ if (location_called_count_ > 0) {
+ // Should be more than 1 location by now, but if not, still don't check first fix speed
+ CheckLocation(last_location_, location_called_count_ > 1);
+ }
+ }
+}
+
void GnssHalTest::notify() {
- std::unique_lock<std::mutex> lock(mtx_);
- notify_count_++;
+ {
+ std::unique_lock<std::mutex> lock(mtx_);
+ notify_count_++;
+ }
cv_.notify_one();
}
@@ -112,6 +193,14 @@
return Void();
}
+Return<void> GnssHalTest::GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
+ ALOGI("Capabilities (v2.0) received %d", capabilities);
+ parent_.capabilities_called_count_++;
+ parent_.last_capabilities_ = capabilities;
+ parent_.notify();
+ return Void();
+}
+
Return<void> GnssHalTest::GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
ALOGI("Name received: %s", name.c_str());
parent_.name_called_count_++;
@@ -120,8 +209,19 @@
return Void();
}
-Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation& location) {
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb(const GnssLocation_1_0& location) {
ALOGI("Location received");
+ GnssLocation_2_0 location_v2_0;
+ location_v2_0.v1_0 = location;
+ return gnssLocationCbImpl(location_v2_0);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCb_2_0(const GnssLocation_2_0& location) {
+ ALOGI("Location (v2.0) received");
+ return gnssLocationCbImpl(location);
+}
+
+Return<void> GnssHalTest::GnssCallback::gnssLocationCbImpl(const GnssLocation_2_0& location) {
parent_.location_called_count_++;
parent_.last_location_ = location;
parent_.notify();
diff --git a/gnss/2.0/vts/functional/gnss_hal_test.h b/gnss/2.0/vts/functional/gnss_hal_test.h
index 5649b45..7793eb7 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test.h
+++ b/gnss/2.0/vts/functional/gnss_hal_test.h
@@ -18,7 +18,6 @@
#define GNSS_HAL_TEST_H_
#include <android/hardware/gnss/2.0/IGnss.h>
-
#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>
@@ -29,11 +28,13 @@
using android::hardware::Return;
using android::hardware::Void;
-using android::hardware::gnss::V1_0::GnssLocation;
-
using android::hardware::gnss::V1_0::GnssLocationFlags;
-using android::hardware::gnss::V1_1::IGnssCallback;
using android::hardware::gnss::V2_0::IGnss;
+using android::hardware::gnss::V2_0::IGnssCallback;
+
+using GnssLocation_1_0 = android::hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_2_0 = android::hardware::gnss::V2_0::GnssLocation;
+
using IGnssMeasurementCallback_1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
using IGnssMeasurementCallback_1_1 = android::hardware::gnss::V1_1::IGnssMeasurementCallback;
using IGnssMeasurementCallback_2_0 = android::hardware::gnss::V2_0::IGnssMeasurementCallback;
@@ -97,10 +98,15 @@
Return<void> gnssRequestTimeCb() override { return Void(); }
// Actual (test) callback handlers
Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
- Return<void> gnssLocationCb(const GnssLocation& location) override;
+ Return<void> gnssLocationCb(const GnssLocation_1_0& location) override;
+ Return<void> gnssLocationCb_2_0(const GnssLocation_2_0& location) override;
Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
+ Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
+
+ private:
+ Return<void> gnssLocationCbImpl(const GnssLocation_2_0& location);
};
/* Callback class for GnssMeasurement. */
@@ -130,9 +136,51 @@
*/
void SetUpGnssCallback();
+ /*
+ * StartAndCheckFirstLocation:
+ * Helper function to start location, and check the first one.
+ *
+ * <p> Note this leaves the Location request active, to enable Stop call vs. other call
+ * reordering tests.
+ *
+ * returns true if a location was successfully generated
+ */
+ bool StartAndCheckFirstLocation();
+
+ /*
+ * CheckLocation:
+ * Helper function to vet Location fields
+ *
+ * check_speed: true if speed related fields are also verified.
+ */
+ void CheckLocation(const GnssLocation_2_0& location, const bool check_speed);
+
+ /*
+ * StartAndCheckLocations:
+ * Helper function to collect, and check a number of
+ * normal ~1Hz locations.
+ *
+ * Note this leaves the Location request active, to enable Stop call vs. other call
+ * reordering tests.
+ */
+ void StartAndCheckLocations(int count);
+
+ /*
+ * StopAndClearLocations:
+ * Helper function to stop locations, and clear any remaining notifications
+ */
+ void StopAndClearLocations();
+
+ /*
+ * SetPositionMode:
+ * Helper function to set positioning mode and verify output
+ */
+ void SetPositionMode(const int min_interval_msec, const bool low_power_mode);
+
sp<IGnss> gnss_hal_; // GNSS HAL to call into
sp<IGnssCallback> gnss_cb_; // Primary callback interface
+ // TODO: make these variables thread-safe.
/* Count of calls to set the following items, and the latest item (used by
* test.)
*/
@@ -144,7 +192,7 @@
IGnssCallback::GnssSystemInfo last_info_;
uint32_t last_capabilities_;
- GnssLocation last_location_;
+ GnssLocation_2_0 last_location_;
IGnssMeasurementCallback_2_0::GnssData last_measurement_;
android::hardware::hidl_string last_name_;
diff --git a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
index 48f2be8..b135dba 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -31,7 +31,9 @@
using IAGnss_2_0 = android::hardware::gnss::V2_0::IAGnss;
using IAGnss_1_0 = android::hardware::gnss::V1_0::IAGnss;
using IAGnssCallback_2_0 = android::hardware::gnss::V2_0::IAGnssCallback;
+
using android::hardware::gnss::V1_0::IGnssNi;
+using android::hardware::gnss::V2_0::ElapsedRealtimeFlags;
using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
/*
@@ -269,3 +271,64 @@
ASSERT_TRUE(result.isOk());
EXPECT_TRUE(result);
}
+
+/*
+ * TestGnssDataElapsedRealtimeFlags:
+ * Sets a GnssMeasurementCallback, waits for a GnssData object, and verifies the flags in member
+ * elapsedRealitme are valid.
+ */
+TEST_F(GnssHalTest, TestGnssDataElapsedRealtimeFlags) {
+ const int kFirstGnssMeasurementTimeoutSeconds = 10;
+
+ auto gnssMeasurement = gnss_hal_->getExtensionGnssMeasurement_2_0();
+ if (!gnssMeasurement.isOk()) {
+ return;
+ }
+
+ sp<IGnssMeasurement_2_0> iGnssMeasurement = gnssMeasurement;
+ if (iGnssMeasurement == nullptr) {
+ return;
+ }
+
+ sp<IGnssMeasurementCallback_2_0> callback = new GnssMeasurementCallback(*this);
+
+ auto result = iGnssMeasurement->setCallback_2_0(callback, /* enableFullTracking= */ true);
+ ASSERT_TRUE(result.isOk());
+ EXPECT_EQ(result, IGnssMeasurement_1_0::GnssMeasurementStatus::SUCCESS);
+
+ wait(kFirstGnssMeasurementTimeoutSeconds);
+ EXPECT_EQ(measurement_called_count_, 1);
+
+ ASSERT_TRUE((int)last_measurement_.elapsedRealtime.flags >= 0 &&
+ (int)last_measurement_.elapsedRealtime.flags <=
+ (int)ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS);
+
+ // We expect a non-zero timestamp when set.
+ if (last_measurement_.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+ ASSERT_TRUE(last_measurement_.elapsedRealtime.timestampNs != 0);
+ }
+
+ iGnssMeasurement->close();
+}
+
+TEST_F(GnssHalTest, TestGnssLocationElapsedRealtime) {
+ StartAndCheckFirstLocation();
+
+ ASSERT_TRUE((int)last_location_.elapsedRealtime.flags >= 0 &&
+ (int)last_location_.elapsedRealtime.flags <=
+ (int)ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS);
+
+ // We expect a non-zero timestamp when set.
+ if (last_location_.elapsedRealtime.flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+ ASSERT_TRUE(last_location_.elapsedRealtime.timestampNs != 0);
+ }
+
+ StopAndClearLocations();
+}
+
+// This test only verify that injectBestLocation_2_0 does not crash.
+TEST_F(GnssHalTest, TestInjectBestLocation_2_0) {
+ StartAndCheckFirstLocation();
+ gnss_hal_->injectBestLocation_2_0(last_location_);
+ StopAndClearLocations();
+}
diff --git a/gnss/common/OWNERS b/gnss/common/OWNERS
new file mode 100644
index 0000000..3ed36da
--- /dev/null
+++ b/gnss/common/OWNERS
@@ -0,0 +1,7 @@
+wyattriley@google.com
+gomo@google.com
+smalkos@google.com
+yuhany@google.com
+
+# VTS team
+yim@google.com
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
new file mode 100644
index 0000000..4ea97fa
--- /dev/null
+++ b/gnss/common/utils/default/Android.bp
@@ -0,0 +1,33 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_library_static {
+ name: "android.hardware.gnss@common-default-lib",
+ vendor_available: true,
+ relative_install_path: "hw",
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+ srcs: [
+ "Utils.cpp",
+ ],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "android.hardware.gnss@1.0",
+ ],
+}
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
new file mode 100644
index 0000000..b9a06e8
--- /dev/null
+++ b/gnss/common/utils/default/Utils.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Constants.h>
+#include <Utils.h>
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+using GnssSvFlags = V1_0::IGnssCallback::GnssSvFlags;
+
+GnssLocation Utils::getMockLocation() {
+ GnssLocation location = {.gnssLocationFlags = 0xFF,
+ .latitudeDegrees = kMockLatitudeDegrees,
+ .longitudeDegrees = kMockLongitudeDegrees,
+ .altitudeMeters = kMockAltitudeMeters,
+ .speedMetersPerSec = kMockSpeedMetersPerSec,
+ .bearingDegrees = kMockBearingDegrees,
+ .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+ .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+ .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+ .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+ .timestamp = kMockTimestamp};
+ return location;
+}
+
+GnssSvInfo Utils::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
+ float elevationDegrees, float azimuthDegrees) {
+ GnssSvInfo svInfo = {.svid = svid,
+ .constellation = type,
+ .cN0Dbhz = cN0DbHz,
+ .elevationDegrees = elevationDegrees,
+ .azimuthDegrees = azimuthDegrees,
+ .svFlag = GnssSvFlags::USED_IN_FIX | GnssSvFlags::HAS_EPHEMERIS_DATA |
+ GnssSvFlags::HAS_ALMANAC_DATA};
+ return svInfo;
+}
+
+} // namespace common
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/1.1/default/GnssConstants.h b/gnss/common/utils/default/include/Constants.h
similarity index 78%
rename from gnss/1.1/default/GnssConstants.h
rename to gnss/common/utils/default/include/Constants.h
index 9ce1a12..000a9ec 100644
--- a/gnss/1.1/default/GnssConstants.h
+++ b/gnss/common/utils/default/include/Constants.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,14 +14,15 @@
* limitations under the License.
*/
-#ifndef android_hardware_gnss_V1_1_GnssConstants_H_
-#define android_hardware_gnss_V1_1_GnssConstants_H_
+#ifndef android_hardware_gnss_common_Constants_H_
+#define android_hardware_gnss_common_Constants_H_
+
+#include <cstdint>
namespace android {
namespace hardware {
namespace gnss {
-namespace V1_1 {
-namespace implementation {
+namespace common {
const float kMockLatitudeDegrees = 37.4219999;
const float kMockLongitudeDegrees = -122.0840575;
@@ -34,10 +35,9 @@
const float kMockBearingAccuracyDegrees = 90;
const int64_t kMockTimestamp = 1519930775453L;
-} // namespace implementation
-} // namespace V1_1
+} // namespace common
} // namespace gnss
} // namespace hardware
} // namespace android
-#endif // android_hardware_gnss_V1_1_GnssConstants_H_
+#endif // android_hardware_gnss_common_Constants_H_
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
new file mode 100644
index 0000000..47c8812
--- /dev/null
+++ b/gnss/common/utils/default/include/Utils.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef android_hardware_gnss_common_default_Utils_H_
+#define android_hardware_gnss_common_default_Utils_H_
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+
+using GnssConstellationType = ::android::hardware::gnss::V1_0::GnssConstellationType;
+using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
+using GnssSvInfo = ::android::hardware::gnss::V1_0::IGnssCallback::GnssSvInfo;
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct Utils {
+ static GnssLocation getMockLocation();
+ static GnssSvInfo getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz,
+ float elevationDegrees, float azimuthDegrees);
+};
+
+} // namespace common
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_common_default_Utils_H_
diff --git a/gnss/common/utils/vts/Android.bp b/gnss/common/utils/vts/Android.bp
new file mode 100644
index 0000000..99d8cf9
--- /dev/null
+++ b/gnss/common/utils/vts/Android.bp
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_library_static {
+ name: "android.hardware.gnss@common-vts-lib",
+ vendor_available: true,
+ relative_install_path: "hw",
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ ],
+ srcs: [
+ "Utils.cpp",
+ ],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "android.hardware.gnss@1.0",
+ ],
+ static_libs: [
+ "libgtest",
+ ],
+}
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
new file mode 100644
index 0000000..24d6883
--- /dev/null
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <Utils.h>
+#include "gtest/gtest.h"
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+using V1_0::GnssLocationFlags;
+
+void Utils::checkLocation(const GnssLocation& location, bool check_speed,
+ bool check_more_accuracies) {
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
+ if (check_speed) {
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
+ }
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
+ // New uncertainties available in O must be provided,
+ // at least when paired with modern hardware (2017+)
+ if (check_more_accuracies) {
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY);
+ if (check_speed) {
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY);
+ if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY);
+ }
+ }
+ }
+ EXPECT_GE(location.latitudeDegrees, -90.0);
+ EXPECT_LE(location.latitudeDegrees, 90.0);
+ EXPECT_GE(location.longitudeDegrees, -180.0);
+ EXPECT_LE(location.longitudeDegrees, 180.0);
+ EXPECT_GE(location.altitudeMeters, -1000.0);
+ EXPECT_LE(location.altitudeMeters, 30000.0);
+ if (check_speed) {
+ EXPECT_GE(location.speedMetersPerSec, 0.0);
+ EXPECT_LE(location.speedMetersPerSec, 5.0); // VTS tests are stationary.
+
+ // Non-zero speeds must be reported with an associated bearing
+ if (location.speedMetersPerSec > 0.0) {
+ EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
+ }
+ }
+
+ /*
+ * Tolerating some especially high values for accuracy estimate, in case of
+ * first fix with especially poor geometry (happens occasionally)
+ */
+ EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
+ EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
+
+ /*
+ * Some devices may define bearing as -180 to +180, others as 0 to 360.
+ * Both are okay & understandable.
+ */
+ if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+ EXPECT_GE(location.bearingDegrees, -180.0);
+ EXPECT_LE(location.bearingDegrees, 360.0);
+ }
+ if (location.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) {
+ EXPECT_GT(location.verticalAccuracyMeters, 0.0);
+ EXPECT_LE(location.verticalAccuracyMeters, 500.0);
+ }
+ if (location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) {
+ EXPECT_GT(location.speedAccuracyMetersPerSecond, 0.0);
+ EXPECT_LE(location.speedAccuracyMetersPerSecond, 50.0);
+ }
+ if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) {
+ EXPECT_GT(location.bearingAccuracyDegrees, 0.0);
+ EXPECT_LE(location.bearingAccuracyDegrees, 360.0);
+ }
+
+ // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
+ EXPECT_GT(location.timestamp, 1.48e12);
+}
+
+} // namespace common
+} // namespace gnss
+} // namespace hardware
+} // namespace android
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
new file mode 100644
index 0000000..f8eeff6
--- /dev/null
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef android_hardware_gnss_common_vts_Utils_H_
+#define android_hardware_gnss_common_vts_Utils_H_
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+
+using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
+
+namespace android {
+namespace hardware {
+namespace gnss {
+namespace common {
+
+struct Utils {
+ static void checkLocation(const GnssLocation& location, bool check_speed,
+ bool check_more_accuracies);
+};
+
+} // namespace common
+} // namespace gnss
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_gnss_common_vts_Utils_H_
diff --git a/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp b/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
index 5ad561c..946e5f2 100644
--- a/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
+++ b/health/storage/1.0/vts/functional/VtsHalHealthStorageV1_0TargetTest.cpp
@@ -36,7 +36,7 @@
const uint64_t kDevGcTimeoutSec = 120;
const std::chrono::seconds kDevGcTimeout{kDevGcTimeoutSec};
// Time accounted for RPC calls.
-const std::chrono::milliseconds kRpcTime{100};
+const std::chrono::milliseconds kRpcTime{1000};
template <typename R>
std::string toString(std::chrono::duration<R, std::milli> time) {
@@ -90,11 +90,8 @@
template <typename R, typename P>
void waitForResult(std::chrono::duration<R, P> timeout, Result expected) {
std::unique_lock<std::mutex> lock(mMutex);
- if (waitLocked(&lock, timeout)) {
- EXPECT_EQ(expected, mResult);
- } else {
- LOG(INFO) << "timeout after " << toString(timeout);
- }
+ ASSERT_TRUE(waitLocked(&lock, timeout)) << "timeout after " << toString(timeout);
+ EXPECT_EQ(expected, mResult);
}
private:
diff --git a/input/classifier/1.0/vts/OWNERS b/input/classifier/1.0/vts/OWNERS
new file mode 100644
index 0000000..447f3d9
--- /dev/null
+++ b/input/classifier/1.0/vts/OWNERS
@@ -0,0 +1,3 @@
+michaelwr@google.com
+pquinn@google.com
+svv@google.com
\ No newline at end of file
diff --git a/input/classifier/1.0/vts/functional/Android.bp b/input/classifier/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..ef49d70
--- /dev/null
+++ b/input/classifier/1.0/vts/functional/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2019 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.
+//
+
+cc_test {
+ name: "VtsHalInputClassifierV1_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalInputClassifierV1_0TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.input.classifier@1.0",
+ "android.hardware.input.common@1.0",
+ ],
+ test_suites: ["general-tests"],
+}
+
diff --git a/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp
new file mode 100644
index 0000000..f033c2a
--- /dev/null
+++ b/input/classifier/1.0/vts/functional/VtsHalInputClassifierV1_0TargetTest.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "input_classifier_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/logging.h>
+#include <android/hardware/input/classifier/1.0/IInputClassifier.h>
+#include <android/hardware/input/common/1.0/types.h>
+#include <input/InputDevice.h>
+#include <unistd.h>
+
+using ::android::ReservedInputDeviceId;
+using ::android::sp;
+using ::android::hardware::Return;
+using ::android::hardware::input::classifier::V1_0::IInputClassifier;
+using ::android::hardware::input::common::V1_0::Action;
+using ::android::hardware::input::common::V1_0::Axis;
+using ::android::hardware::input::common::V1_0::Button;
+using ::android::hardware::input::common::V1_0::EdgeFlag;
+using ::android::hardware::input::common::V1_0::MotionEvent;
+using ::android::hardware::input::common::V1_0::PointerCoords;
+using ::android::hardware::input::common::V1_0::PointerProperties;
+using ::android::hardware::input::common::V1_0::Source;
+using ::android::hardware::input::common::V1_0::ToolType;
+using ::android::hardware::input::common::V1_0::VideoFrame;
+
+static MotionEvent getSimpleMotionEvent() {
+ MotionEvent event;
+ event.action = Action::DOWN;
+ event.actionButton = Button::NONE;
+ event.actionIndex = 0;
+ event.buttonState = 0;
+ event.deviceId = 0;
+ event.deviceTimestamp = 0;
+ event.displayId = 1;
+ event.downTime = 2;
+ event.edgeFlags = 0;
+ event.eventTime = 3;
+ event.flags = 0;
+ event.frames = {};
+ event.metaState = 0;
+ event.policyFlags = 0;
+ event.source = Source::TOUCHSCREEN;
+ event.xPrecision = 0;
+ event.yPrecision = 0;
+
+ PointerCoords coords;
+ coords.bits = Axis::X | Axis::Y;
+ coords.values = {1 /*X*/, 2 /*Y*/};
+ event.pointerCoords = {coords};
+
+ PointerProperties properties;
+ properties.id = 0;
+ properties.toolType = ToolType::FINGER;
+ event.pointerProperties = {properties};
+
+ return event;
+}
+
+// Test environment for Input Classifier HIDL HAL.
+class InputClassifierHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static InputClassifierHidlEnvironment* Instance() {
+ static InputClassifierHidlEnvironment* instance = new InputClassifierHidlEnvironment;
+ return instance;
+ }
+
+ virtual void registerTestServices() override { registerTestService<IInputClassifier>(); }
+
+ private:
+ InputClassifierHidlEnvironment() {}
+};
+
+// The main test class for INPUT CLASSIFIER HIDL HAL 1.0.
+class InputClassifierHidlTest_1_0 : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ classifier = ::testing::VtsHalHidlTargetTestBase::getService<IInputClassifier>(
+ InputClassifierHidlEnvironment::Instance()->getServiceName<IInputClassifier>());
+ ASSERT_NE(classifier, nullptr);
+ }
+
+ virtual void TearDown() override {}
+
+ sp<IInputClassifier> classifier;
+};
+
+/**
+ * Call resetDevice(..) for a few common device id values, and make sure that the HAL
+ * can handle the resets gracefully.
+ */
+TEST_F(InputClassifierHidlTest_1_0, ResetDevice) {
+ EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID).isOk());
+ EXPECT_TRUE(classifier->resetDevice(ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID).isOk());
+ EXPECT_TRUE(classifier->resetDevice(1).isOk());
+ EXPECT_TRUE(classifier->resetDevice(2).isOk());
+}
+
+/**
+ * Call reset() on the HAL to ensure no fatal failure there.
+ */
+TEST_F(InputClassifierHidlTest_1_0, ResetHal) {
+ EXPECT_TRUE(classifier->reset().isOk());
+}
+
+/**
+ * Classify an event without any video frames.
+ */
+TEST_F(InputClassifierHidlTest_1_0, Classify_NoVideoFrame) {
+ // Create a MotionEvent that does not have any video data
+ MotionEvent event = getSimpleMotionEvent();
+
+ EXPECT_TRUE(classifier->classify(event).isOk());
+ // We are not checking the actual classification here,
+ // because the HAL operation is highly device-specific.
+
+ // Return HAL to a consistent state by doing a reset
+ classifier->reset();
+}
+
+/**
+ * Classify an event with one video frame. Should be the most common scenario.
+ */
+TEST_F(InputClassifierHidlTest_1_0, Classify_OneVideoFrame) {
+ MotionEvent event = getSimpleMotionEvent();
+ VideoFrame frame;
+ frame.data = {1, 2, 3, 4};
+ frame.height = 2;
+ frame.width = 2;
+ frame.timestamp = event.eventTime;
+ event.frames = {frame};
+
+ EXPECT_TRUE(classifier->classify(event).isOk());
+ // We are not checking the actual classification here,
+ // because the HAL operation is highly device-specific.
+
+ // Return HAL to a consistent state by doing a reset
+ classifier->reset();
+}
+
+/**
+ * Classify an event with 2 video frames. This could happen if there's slowness in the system,
+ * or if simply the video rate is somehow higher that the input event rate.
+ * The HAL should be able to handle events with more than 1 video frame.
+ *
+ * The frames should be in chronological order, but it is not guaranteed that they will have
+ * monotonically increasing timestamps. Still, we provide consistent timestamps here since that
+ * is the most realistic mode of operation.
+ */
+TEST_F(InputClassifierHidlTest_1_0, Classify_TwoVideoFrames) {
+ MotionEvent event = getSimpleMotionEvent();
+ VideoFrame frame1;
+ frame1.data = {1, 2, 3, 4};
+ frame1.height = 2;
+ frame1.width = 2;
+ frame1.timestamp = event.eventTime;
+ VideoFrame frame2 = frame1;
+ frame2.data = {5, 5, 5, -1};
+ frame2.timestamp += 1;
+ event.frames = {frame1, frame2};
+
+ EXPECT_TRUE(classifier->classify(event).isOk());
+ // We are not checking the actual classification here,
+ // because the HAL operation is highly device-specific.
+
+ // Return HAL to a consistent state by doing a reset
+ classifier->reset();
+}
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(InputClassifierHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ InputClassifierHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/input/common/1.0/types.hal b/input/common/1.0/types.hal
index 1a07f3b..9ad368b 100644
--- a/input/common/1.0/types.hal
+++ b/input/common/1.0/types.hal
@@ -685,20 +685,20 @@
* Touch heatmap.
*
* The array is a 2-D row-major matrix with dimensions (height, width).
- * The heatmap data does not rotate when device orientation changes.
+ * The heatmap data is rotated when device orientation changes.
*
* Example:
*
* If the data in the array is:
* data[i] = i for i in 0 .. 59,
- * then it can be represented as follows:
+ * then it can be represented as a 10 x 6 matrix:
*
- * <-- width -- >
+ * <-- width -->
* 0 1 2 3 4 5 ^
* 6 7 8 9 10 11 |
- * 12 12 14 15 16 17 |
- * 18 ... 23 | height
- * 24 ... 29 |
+ * 12 13 14 15 16 17 |
+ * 18 ... 23 |
+ * 24 ... 29 | height
* 30 ... 35 |
* 36 ... 41 |
* 42 ... 47 |
@@ -708,16 +708,33 @@
* Looking at the device in standard portrait orientation,
* the element "0" is the top left of the screen,
* "5" is at the top right, and "59" is the bottom right.
- * Here width=6, and height=10.
+ * Here height=10 and width=6.
+ *
+ * If the screen orientation changes to landscape (a 90 degree orientation
+ * change), the frame's dimensions will become 6 x 10
+ * and the data will look as follows:
+ * 54 48 42 36 30 24 18 12 6 0 ^
+ * ... 13 7 1 |
+ * ... 14 8 2 | height
+ * ... 15 9 3 |
+ * ... 16 10 4 |
+ * 59 53 47 41 35 29 23 17 11 5 v
+ * <-- width -->
+ *
+ * Here the element "0" is at the physical top left of the unrotated screen.
+ *
+ * Since the coordinates of a MotionEvent are also adjusted based on the
+ * orientation, the rotation of the video frame data ensures that
+ * the axes for MotionEvent and VideoFrame data are consistent.
*/
struct VideoFrame {
/**
* Video frame data.
- * Size of the data is width * height.
+ * Size of the data is height * width.
*/
vec<int16_t> data;
- uint32_t width;
uint32_t height;
+ uint32_t width;
/**
* Time at which the frame was collected, in nanoseconds.
* Measured with the same clock that is used to populate MotionEvent times.
diff --git a/neuralnetworks/1.0/vts/functional/Android.bp b/neuralnetworks/1.0/vts/functional/Android.bp
index 52d6328..9057695 100644
--- a/neuralnetworks/1.0/vts/functional/Android.bp
+++ b/neuralnetworks/1.0/vts/functional/Android.bp
@@ -80,6 +80,7 @@
},
},
},
+ test_suites: ["general-tests"],
}
cc_test {
@@ -89,5 +90,16 @@
"BasicTests.cpp",
"GeneratedTests.cpp",
],
- test_suites: ["general-tests"],
+}
+
+cc_test {
+ name: "PresubmitHalNeuralnetworksV1_0TargetTest",
+ defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ srcs: [
+ "BasicTests.cpp",
+ "GeneratedTests.cpp",
+ ],
+ cflags: [
+ "-DPRESUBMIT_NOT_VTS",
+ ],
}
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 0724c09..7eea7fc 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -72,7 +72,8 @@
copy_back_(&dst->bool8Operands, ra, src);
copy_back_(&dst->quant8ChannelOperands, ra, src);
copy_back_(&dst->quant16AsymmOperands, ra, src);
- static_assert(8 == MixedTyped::kNumTypes,
+ copy_back_(&dst->quant8SymmOperands, ra, src);
+ static_assert(9 == MixedTyped::kNumTypes,
"Number of types in MixedTyped changed, but copy_back function wasn't updated");
}
diff --git a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
index 9ebc0aa..8883057 100644
--- a/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.0/vts/functional/VtsHalNeuralnetworks.cpp
@@ -49,7 +49,17 @@
void NeuralnetworksHidlTest::SetUp() {
::testing::VtsHalHidlTargetTestBase::SetUp();
device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
+ NeuralnetworksHidlEnvironment::getInstance());
+
+#ifdef PRESUBMIT_NOT_VTS
+ const std::string name =
+ NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
+ const std::string sampleDriver = "sample-";
+ if (device == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
+ GTEST_SKIP();
+ }
+#endif // PRESUBMIT_NOT_VTS
+
ASSERT_NE(nullptr, device.get());
}
diff --git a/neuralnetworks/1.1/vts/functional/Android.bp b/neuralnetworks/1.1/vts/functional/Android.bp
index 3f0c256..4fbeac9 100644
--- a/neuralnetworks/1.1/vts/functional/Android.bp
+++ b/neuralnetworks/1.1/vts/functional/Android.bp
@@ -21,7 +21,6 @@
srcs: [
"GeneratedTestsV1_0.cpp",
],
- test_suites: ["general-tests"],
}
// Tests for V1_1 models.
@@ -32,5 +31,16 @@
"BasicTests.cpp",
"GeneratedTests.cpp",
],
- test_suites: ["general-tests"],
+}
+
+cc_test {
+ name: "PresubmitHalNeuralnetworksV1_1TargetTest",
+ defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ srcs: [
+ "BasicTests.cpp",
+ "GeneratedTests.cpp",
+ ],
+ cflags: [
+ "-DPRESUBMIT_NOT_VTS",
+ ],
}
diff --git a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
index 4165953..224a51d 100644
--- a/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.1/vts/functional/VtsHalNeuralnetworks.cpp
@@ -49,7 +49,17 @@
void NeuralnetworksHidlTest::SetUp() {
::testing::VtsHalHidlTargetTestBase::SetUp();
device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
+ NeuralnetworksHidlEnvironment::getInstance());
+
+#ifdef PRESUBMIT_NOT_VTS
+ const std::string name =
+ NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
+ const std::string sampleDriver = "sample-";
+ if (device == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
+ GTEST_SKIP();
+ }
+#endif // PRESUBMIT_NOT_VTS
+
ASSERT_NE(nullptr, device.get());
}
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 06bdc6a..ab17598 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -342,7 +342,7 @@
* * * input.scale * filter.scale).
*
* Available since API level 29:
- * * Quantized with symetric per channel quantization for the filter:
+ * * Quantized with symmetric per channel quantization for the filter:
* * * {@link OperandType::TENSOR_QUANT8_ASYMM} for input, and output.
* * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter.
* * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0,
@@ -491,7 +491,7 @@
* * * input.scale * filter.scale).
*
* Available since API level 29:
- * * Quantized with symetric per channel quantization for the filter:
+ * * Quantized with symmetric per channel quantization for the filter:
* * * {@link OperandType::TENSOR_QUANT8_ASYMM} for input, and output.
* * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter.
* * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0,
@@ -3018,7 +3018,7 @@
* * * {@link OperandType::TENSOR_INT32} for bias (with scale set to
* * * input.scale * filter.scale).
*
- * * Quantized with symetric per channel quantization for the filter:
+ * * Quantized with symmetric per channel quantization for the filter:
* * * {@link OperandType::TENSOR_QUANT8_ASYMM} for input, and output.
* * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter.
* * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0,
@@ -4204,10 +4204,21 @@
* The output dimensions are functions of the filter dimensions, stride, and
* padding.
*
- * Supported tensor {@link OperandType}:
- * * {@link OperandType::TENSOR_FLOAT16}
- * * {@link OperandType::TENSOR_FLOAT32}
- * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * Supported tensor {@link OperandCode} configurations:
+ * * 32 bit Floating point :
+ * * * {@link OperandType::TENSOR_FLOAT32} for input, filter, output, and bias.
+ *
+ * * Quantized:
+ * * * {@link OperandType::TENSOR_QUANT8_ASYMM} for input, filter, and output.
+ * * * {@link OperandType::TENSOR_INT32} for bias (with scale set to
+ * * * input.scale * filter.scale).
+ *
+ * Available since API level 29:
+ * * Quantized with symmetric per channel quantization for the filter:
+ * * * {@link OperandType::TENSOR_QUANT8_ASYMM} for input, and output.
+ * * * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} for filter.
+ * * * {@link OperandType::TENSOR_INT32} for bias (scale set to 0.0,
+ * * * each value scaling is separate and equal to input.scale * filter.scales[channel]).
*
* Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
* With the default data layout NHWC, the data is stored in the order of:
@@ -4221,14 +4232,20 @@
* specifying the input.
* * 1: A 4-D tensor, of shape
* [depth_out, filter_height, filter_width, depth_in], specifying the
- * filter.
+ * filter. For tensor of type
+ * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} the channel
+ * dimension (extraParams.channelQuant.channelDim) must be set to 0.
* * 2: A 1-D tensor, of shape [depth_out], specifying the bias. For input
* tensor of type {@link OperandType::TENSOR_FLOAT32} or
* {@link OperandType::TENSOR_FLOAT16}, the bias should be of the
* same type. For input tensor of type
* {@link OperandType::TENSOR_QUANT8_ASYMM}, the bias should be
* of {@link OperandType::TENSOR_INT32}, with zeroPoint of 0 and
- * bias_scale == input_scale * filter_scale.
+ * bias_scale == input_scale * filter_scale. For filter tensor of
+ * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL}, the bias
+ * must be of {@link OperandType::TENSOR_INT32}, with zeroPoint of
+ * 0 and bias_scale of 0. The actual scale of each value 'i' is equal
+ * to bias_scale[i] = input_scale * filter_scale[i].
* * 3: An {@link OperandType::INT32} scalar, specifying the padding on
* the left, in the ‘width’ dimension.
* * 4: An {@link OperandType::INT32} scalar, specifying the padding on
@@ -4252,14 +4269,20 @@
* specifying the input.
* * 1: A 4-D tensor, of shape
* [depth_out, filter_height, filter_width, depth_in], specifying the
- * filter.
+ * filter. For tensor of type
+ * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL} the channel
+ * dimension (extraParams.channelQuant.channelDim) must be set to 0.
* * 2: A 1-D tensor, of shape [depth_out], specifying the bias. For input
* tensor of type {@link OperandType::TENSOR_FLOAT32} or
* {@link OperandType::TENSOR_FLOAT16}, the bias should be of the
* same type. For input tensor of type
* {@link OperandType::TENSOR_QUANT8_ASYMM}, the bias should be
* of {@link OperandType::TENSOR_INT32}, with zeroPoint of 0 and
- * bias_scale == input_scale * filter_scale.
+ * bias_scale == input_scale * filter_scale. For filter tensor of
+ * {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL}, the bias
+ * must be of {@link OperandType::TENSOR_INT32}, with zeroPoint of
+ * 0 and bias_scale of 0. The actual scale of each value 'i' is equal
+ * to bias_scale[i] = input_scale * filter_scale[i].
* * 3: An {@link OperandType::TENSOR_INT32} tensor, specifying the output
* tensor shape.
* * 4: An {@link OperandType::INT32} scalar, specifying the implicit
@@ -4279,7 +4302,9 @@
* * 0: The output 4-D tensor, of shape
* [batches, out_height, out_width, depth_out]. For output tensor of
* {@link OperandType::TENSOR_QUANT8_ASYMM}, the following condition
- * must be satisfied: output_scale > input_scale * filter_scale.
+ * must be satisfied: output_scale > input_scale * filter_scale (for
+ * filter tensor of {@link OperandType::TENSOR_QUANT8_SYMM_PER_CHANNEL}
+ * this condition must be true for all filter scales).
*
* Available since API level 29.
*/
diff --git a/neuralnetworks/1.2/vts/functional/Android.bp b/neuralnetworks/1.2/vts/functional/Android.bp
index 510a0d5..891b414 100644
--- a/neuralnetworks/1.2/vts/functional/Android.bp
+++ b/neuralnetworks/1.2/vts/functional/Android.bp
@@ -24,7 +24,6 @@
cflags: [
"-DNN_TEST_DYNAMIC_OUTPUT_SHAPE"
],
- test_suites: ["general-tests"],
}
// Tests for V1_1 models using the V1_2 HAL.
@@ -37,7 +36,6 @@
cflags: [
"-DNN_TEST_DYNAMIC_OUTPUT_SHAPE"
],
- test_suites: ["general-tests"],
}
// Tests for V1_2 models.
@@ -52,5 +50,17 @@
cflags: [
"-DNN_TEST_DYNAMIC_OUTPUT_SHAPE"
],
- test_suites: ["general-tests"],
+}
+
+cc_test {
+ name: "PresubmitHalNeuralnetworksV1_2TargetTest",
+ defaults: ["VtsHalNeuralNetworksTargetTestDefaults"],
+ srcs: [
+ "BasicTests.cpp",
+ "GeneratedTests.cpp",
+ ],
+ cflags: [
+ "-DNN_TEST_DYNAMIC_OUTPUT_SHAPE",
+ "-DPRESUBMIT_NOT_VTS",
+ ],
}
diff --git a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
index 34c73ef..4728c28 100644
--- a/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
+++ b/neuralnetworks/1.2/vts/functional/VtsHalNeuralnetworks.cpp
@@ -49,7 +49,17 @@
void NeuralnetworksHidlTest::SetUp() {
::testing::VtsHalHidlTargetTestBase::SetUp();
device = ::testing::VtsHalHidlTargetTestBase::getService<IDevice>(
- NeuralnetworksHidlEnvironment::getInstance());
+ NeuralnetworksHidlEnvironment::getInstance());
+
+#ifdef PRESUBMIT_NOT_VTS
+ const std::string name =
+ NeuralnetworksHidlEnvironment::getInstance()->getServiceName<IDevice>();
+ const std::string sampleDriver = "sample-";
+ if (device == nullptr && name.substr(0, sampleDriver.size()) == sampleDriver) {
+ GTEST_SKIP();
+ }
+#endif // PRESUBMIT_NOT_VTS
+
ASSERT_NE(nullptr, device.get());
}
diff --git a/neuralnetworks/TEST_MAPPING b/neuralnetworks/TEST_MAPPING
new file mode 100644
index 0000000..50b6c19
--- /dev/null
+++ b/neuralnetworks/TEST_MAPPING
@@ -0,0 +1,28 @@
+{
+ "presubmit": [
+ {
+ "name": "PresubmitHalNeuralnetworksV1_0TargetTest",
+ "options": [
+ {
+ "native-test-flag": "--hal_service_instance=android.hardware.neuralnetworks@1.0::IDevice/sample-all"
+ }
+ ]
+ },
+ {
+ "name": "PresubmitHalNeuralnetworksV1_1TargetTest",
+ "options": [
+ {
+ "native-test-flag": "--hal_service_instance=android.hardware.neuralnetworks@1.1::IDevice/sample-all"
+ }
+ ]
+ },
+ {
+ "name": "PresubmitHalNeuralnetworksV1_2TargetTest",
+ "options": [
+ {
+ "native-test-flag": "--hal_service_instance=android.hardware.neuralnetworks@1.2::IDevice/sample-all"
+ }
+ ]
+ }
+ ]
+}
diff --git a/power/stats/1.0/types.hal b/power/stats/1.0/types.hal
index 644224b..6051e3f 100644
--- a/power/stats/1.0/types.hal
+++ b/power/stats/1.0/types.hal
@@ -26,9 +26,9 @@
struct RailInfo {
/** Index corresponding to the rail */
uint32_t index;
- /** Name of the rail */
+ /** Name of the rail (opaque to the framework) */
string railName;
- /** Name of the subsystem to which this rail belongs */
+ /** Name of the subsystem to which this rail belongs (opaque to the framework) */
string subsysName;
/** Hardware sampling rate */
uint32_t samplingRate;
@@ -71,7 +71,7 @@
struct PowerEntityInfo {
/** Unique ID corresponding to the PowerEntity */
uint32_t powerEntityId;
- /** Name of the PowerEntity */
+ /** Name of the PowerEntity (opaque to the framework) */
string powerEntityName;
/** Type of the PowerEntity */
PowerEntityType type;
@@ -82,7 +82,7 @@
* ID corresponding to the state. Unique for a given PowerEntityStateSpace
*/
uint32_t powerEntityStateId;
- /** Name of the state */
+ /** Name of the state (opaque to the framework) */
string powerEntityStateName;
};
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index 8ef1f96..046f074 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -115,11 +115,13 @@
* PUK/PIN state of the subscription and the service state of the radio.
*
* Some countries or carriers require some emergency numbers that must be handled with normal
- * call routing or emergency routing. If the 'routing' field is specified as
- * @1.4::EmergencyNumberRouting#NORMAL, the implementation must use normal call routing to
- * handle the call; if it is specified as @1.4::EmergencyNumberRouting#EMERGENCY, the
- * implementation must use emergency routing to handle the call; if it is
- * @1.4::EmergencyNumberRouting#UNKNOWN, Android does not know how to handle the call.
+ * call routing if possible or emergency routing. 1) if the 'routing' field is specified as
+ * @1.4::EmergencyNumberRouting#NORMAL, the implementation must try the full radio service to
+ * use normal call routing to handle the call; if service cannot support normal routing, the
+ * implementation must use emergency routing to handle the call. 2) if 'routing' is specified
+ * as @1.4::EmergencyNumberRouting#EMERGENCY, the implementation must use emergency routing to
+ * handle the call. 3) if 'routing' is specified as @1.4::EmergencyNumberRouting#UNKNOWN,
+ * Android does not know how to handle the call.
*
* If the dialed emergency number does not have a specified emergency service category, the
* 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed
@@ -128,9 +130,11 @@
* does not support the emergency service category or emergency uniform resource names, the
* field 'categories' or 'urns' may be ignored.
*
- * 'fromEmergencyDialer' indicates if this request originated from emergency dialer/shortcut,
- * which means an explicit intent from the user to dial an emergency number. The modem must
- * treat this as an actual emergency dial and not try to disambiguate.
+ * In the scenarios that the 'address' in the 'dialInfo' field has other functions besides the
+ * emergency number function, if the 'hasKnownUserIntentEmergency' field is true, the user's
+ * intent for this dial request is emergency call, and the modem must treat this as an actual
+ * emergency dial; if the 'hasKnownUserIntentEmergency' field is false, Android does not know
+ * user's intent for this call.
*
* If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real
* emergency service; otherwise it's for a real emergency call request.
@@ -146,14 +150,15 @@
* of the call.
* @param urns the emergency Uniform Resource Names (URN)
* @param routing @1.4::EmergencyCallRouting the emergency call routing information.
- * @param fromEmergencyDialer Flag indicating if this request originated from emergency dialer.
+ * @param hasKnownUserIntentEmergency Flag indicating if user's intent for the emergency call
+ * is known.
* @param isTesting Flag indicating if this request is for testing purpose.
*
* Response function is IRadioResponse.emergencyDialResponse()
*/
oneway emergencyDial(int32_t serial, Dial dialInfo,
bitfield<EmergencyServiceCategory> categories, vec<string> urns,
- EmergencyCallRouting routing, bool fromEmergencyDialer, bool isTesting);
+ EmergencyCallRouting routing, bool hasKnownUserIntentEmergency, bool isTesting);
/**
* Starts a network scan
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
index 6b1f85e..52eb277 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.4/vts/functional/radio_hidl_hal_api.cpp
@@ -16,4 +16,480 @@
#include <radio_hidl_hal_utils_v1_4.h>
-#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
\ No newline at end of file
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+/*
+ * Test IRadio.emergencyDial() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, emergencyDial) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_0::Dial dialInfo;
+ dialInfo.address = hidl_string("911");
+ int categories = static_cast<int>(
+ ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
+ std::vector<hidl_string> urns = {""};
+ ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+ ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
+
+ Return<void> res =
+ radio_v1_4->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("emergencyDial, rspInfo.error = %s\n", toString(radioRsp_v1_4->rspInfo.error).c_str());
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+}
+
+/*
+ * Test IRadio.emergencyDial() with specified service and its response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, emergencyDial_withServices) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_0::Dial dialInfo;
+ dialInfo.address = hidl_string("911");
+ int categories =
+ static_cast<int>(::android::hardware::radio::V1_4::EmergencyServiceCategory::AMBULANCE);
+ std::vector<hidl_string> urns = {"urn:service:sos.ambulance"};
+ ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+ ::android::hardware::radio::V1_4::EmergencyCallRouting::UNKNOWN;
+
+ Return<void> res =
+ radio_v1_4->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("emergencyDial_withServices, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+}
+
+/*
+ * Test IRadio.emergencyDial() with known emergency call routing and its response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, emergencyDial_withEmergencyRouting) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_0::Dial dialInfo;
+ dialInfo.address = hidl_string("911");
+ int categories = static_cast<int>(
+ ::android::hardware::radio::V1_4::EmergencyServiceCategory::UNSPECIFIED);
+ std::vector<hidl_string> urns = {""};
+ ::android::hardware::radio::V1_4::EmergencyCallRouting routing =
+ ::android::hardware::radio::V1_4::EmergencyCallRouting::EMERGENCY;
+
+ Return<void> res =
+ radio_v1_4->emergencyDial(serial, dialInfo, categories, urns, routing, true, true);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("emergencyDial_withEmergencyRouting, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_4->rspInfo.error);
+}
+
+/*
+ * Test IRadio.startNetworkScan() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT, .interval = 60, .specifiers = {specifier}};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan, rspInfo.error = %s\n", toString(radioRsp_v1_4->rspInfo.error).c_str());
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ // OPERATION_NOT_ALLOWED should not be allowed; however, some vendors do not support the
+ // required manual GSM search functionality. This is tracked in b/112206766.
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::OPERATION_NOT_ALLOWED}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid specifier.
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidArgument) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {.type = ScanType::ONE_SHOT,
+ .interval = 60};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidArgument, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid interval (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 4,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidInterval1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid interval (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidInterval2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 301,
+ .specifiers = {specifier},
+ .maxSearchTime = 60,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidInterval2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid max search time (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 59,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidMaxSearchTime1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid max search time (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidMaxSearchTime2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 3601,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 1};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidMaxSearchTime2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid periodicity (lower boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 0};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidPeriodicity1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with invalid periodicity (upper boundary).
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_InvalidPeriodicity2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ .maxSearchTime = 600,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 11};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_InvalidPeriodicity2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::INVALID_ARGUMENTS}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(
+ CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error, {RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with valid periodicity
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest1) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ // Some vendor may not support max search time of 360s.
+ // This issue is tracked in b/112205669.
+ .maxSearchTime = 300,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_GoodRequest1, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+ }
+}
+
+/*
+ * Test IRadio.startNetworkScan() with valid periodicity and plmns
+ */
+TEST_F(RadioHidlTest_v1_4, startNetworkScan_GoodRequest2) {
+ serial = GetRandomSerialNumber();
+
+ RadioAccessSpecifier specifier = {.radioAccessNetwork = RadioAccessNetworks::GERAN,
+ .geranBands = {GeranBands::BAND_450, GeranBands::BAND_480},
+ .channels = {1, 2}};
+
+ ::android::hardware::radio::V1_2::NetworkScanRequest request = {
+ .type = ScanType::ONE_SHOT,
+ .interval = 60,
+ .specifiers = {specifier},
+ // Some vendor may not support max search time of 360s.
+ // This issue is tracked in b/112205669.
+ .maxSearchTime = 300,
+ .incrementalResults = false,
+ .incrementalResultsPeriodicity = 10,
+ .mccMncs = {"310410"}};
+
+ Return<void> res = radio_v1_4->startNetworkScan_1_4(serial, request);
+
+ ASSERT_OK(res);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ ALOGI("startNetworkScan_GoodRequest2, rspInfo.error = %s\n",
+ toString(radioRsp_v1_4->rspInfo.error).c_str());
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::SIM_ABSENT}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::INVALID_ARGUMENTS}));
+ }
+}
+/*
+ * Test IRadio.setupDataCall_1_4() for the response returned.
+ */
+TEST_F(RadioHidlTest_v1_4, setupDataCall_1_4) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_4::AccessNetwork accessNetwork =
+ ::android::hardware::radio::V1_4::AccessNetwork::EUTRAN;
+
+ android::hardware::radio::V1_4::DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileId::DEFAULT;
+ dataProfileInfo.apn = hidl_string("internet");
+ dataProfileInfo.protocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.roamingProtocol = PdpProtocolType::IPV4V6;
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = hidl_string("username");
+ dataProfileInfo.password = hidl_string("password");
+ dataProfileInfo.type = DataProfileInfoType::THREE_GPP;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtu = 0;
+ dataProfileInfo.preferred = true;
+ dataProfileInfo.persistent = false;
+
+ bool roamingAllowed = false;
+
+ ::android::hardware::radio::V1_2::DataRequestReason reason =
+ ::android::hardware::radio::V1_2::DataRequestReason::NORMAL;
+ std::vector<hidl_string> addresses = {""};
+ std::vector<hidl_string> dnses = {""};
+
+ Return<void> res = radio_v1_4->setupDataCall_1_4(serial, accessNetwork, dataProfileInfo,
+ roamingAllowed, reason, addresses, dnses);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_4->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_4->rspInfo.serial);
+
+ if (cardStatus.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ } else if (cardStatus.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_4->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ }
+}
diff --git a/thermal/2.0/IThermal.hal b/thermal/2.0/IThermal.hal
index f890694..3ea4590 100644
--- a/thermal/2.0/IThermal.hal
+++ b/thermal/2.0/IThermal.hal
@@ -56,22 +56,24 @@
* they go offline, if these devices exist on boot. The method
* always returns and never removes such temperatures. The thresholds
* are returned as static values and must not change across calls. The actual
- * throttling state is determined in driver and HAL and must not be simply
- * compared with these thresholds. To get accurate throttling status, use
- * getCurrentTemperatures or registerThermalChangedCallback and listen.
+ * throttling state is determined in device thermal mitigation policy/agorithm
+ * which might not be simple thresholds so these values Thermal HAL provided
+ * may not be accurate to detemin the throttling status. To get accurate
+ * throttling status, use getCurrentTemperatures or registerThermalChangedCallback
+ * and listen to the callback.
*/
getTemperatureThresholds(bool filterType, TemperatureType type)
generates (ThermalStatus status, vec<TemperatureThreshold> temperatureThresholds);
/**
* Register an IThermalChangedCallback, used by the Thermal HAL
- * to send thermal events when thermal mitigation status changed.
+ * to receive thermal events when thermal mitigation status changed.
* Multiple registrations with different IThermalChangedCallback must be allowed.
* Multiple registrations with same IThermalChangedCallback is not allowed, client
* should unregister the given IThermalChangedCallback first.
*
- * @param callback the IThermalChangedCallback to use for sending
- * thermal events (cannot be nullptr).
+ * @param callback the IThermalChangedCallback to use for receiving
+ * thermal events (nullptr callback will lead to failure with status code FAILURE).
* @param filterType if filter for given sensor type.
* @param type the type to be filtered.
*
@@ -84,11 +86,11 @@
generates (ThermalStatus status);
/**
- * Register an IThermalChangedCallback, used by the Thermal HAL
- * to send thermal events when thermal mitigation status changed.
+ * Unregister an IThermalChangedCallback, used by the Thermal HAL
+ * to receive thermal events when thermal mitigation status changed.
*
- * @param callback the IThermalChangedCallback to use for sending
- * thermal events, or nullptr to set no callback.
+ * @param callback the IThermalChangedCallback used for receiving
+ * thermal events (nullptr callback will lead to failure with status code FAILURE).
*
* @return status Status of the operation. If status code is FAILURE,
* the status.debugMessage must be populated with a human-readable error message.
diff --git a/thermal/2.0/default/Thermal.cpp b/thermal/2.0/default/Thermal.cpp
index 442af61..0ef4b63 100644
--- a/thermal/2.0/default/Thermal.cpp
+++ b/thermal/2.0/default/Thermal.cpp
@@ -155,7 +155,15 @@
bool filterType, TemperatureType type,
registerThermalChangedCallback_cb _hidl_cb) {
ThermalStatus status;
- status.code = ThermalStatusCode::SUCCESS;
+ if (callback == nullptr) {
+ status.code = ThermalStatusCode::FAILURE;
+ status.debugMessage = "Invalid nullptr callback";
+ LOG(ERROR) << status.debugMessage;
+ _hidl_cb(status);
+ return Void();
+ } else {
+ status.code = ThermalStatusCode::SUCCESS;
+ }
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
if (std::any_of(callbacks_.begin(), callbacks_.end(), [&](const CallbackSetting& c) {
return interfacesEqual(c.callback, callback);
@@ -175,7 +183,15 @@
Return<void> Thermal::unregisterThermalChangedCallback(
const sp<IThermalChangedCallback>& callback, unregisterThermalChangedCallback_cb _hidl_cb) {
ThermalStatus status;
- status.code = ThermalStatusCode::SUCCESS;
+ if (callback == nullptr) {
+ status.code = ThermalStatusCode::FAILURE;
+ status.debugMessage = "Invalid nullptr callback";
+ LOG(ERROR) << status.debugMessage;
+ _hidl_cb(status);
+ return Void();
+ } else {
+ status.code = ThermalStatusCode::SUCCESS;
+ }
bool removed = false;
std::lock_guard<std::mutex> _lock(thermal_callback_mutex_);
callbacks_.erase(
diff --git a/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp b/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
index 3893014..cc2f3df 100644
--- a/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
+++ b/thermal/2.0/vts/functional/VtsHalThermalV2_0TargetTest.cpp
@@ -132,8 +132,13 @@
TEST_F(ThermalHidlTest, RegisterThermalChangedCallbackTest) {
// Expect to fail with same callback
auto ret = mThermal->registerThermalChangedCallback(
- mThermalCallback, false, TemperatureType::SKIN,
- [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); });
+ mThermalCallback, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
+ ASSERT_TRUE(ret.isOk());
+ // Expect to fail with null callback
+ ret = mThermal->registerThermalChangedCallback(
+ nullptr, false, TemperatureType::SKIN,
+ [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); });
ASSERT_TRUE(ret.isOk());
sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback();
// Expect to succeed with different callback
@@ -141,11 +146,16 @@
localThermalCallback, false, TemperatureType::SKIN,
[](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
ASSERT_TRUE(ret.isOk());
- // Remove the local callback.
+ // Remove the local callback
ret = mThermal->unregisterThermalChangedCallback(
localThermalCallback,
[](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); });
ASSERT_TRUE(ret.isOk());
+ // Expect to fail with null callback
+ ret = mThermal->unregisterThermalChangedCallback(nullptr, [](ThermalStatus status) {
+ EXPECT_EQ(ThermalStatusCode::FAILURE, status.code);
+ });
+ ASSERT_TRUE(ret.isOk());
}
// Test Thermal->unregisterThermalChangedCallback.
diff --git a/wifi/supplicant/1.2/Android.bp b/wifi/supplicant/1.2/Android.bp
index addcc2a..a0fc2b1 100644
--- a/wifi/supplicant/1.2/Android.bp
+++ b/wifi/supplicant/1.2/Android.bp
@@ -24,7 +24,6 @@
"DppFailureCode",
"DppNetRole",
"DppProgressCode",
- "DppSuccessCode",
],
gen_java: true,
}
diff --git a/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.hal
index 5d5cccf..3eac398 100644
--- a/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.2/ISupplicantStaIfaceCallback.hal
@@ -37,7 +37,7 @@
/**
* Indicates DPP configuration sent success event (Configurator mode).
*/
- oneway onDppSuccess(DppSuccessCode code);
+ oneway onDppSuccessConfigSent();
/**
* Indicates a DPP progress event.
diff --git a/wifi/supplicant/1.2/types.hal b/wifi/supplicant/1.2/types.hal
index eaf2546..303af19 100644
--- a/wifi/supplicant/1.2/types.hal
+++ b/wifi/supplicant/1.2/types.hal
@@ -35,13 +35,6 @@
};
/**
- * DppSuccessCode: Success codes for DPP (Easy Connect)
- */
-enum DppSuccessCode : uint32_t {
- CONFIGURATION_SENT,
-};
-
-/**
* DppProgressCode: Progress codes for DPP (Easy Connect)
*/
enum DppProgressCode : uint32_t {
diff --git a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 4425281..2ff7751 100644
--- a/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.2/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -40,7 +40,6 @@
using ::android::hardware::wifi::supplicant::V1_2::DppFailureCode;
using ::android::hardware::wifi::supplicant::V1_2::DppNetRole;
using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode;
-using ::android::hardware::wifi::supplicant::V1_2::DppSuccessCode;
using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaIfaceCallback;
using ::android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork;
@@ -64,7 +63,7 @@
ANY_CALLBACK = -2,
INVALID = -1,
- EVENT_SUCCESS = 0,
+ EVENT_SUCCESS_CONFIG_SENT = 0,
EVENT_SUCCESS_CONFIG_RECEIVED,
EVENT_PROGRESS,
EVENT_FAILURE,
@@ -202,9 +201,7 @@
DppAkm /* securityAkm */) override {
return Void();
}
- Return<void> onDppSuccess(DppSuccessCode /* code */) override {
- return Void();
- }
+ Return<void> onDppSuccessConfigSent() override { return Void(); }
Return<void> onDppProgress(DppProgressCode /* code */) override {
return Void();
}
@@ -226,10 +223,10 @@
parent_.notify();
return Void();
}
- Return<void> onDppSuccess(DppSuccessCode code) override {
- parent_.code = (uint32_t)code;
- parent_.dppCallbackType =
- SupplicantStaIfaceHidlTest::DppCallbackType::EVENT_SUCCESS;
+ Return<void> onDppSuccessConfigSent() override {
+ parent_.code = 0;
+ parent_.dppCallbackType = SupplicantStaIfaceHidlTest::DppCallbackType::
+ EVENT_SUCCESS_CONFIG_SENT;
parent_.notify();
return Void();
}