Merge "Sync docs between NeuralNetworks.h and HAL file"
diff --git a/biometrics/face/1.0/IBiometricsFace.hal b/biometrics/face/1.0/IBiometricsFace.hal
index e3c256a..813f040 100644
--- a/biometrics/face/1.0/IBiometricsFace.hal
+++ b/biometrics/face/1.0/IBiometricsFace.hal
@@ -18,9 +18,6 @@
import IBiometricsFaceClientCallback;
-// TODO(b/78538290): Update comments with state machine transitions when ready.
-// TODO(b/78537981): Update comments with callback interaction contract.
-// TODO(b/79496983): Update comments with status returns fully enumerated.
/**
* The HAL interface for biometric face authentication.
*/
diff --git a/biometrics/face/1.0/types.hal b/biometrics/face/1.0/types.hal
index 89e809b..b5db966 100644
--- a/biometrics/face/1.0/types.hal
+++ b/biometrics/face/1.0/types.hal
@@ -297,7 +297,7 @@
* capture plane is too high.
*
* The tilt angle is defined as the angle swept out by the user’s face looking up
- * and down. The pan angle would be zero if the user faced the camera directly.
+ * and down. The tilt angle would be zero if the user faced the camera directly.
*
* The user should be informed to look more directly at the camera.
*/
@@ -308,8 +308,8 @@
* capture plane is too high.
*
* The roll angle is defined as the angle swept out by the user’s face tilting their head
- * towards their shoulders to the left and right. The pan angle would be zero if the user
- * faced the camera directly.
+ * towards their shoulders to the left and right. The roll angle would be zero if the user's
+ * head is vertically aligned with the camera.
*
* The user should be informed to look more directly at the camera.
*/
diff --git a/camera/common/1.0/default/Exif.cpp b/camera/common/1.0/default/Exif.cpp
index 6054999..4de05c5 100644
--- a/camera/common/1.0/default/Exif.cpp
+++ b/camera/common/1.0/default/Exif.cpp
@@ -18,7 +18,7 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
-#include <cutils/log.h>
+#include <android/log.h>
#include <inttypes.h>
#include <math.h>
diff --git a/camera/metadata/3.4/types.hal b/camera/metadata/3.4/types.hal
index 9bbc90d..a79fe53 100644
--- a/camera/metadata/3.4/types.hal
+++ b/camera/metadata/3.4/types.hal
@@ -111,6 +111,14 @@
* Enumeration definitions for the various entries that need them
*/
+/** android.request.availableCapabilities enumeration values added since v3.3
+ * @see ANDROID_REQUEST_AVAILABLE_CAPABILITIES
+ */
+enum CameraMetadataEnumAndroidRequestAvailableCapabilities :
+ @3.3::CameraMetadataEnumAndroidRequestAvailableCapabilities {
+ ANDROID_REQUEST_AVAILABLE_CAPABILITIES_SECURE_IMAGE_DATA,
+};
+
/** android.scaler.availableFormats enumeration values added since v3.2
* @see ANDROID_SCALER_AVAILABLE_FORMATS
*/
diff --git a/cas/1.1/Android.bp b/cas/1.1/Android.bp
new file mode 100644
index 0000000..bb0edb9
--- /dev/null
+++ b/cas/1.1/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.cas@1.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "ICas.hal",
+ "ICasListener.hal",
+ "IMediaCasService.hal",
+ ],
+ interfaces: [
+ "android.hardware.cas@1.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
+
diff --git a/cas/1.1/ICas.hal b/cas/1.1/ICas.hal
new file mode 100644
index 0000000..027968e
--- /dev/null
+++ b/cas/1.1/ICas.hal
@@ -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.
+ */
+package android.hardware.cas@1.1;
+
+import @1.0::HidlCasSessionId;
+import @1.0::ICas;
+import @1.0::Status;
+
+/**
+ * ICas is the API to control the cas system and is accessible from both
+ * Java and native level. It is used to manage sessions, provision/refresh
+ * the cas system, and process the EMM/ECM messages. It also allows bi-directional,
+ * scheme-specific communications between the client and the cas system.
+ */
+
+interface ICas extends @1.0::ICas {
+ /**
+ * Send an scheme-specific session event to the CasPlugin.
+ *
+ * @param sessionId the id of an opened session.
+ * @param event an integer denoting a scheme-specific event to be sent.
+ * @param arg a scheme-specific integer argument for the event.
+ * @param data a byte array containing scheme-specific data for the event.
+ * @return status the status of the call.
+ */
+ sendSessionEvent(HidlCasSessionId sessionId, int32_t event, int32_t arg,
+ vec<uint8_t> eventData)
+ generates (Status status);
+};
diff --git a/cas/1.1/ICasListener.hal b/cas/1.1/ICasListener.hal
new file mode 100644
index 0000000..5ec1154
--- /dev/null
+++ b/cas/1.1/ICasListener.hal
@@ -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.
+ */
+package android.hardware.cas@1.1;
+
+import @1.0::ICasListener;
+import @1.0::HidlCasSessionId;
+
+interface ICasListener extends @1.0::ICasListener{
+ /**
+ * Notify the listener of a scheme-specific session event from CA system.
+ *
+ * @param sessionId the id of an opened session.
+ * @param event an integer whose meaning is scheme-specific.
+ * @param arg an integer whose meaning is scheme-specific.
+ * @param data a byte array of data whose format and meaning are
+ * scheme-specific.
+ */
+ onSessionEvent(HidlCasSessionId sessionId, int32_t event, int32_t arg,
+ vec<uint8_t> data);
+};
diff --git a/cas/1.1/IMediaCasService.hal b/cas/1.1/IMediaCasService.hal
new file mode 100644
index 0000000..e82b54c
--- /dev/null
+++ b/cas/1.1/IMediaCasService.hal
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+package android.hardware.cas@1.1;
+
+import @1.1::ICas;
+import @1.1::ICasListener;
+import @1.0::IMediaCasService;
+
+/**
+ * IMediaCasService is the main entry point for interacting with a vendor's
+ * cas HAL to create cas and descrambler plugin instances. A cas plugin instance
+ * opens cas sessions which are used to obtain keys for a descrambler session,
+ * which can in turn be used to descramble protected video content.
+ */
+
+interface IMediaCasService extends @1.0::IMediaCasService {
+ /**
+ * Construct a new instance of a @1.1 ICAS CasPlugin given a CA_system_id.
+ *
+ * @param caSystemId the id of the CA system.
+ * @param listener the event listener to receive events coming from the CasPlugin.
+ * @return cas the newly created CasPlugin interface.
+ */
+ createPluginExt(int32_t caSystemId, ICasListener listener) generates (ICas cas);
+};
diff --git a/cas/1.1/default/Android.bp b/cas/1.1/default/Android.bp
new file mode 100644
index 0000000..68a49cf
--- /dev/null
+++ b/cas/1.1/default/Android.bp
@@ -0,0 +1,49 @@
+cc_defaults {
+ name: "cas_service_defaults@1.1",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "CasImpl.cpp",
+ "DescramblerImpl.cpp",
+ "MediaCasService.cpp",
+ "service.cpp",
+ "SharedLibrary.cpp",
+ "TypeConvert.cpp",
+ ],
+
+ compile_multilib: "32",
+
+ shared_libs: [
+ "android.hardware.cas@1.0",
+ "android.hardware.cas@1.1",
+ "android.hardware.cas.native@1.0",
+ "android.hidl.memory@1.0",
+ "libbinder",
+ "libhidlbase",
+ "libhidlmemory",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ ],
+ header_libs: [
+ "libstagefright_foundation_headers",
+ "media_plugin_headers",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.cas@1.1-service",
+ vintf_fragments: ["android.hardware.cas@1.1-service.xml"],
+ defaults: ["cas_service_defaults@1.1"],
+ init_rc: ["android.hardware.cas@1.1-service.rc"],
+}
+
+cc_binary {
+ name: "android.hardware.cas@1.1-service-lazy",
+ vintf_fragments: ["android.hardware.cas@1.1-service-lazy.xml"],
+ overrides: ["android.hardware.cas@1.1-service"],
+ defaults: ["cas_service_defaults@1.1"],
+ init_rc: ["android.hardware.cas@1.1-service-lazy.rc"],
+ cflags: ["-DLAZY_SERVICE"],
+}
diff --git a/cas/1.1/default/CasImpl.cpp b/cas/1.1/default/CasImpl.cpp
new file mode 100644
index 0000000..4cc6017
--- /dev/null
+++ b/cas/1.1/default/CasImpl.cpp
@@ -0,0 +1,222 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "android.hardware.cas@1.1-CasImpl"
+
+#include <android/hardware/cas/1.1/ICasListener.h>
+#include <media/cas/CasAPI.h>
+#include <utils/Log.h>
+
+#include "CasImpl.h"
+#include "SharedLibrary.h"
+#include "TypeConvert.h"
+
+namespace android {
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+CasImpl::CasImpl(const sp<ICasListener>& listener) : mListener(listener) {
+ ALOGV("CTOR");
+}
+
+CasImpl::~CasImpl() {
+ ALOGV("DTOR");
+ release();
+}
+
+// static
+void CasImpl::OnEvent(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size) {
+ if (appData == NULL) {
+ ALOGE("Invalid appData!");
+ return;
+ }
+ CasImpl* casImpl = static_cast<CasImpl*>(appData);
+ casImpl->onEvent(event, arg, data, size);
+}
+
+// static
+void CasImpl::CallBackExt(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size,
+ const CasSessionId* sessionId) {
+ if (appData == NULL) {
+ ALOGE("Invalid appData!");
+ return;
+ }
+ CasImpl* casImpl = static_cast<CasImpl*>(appData);
+ casImpl->onEvent(sessionId, event, arg, data, size);
+}
+
+void CasImpl::init(const sp<SharedLibrary>& library, CasPlugin* plugin) {
+ mLibrary = library;
+ std::shared_ptr<CasPlugin> holder(plugin);
+ std::atomic_store(&mPluginHolder, holder);
+}
+
+void CasImpl::onEvent(int32_t event, int32_t arg, uint8_t* data, size_t size) {
+ if (mListener == NULL) {
+ return;
+ }
+
+ HidlCasData eventData;
+ if (data != NULL) {
+ eventData.setToExternal(data, size);
+ }
+
+ mListener->onEvent(event, arg, eventData);
+}
+
+void CasImpl::onEvent(const CasSessionId* sessionId, int32_t event, int32_t arg, uint8_t* data,
+ size_t size) {
+ if (mListener == NULL) {
+ return;
+ }
+
+ HidlCasData eventData;
+ if (data != NULL) {
+ eventData.setToExternal(data, size);
+ }
+
+ if (sessionId != NULL) {
+ mListener->onSessionEvent(*sessionId, event, arg, eventData);
+ } else {
+ mListener->onEvent(event, arg, eventData);
+ }
+}
+
+Return<Status> CasImpl::setPrivateData(const HidlCasData& pvtData) {
+ ALOGV("%s", __FUNCTION__);
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+ return toStatus(holder->setPrivateData(pvtData));
+}
+
+Return<void> CasImpl::openSession(openSession_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+ CasSessionId sessionId;
+
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ status_t err = INVALID_OPERATION;
+ if (holder.get() != nullptr) {
+ err = holder->openSession(&sessionId);
+ holder.reset();
+ }
+
+ _hidl_cb(toStatus(err), sessionId);
+
+ return Void();
+}
+
+Return<Status> CasImpl::setSessionPrivateData(const HidlCasSessionId& sessionId,
+ const HidlCasData& pvtData) {
+ ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(sessionId).string());
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+ return toStatus(holder->setSessionPrivateData(sessionId, pvtData));
+}
+
+Return<Status> CasImpl::closeSession(const HidlCasSessionId& sessionId) {
+ ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(sessionId).string());
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+ return toStatus(holder->closeSession(sessionId));
+}
+
+Return<Status> CasImpl::processEcm(const HidlCasSessionId& sessionId, const HidlCasData& ecm) {
+ ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(sessionId).string());
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+
+ return toStatus(holder->processEcm(sessionId, ecm));
+}
+
+Return<Status> CasImpl::processEmm(const HidlCasData& emm) {
+ ALOGV("%s", __FUNCTION__);
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+
+ return toStatus(holder->processEmm(emm));
+}
+
+Return<Status> CasImpl::sendEvent(int32_t event, int32_t arg, const HidlCasData& eventData) {
+ ALOGV("%s", __FUNCTION__);
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+
+ status_t err = holder->sendEvent(event, arg, eventData);
+ return toStatus(err);
+}
+
+Return<Status> CasImpl::sendSessionEvent(const HidlCasSessionId& sessionId, int32_t event,
+ int32_t arg, const HidlCasData& eventData) {
+ ALOGV("%s", __FUNCTION__);
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+
+ status_t err = holder->sendSessionEvent(sessionId, event, arg, eventData);
+ return toStatus(err);
+}
+
+Return<Status> CasImpl::provision(const hidl_string& provisionString) {
+ ALOGV("%s: provisionString=%s", __FUNCTION__, provisionString.c_str());
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+
+ return toStatus(holder->provision(String8(provisionString.c_str())));
+}
+
+Return<Status> CasImpl::refreshEntitlements(int32_t refreshType, const HidlCasData& refreshData) {
+ ALOGV("%s", __FUNCTION__);
+ std::shared_ptr<CasPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+
+ status_t err = holder->refreshEntitlements(refreshType, refreshData);
+ return toStatus(err);
+}
+
+Return<Status> CasImpl::release() {
+ ALOGV("%s: plugin=%p", __FUNCTION__, mPluginHolder.get());
+
+ std::shared_ptr<CasPlugin> holder(nullptr);
+ std::atomic_store(&mPluginHolder, holder);
+
+ return Status::OK;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
diff --git a/cas/1.1/default/CasImpl.h b/cas/1.1/default/CasImpl.h
new file mode 100644
index 0000000..18aee9e
--- /dev/null
+++ b/cas/1.1/default/CasImpl.h
@@ -0,0 +1,98 @@
+/*
+ * 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_CAS_V1_1_CAS_IMPL_H_
+#define ANDROID_HARDWARE_CAS_V1_1_CAS_IMPL_H_
+
+#include <android/hardware/cas/1.1/ICas.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+struct CasPlugin;
+
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+struct ICasListener;
+namespace implementation {
+
+using ::android::hardware::cas::V1_0::HidlCasData;
+using ::android::hardware::cas::V1_0::HidlCasSessionId;
+using ::android::hardware::cas::V1_0::Status;
+
+class SharedLibrary;
+
+class CasImpl : public ICas {
+ public:
+ CasImpl(const sp<ICasListener>& listener);
+ virtual ~CasImpl();
+
+ static void OnEvent(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size);
+
+ static void CallBackExt(void* appData, int32_t event, int32_t arg, uint8_t* data, size_t size,
+ const CasSessionId* sessionId);
+
+ void init(const sp<SharedLibrary>& library, CasPlugin* plugin);
+ void onEvent(int32_t event, int32_t arg, uint8_t* data, size_t size);
+
+ void onEvent(const CasSessionId* sessionId, int32_t event, int32_t arg, uint8_t* data,
+ size_t size);
+
+ // ICas inherits
+
+ virtual Return<Status> setPrivateData(const HidlCasData& pvtData) override;
+
+ virtual Return<void> openSession(openSession_cb _hidl_cb) override;
+
+ virtual Return<Status> closeSession(const HidlCasSessionId& sessionId) override;
+
+ virtual Return<Status> setSessionPrivateData(const HidlCasSessionId& sessionId,
+ const HidlCasData& pvtData) override;
+
+ virtual Return<Status> processEcm(const HidlCasSessionId& sessionId,
+ const HidlCasData& ecm) override;
+
+ virtual Return<Status> processEmm(const HidlCasData& emm) override;
+
+ virtual Return<Status> sendEvent(int32_t event, int32_t arg,
+ const HidlCasData& eventData) override;
+
+ virtual Return<Status> sendSessionEvent(const HidlCasSessionId& sessionId, int32_t event,
+ int32_t arg, const HidlCasData& eventData) override;
+
+ virtual Return<Status> provision(const hidl_string& provisionString) override;
+
+ virtual Return<Status> refreshEntitlements(int32_t refreshType,
+ const HidlCasData& refreshData) override;
+
+ virtual Return<Status> release() override;
+
+ private:
+ struct PluginHolder;
+ sp<SharedLibrary> mLibrary;
+ std::shared_ptr<CasPlugin> mPluginHolder;
+ sp<ICasListener> mListener;
+
+ DISALLOW_EVIL_CONSTRUCTORS(CasImpl);
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CAS_V1_1_CAS_IMPL_H_
diff --git a/cas/1.1/default/DescramblerImpl.cpp b/cas/1.1/default/DescramblerImpl.cpp
new file mode 100644
index 0000000..36dc1a5
--- /dev/null
+++ b/cas/1.1/default/DescramblerImpl.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "android.hardware.cas@1.1-DescramblerImpl"
+
+#include <hidlmemory/mapping.h>
+#include <media/cas/DescramblerAPI.h>
+#include <media/hardware/CryptoAPI.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <utils/Log.h>
+
+#include "DescramblerImpl.h"
+#include "SharedLibrary.h"
+#include "TypeConvert.h"
+
+namespace android {
+using hidl::memory::V1_0::IMemory;
+
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+#define CHECK_SUBSAMPLE_DEF(type) \
+ static_assert(sizeof(SubSample) == sizeof(type::SubSample), "SubSample: size doesn't match"); \
+ static_assert(offsetof(SubSample, numBytesOfClearData) == \
+ offsetof(type::SubSample, mNumBytesOfClearData), \
+ "SubSample: numBytesOfClearData offset doesn't match"); \
+ static_assert(offsetof(SubSample, numBytesOfEncryptedData) == \
+ offsetof(type::SubSample, mNumBytesOfEncryptedData), \
+ "SubSample: numBytesOfEncryptedData offset doesn't match")
+
+CHECK_SUBSAMPLE_DEF(DescramblerPlugin);
+CHECK_SUBSAMPLE_DEF(CryptoPlugin);
+
+DescramblerImpl::DescramblerImpl(const sp<SharedLibrary>& library, DescramblerPlugin* plugin)
+ : mLibrary(library), mPluginHolder(plugin) {
+ ALOGV("CTOR: plugin=%p", mPluginHolder.get());
+}
+
+DescramblerImpl::~DescramblerImpl() {
+ ALOGV("DTOR: plugin=%p", mPluginHolder.get());
+ release();
+}
+
+Return<Status> DescramblerImpl::setMediaCasSession(const HidlCasSessionId& sessionId) {
+ ALOGV("%s: sessionId=%s", __FUNCTION__, sessionIdToString(sessionId).string());
+
+ std::shared_ptr<DescramblerPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return toStatus(INVALID_OPERATION);
+ }
+
+ return toStatus(holder->setMediaCasSession(sessionId));
+}
+
+Return<bool> DescramblerImpl::requiresSecureDecoderComponent(const hidl_string& mime) {
+ std::shared_ptr<DescramblerPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ return false;
+ }
+
+ return holder->requiresSecureDecoderComponent(String8(mime.c_str()));
+}
+
+static inline bool validateRangeForSize(uint64_t offset, uint64_t length, uint64_t size) {
+ return isInRange<uint64_t, uint64_t>(0, size, offset, length);
+}
+
+Return<void> DescramblerImpl::descramble(ScramblingControl scramblingControl,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& srcBuffer, uint64_t srcOffset,
+ const DestinationBuffer& dstBuffer, uint64_t dstOffset,
+ descramble_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ // hidl_memory's size is stored in uint64_t, but mapMemory's mmap will map
+ // size in size_t. If size is over SIZE_MAX, mapMemory mapMemory could succeed
+ // but the mapped memory's actual size will be smaller than the reported size.
+ if (srcBuffer.heapBase.size() > SIZE_MAX) {
+ ALOGE("Invalid hidl_memory size: %llu", srcBuffer.heapBase.size());
+ android_errorWriteLog(0x534e4554, "79376389");
+ _hidl_cb(toStatus(BAD_VALUE), 0, NULL);
+ return Void();
+ }
+
+ sp<IMemory> srcMem = mapMemory(srcBuffer.heapBase);
+
+ // Validate if the offset and size in the SharedBuffer is consistent with the
+ // mapped ashmem, since the offset and size is controlled by client.
+ if (srcMem == NULL) {
+ ALOGE("Failed to map src buffer.");
+ _hidl_cb(toStatus(BAD_VALUE), 0, NULL);
+ return Void();
+ }
+ if (!validateRangeForSize(srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize())) {
+ ALOGE("Invalid src buffer range: offset %llu, size %llu, srcMem size %llu",
+ srcBuffer.offset, srcBuffer.size, (uint64_t)srcMem->getSize());
+ android_errorWriteLog(0x534e4554, "67962232");
+ _hidl_cb(toStatus(BAD_VALUE), 0, NULL);
+ return Void();
+ }
+
+ // use 64-bit here to catch bad subsample size that might be overflowing.
+ uint64_t totalBytesInSubSamples = 0;
+ for (size_t i = 0; i < subSamples.size(); i++) {
+ totalBytesInSubSamples +=
+ (uint64_t)subSamples[i].numBytesOfClearData + subSamples[i].numBytesOfEncryptedData;
+ }
+ // Further validate if the specified srcOffset and requested total subsample size
+ // is consistent with the source shared buffer size.
+ if (!validateRangeForSize(srcOffset, totalBytesInSubSamples, srcBuffer.size)) {
+ ALOGE("Invalid srcOffset and subsample size: "
+ "srcOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu",
+ srcOffset, totalBytesInSubSamples, srcBuffer.size);
+ android_errorWriteLog(0x534e4554, "67962232");
+ _hidl_cb(toStatus(BAD_VALUE), 0, NULL);
+ return Void();
+ }
+
+ void* srcPtr = (uint8_t*)(void*)srcMem->getPointer() + srcBuffer.offset;
+ void* dstPtr = NULL;
+ if (dstBuffer.type == BufferType::SHARED_MEMORY) {
+ // When using shared memory, src buffer is also used as dst,
+ // we don't map it again here.
+ dstPtr = srcPtr;
+
+ // In this case the dst and src would be the same buffer, need to validate
+ // dstOffset against the buffer size too.
+ if (!validateRangeForSize(dstOffset, totalBytesInSubSamples, srcBuffer.size)) {
+ ALOGE("Invalid dstOffset and subsample size: "
+ "dstOffset %llu, totalBytesInSubSamples %llu, srcBuffer size %llu",
+ dstOffset, totalBytesInSubSamples, srcBuffer.size);
+ android_errorWriteLog(0x534e4554, "67962232");
+ _hidl_cb(toStatus(BAD_VALUE), 0, NULL);
+ return Void();
+ }
+ } else {
+ native_handle_t* handle =
+ const_cast<native_handle_t*>(dstBuffer.secureMemory.getNativeHandle());
+ dstPtr = static_cast<void*>(handle);
+ }
+
+ // Get a local copy of the shared_ptr for the plugin. Note that before
+ // calling the HIDL callback, this shared_ptr must be manually reset,
+ // since the client side could proceed as soon as the callback is called
+ // without waiting for this method to go out of scope.
+ std::shared_ptr<DescramblerPlugin> holder = std::atomic_load(&mPluginHolder);
+ if (holder.get() == nullptr) {
+ _hidl_cb(toStatus(INVALID_OPERATION), 0, NULL);
+ return Void();
+ }
+
+ // Casting hidl SubSample to DescramblerPlugin::SubSample, but need
+ // to ensure structs are actually idential
+
+ int32_t result =
+ holder->descramble(dstBuffer.type != BufferType::SHARED_MEMORY,
+ (DescramblerPlugin::ScramblingControl)scramblingControl,
+ subSamples.size(), (DescramblerPlugin::SubSample*)subSamples.data(),
+ srcPtr, srcOffset, dstPtr, dstOffset, NULL);
+
+ holder.reset();
+ _hidl_cb(toStatus(result >= 0 ? OK : result), result, NULL);
+ return Void();
+}
+
+Return<Status> DescramblerImpl::release() {
+ ALOGV("%s: plugin=%p", __FUNCTION__, mPluginHolder.get());
+
+ std::shared_ptr<DescramblerPlugin> holder(nullptr);
+ std::atomic_store(&mPluginHolder, holder);
+
+ return Status::OK;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
diff --git a/cas/1.1/default/DescramblerImpl.h b/cas/1.1/default/DescramblerImpl.h
new file mode 100644
index 0000000..a1f66ae
--- /dev/null
+++ b/cas/1.1/default/DescramblerImpl.h
@@ -0,0 +1,67 @@
+/*
+ * 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_CAS_V1_1_DESCRAMBLER_IMPL_H_
+#define ANDROID_HARDWARE_CAS_V1_1_DESCRAMBLER_IMPL_H_
+
+#include <android/hardware/cas/native/1.0/IDescrambler.h>
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+struct DescramblerPlugin;
+using namespace hardware::cas::native::V1_0;
+
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::cas::V1_0::HidlCasSessionId;
+using ::android::hardware::cas::V1_0::Status;
+
+class SharedLibrary;
+
+class DescramblerImpl : public IDescrambler {
+ public:
+ DescramblerImpl(const sp<SharedLibrary>& library, DescramblerPlugin* plugin);
+ virtual ~DescramblerImpl();
+
+ virtual Return<Status> setMediaCasSession(const HidlCasSessionId& sessionId) override;
+
+ virtual Return<bool> requiresSecureDecoderComponent(const hidl_string& mime) override;
+
+ virtual Return<void> descramble(ScramblingControl scramblingControl,
+ const hidl_vec<SubSample>& subSamples,
+ const SharedBuffer& srcBuffer, uint64_t srcOffset,
+ const DestinationBuffer& dstBuffer, uint64_t dstOffset,
+ descramble_cb _hidl_cb) override;
+
+ virtual Return<Status> release() override;
+
+ private:
+ sp<SharedLibrary> mLibrary;
+ std::shared_ptr<DescramblerPlugin> mPluginHolder;
+
+ DISALLOW_EVIL_CONSTRUCTORS(DescramblerImpl);
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CAS_V1_1_DESCRAMBLER_IMPL_H_
diff --git a/cas/1.1/default/FactoryLoader.h b/cas/1.1/default/FactoryLoader.h
new file mode 100644
index 0000000..c4a48e2
--- /dev/null
+++ b/cas/1.1/default/FactoryLoader.h
@@ -0,0 +1,217 @@
+/*
+ * 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_CAS_V1_1_FACTORY_LOADER_H_
+#define ANDROID_HARDWARE_CAS_V1_1_FACTORY_LOADER_H_
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <media/cas/CasAPI.h>
+#include <utils/KeyedVector.h>
+#include <utils/Mutex.h>
+#include "SharedLibrary.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::cas::V1_0::HidlCasPluginDescriptor;
+
+template <class T>
+class FactoryLoader {
+ public:
+ FactoryLoader(const char* name) : mFactory(NULL), mCreateFactoryFuncName(name) {}
+
+ virtual ~FactoryLoader() { closeFactory(); }
+
+ bool findFactoryForScheme(int32_t CA_system_id, sp<SharedLibrary>* library = NULL,
+ T** factory = NULL);
+
+ bool enumeratePlugins(vector<HidlCasPluginDescriptor>* results);
+
+ private:
+ typedef T* (*CreateFactoryFunc)();
+
+ Mutex mMapLock;
+ T* mFactory;
+ const char* mCreateFactoryFuncName;
+ sp<SharedLibrary> mLibrary;
+ KeyedVector<int32_t, String8> mCASystemIdToLibraryPathMap;
+ KeyedVector<String8, wp<SharedLibrary> > mLibraryPathToOpenLibraryMap;
+
+ bool loadFactoryForSchemeFromPath(const String8& path, int32_t CA_system_id,
+ sp<SharedLibrary>* library, T** factory);
+
+ bool queryPluginsFromPath(const String8& path, vector<HidlCasPluginDescriptor>* results);
+
+ bool openFactory(const String8& path);
+ void closeFactory();
+};
+
+template <class T>
+bool FactoryLoader<T>::findFactoryForScheme(int32_t CA_system_id, sp<SharedLibrary>* library,
+ T** factory) {
+ if (library != NULL) {
+ library->clear();
+ }
+ if (factory != NULL) {
+ *factory = NULL;
+ }
+
+ Mutex::Autolock autoLock(mMapLock);
+
+ // first check cache
+ ssize_t index = mCASystemIdToLibraryPathMap.indexOfKey(CA_system_id);
+ if (index >= 0) {
+ return loadFactoryForSchemeFromPath(mCASystemIdToLibraryPathMap[index], CA_system_id,
+ library, factory);
+ }
+
+ // no luck, have to search
+ String8 dirPath("/vendor/lib/mediacas");
+ DIR* pDir = opendir(dirPath.string());
+
+ if (pDir == NULL) {
+ ALOGE("Failed to open plugin directory %s", dirPath.string());
+ return false;
+ }
+
+ struct dirent* pEntry;
+ while ((pEntry = readdir(pDir))) {
+ String8 pluginPath = dirPath + "/" + pEntry->d_name;
+ if (pluginPath.getPathExtension() == ".so") {
+ if (loadFactoryForSchemeFromPath(pluginPath, CA_system_id, library, factory)) {
+ mCASystemIdToLibraryPathMap.add(CA_system_id, pluginPath);
+ closedir(pDir);
+
+ return true;
+ }
+ }
+ }
+
+ closedir(pDir);
+
+ ALOGE("Failed to find plugin");
+ return false;
+}
+
+template <class T>
+bool FactoryLoader<T>::enumeratePlugins(vector<HidlCasPluginDescriptor>* results) {
+ ALOGI("enumeratePlugins");
+
+ results->clear();
+
+ String8 dirPath("/vendor/lib/mediacas");
+ DIR* pDir = opendir(dirPath.string());
+
+ if (pDir == NULL) {
+ ALOGE("Failed to open plugin directory %s", dirPath.string());
+ return false;
+ }
+
+ Mutex::Autolock autoLock(mMapLock);
+
+ struct dirent* pEntry;
+ while ((pEntry = readdir(pDir))) {
+ String8 pluginPath = dirPath + "/" + pEntry->d_name;
+ if (pluginPath.getPathExtension() == ".so") {
+ queryPluginsFromPath(pluginPath, results);
+ }
+ }
+ return true;
+}
+
+template <class T>
+bool FactoryLoader<T>::loadFactoryForSchemeFromPath(const String8& path, int32_t CA_system_id,
+ sp<SharedLibrary>* library, T** factory) {
+ closeFactory();
+
+ if (!openFactory(path) || !mFactory->isSystemIdSupported(CA_system_id)) {
+ closeFactory();
+ return false;
+ }
+
+ if (library != NULL) {
+ *library = mLibrary;
+ }
+ if (factory != NULL) {
+ *factory = mFactory;
+ }
+ return true;
+}
+
+template <class T>
+bool FactoryLoader<T>::queryPluginsFromPath(const String8& path,
+ vector<HidlCasPluginDescriptor>* results) {
+ closeFactory();
+
+ vector<CasPluginDescriptor> descriptors;
+ if (!openFactory(path) || mFactory->queryPlugins(&descriptors) != OK) {
+ closeFactory();
+ return false;
+ }
+
+ for (auto it = descriptors.begin(); it != descriptors.end(); it++) {
+ results->push_back(
+ HidlCasPluginDescriptor{.caSystemId = it->CA_system_id, .name = it->name.c_str()});
+ }
+ return true;
+}
+
+template <class T>
+bool FactoryLoader<T>::openFactory(const String8& path) {
+ // get strong pointer to open shared library
+ ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
+ if (index >= 0) {
+ mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
+ } else {
+ index = mLibraryPathToOpenLibraryMap.add(path, NULL);
+ }
+
+ if (!mLibrary.get()) {
+ mLibrary = new SharedLibrary(path);
+ if (!*mLibrary) {
+ return false;
+ }
+
+ mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
+ }
+
+ CreateFactoryFunc createFactory = (CreateFactoryFunc)mLibrary->lookup(mCreateFactoryFuncName);
+ if (createFactory == NULL || (mFactory = createFactory()) == NULL) {
+ return false;
+ }
+ return true;
+}
+
+template <class T>
+void FactoryLoader<T>::closeFactory() {
+ delete mFactory;
+ mFactory = NULL;
+ mLibrary.clear();
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CAS_V1_1_FACTORY_LOADER_H_
diff --git a/cas/1.1/default/MediaCasService.cpp b/cas/1.1/default/MediaCasService.cpp
new file mode 100644
index 0000000..e2d3357
--- /dev/null
+++ b/cas/1.1/default/MediaCasService.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "android.hardware.cas@1.1-MediaCasService"
+
+#include <android/hardware/cas/1.1/ICasListener.h>
+#include <media/cas/CasAPI.h>
+#include <media/cas/DescramblerAPI.h>
+#include <utils/Log.h>
+
+#include "CasImpl.h"
+#include "DescramblerImpl.h"
+#include "MediaCasService.h"
+
+namespace android {
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+MediaCasService::MediaCasService()
+ : mCasLoader("createCasFactory"), mDescramblerLoader("createDescramblerFactory") {}
+
+MediaCasService::~MediaCasService() {}
+
+Return<void> MediaCasService::enumeratePlugins(enumeratePlugins_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ vector<HidlCasPluginDescriptor> results;
+ mCasLoader.enumeratePlugins(&results);
+
+ _hidl_cb(results);
+ return Void();
+}
+
+Return<bool> MediaCasService::isSystemIdSupported(int32_t CA_system_id) {
+ ALOGV("isSystemIdSupported: CA_system_id=%d", CA_system_id);
+
+ return mCasLoader.findFactoryForScheme(CA_system_id);
+}
+
+Return<sp<V1_0::ICas>> MediaCasService::createPlugin(int32_t /* CA_system_id */,
+ const sp<V1_0::ICasListener>& /* listener */) {
+ ALOGE("%s:Use createPluginExt to create plugin with cas@1.1", __FUNCTION__);
+
+ sp<V1_0::ICas> result;
+ /*
+ CasFactory *factory;
+ sp<SharedLibrary> library;
+ if (mCasLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
+ CasPlugin *plugin = NULL;
+ sp<CasImpl> casImpl = new CasImpl(listener);
+ if (factory->createPlugin(CA_system_id, casImpl.get(),
+ CasImpl::OnEvent, &plugin) == OK && plugin != NULL) {
+ casImpl->init(library, plugin);
+ result = casImpl;
+ }
+ }
+ */
+ return result;
+}
+
+Return<sp<ICas>> MediaCasService::createPluginExt(int32_t CA_system_id,
+ const sp<ICasListener>& listener) {
+ ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
+
+ sp<ICas> result;
+
+ CasFactory* factory;
+ sp<SharedLibrary> library;
+ if (mCasLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
+ CasPlugin* plugin = NULL;
+ sp<CasImpl> casImpl = new CasImpl(listener);
+ if (factory->createPlugin(CA_system_id, casImpl.get(), &CasImpl::CallBackExt, &plugin) ==
+ OK &&
+ plugin != NULL) {
+ casImpl->init(library, plugin);
+ result = casImpl;
+ }
+ }
+
+ return result;
+}
+
+Return<bool> MediaCasService::isDescramblerSupported(int32_t CA_system_id) {
+ ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
+
+ return mDescramblerLoader.findFactoryForScheme(CA_system_id);
+}
+
+Return<sp<IDescramblerBase>> MediaCasService::createDescrambler(int32_t CA_system_id) {
+ ALOGV("%s: CA_system_id=%d", __FUNCTION__, CA_system_id);
+
+ sp<IDescrambler> result;
+
+ DescramblerFactory* factory;
+ sp<SharedLibrary> library;
+ if (mDescramblerLoader.findFactoryForScheme(CA_system_id, &library, &factory)) {
+ DescramblerPlugin* plugin = NULL;
+ if (factory->createPlugin(CA_system_id, &plugin) == OK && plugin != NULL) {
+ result = new DescramblerImpl(library, plugin);
+ }
+ }
+
+ return result;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
diff --git a/cas/1.1/default/MediaCasService.h b/cas/1.1/default/MediaCasService.h
new file mode 100644
index 0000000..ec5a86d
--- /dev/null
+++ b/cas/1.1/default/MediaCasService.h
@@ -0,0 +1,66 @@
+/*
+ * 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_CAS_V1_1_MEDIA_CAS_SERVICE_H_
+#define ANDROID_HARDWARE_CAS_V1_1_MEDIA_CAS_SERVICE_H_
+
+#include <android/hardware/cas/1.1/IMediaCasService.h>
+
+#include "FactoryLoader.h"
+
+namespace android {
+struct CasFactory;
+struct DescramblerFactory;
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::cas::V1_0::HidlCasPluginDescriptor;
+using ::android::hardware::cas::V1_0::IDescramblerBase;
+
+class MediaCasService : public IMediaCasService {
+ public:
+ MediaCasService();
+
+ virtual Return<void> enumeratePlugins(enumeratePlugins_cb _hidl_cb) override;
+
+ virtual Return<bool> isSystemIdSupported(int32_t CA_system_id) override;
+
+ virtual Return<sp<V1_0::ICas>> createPlugin(int32_t CA_system_id,
+ const sp<V1_0::ICasListener>& listener) override;
+
+ virtual Return<sp<ICas>> createPluginExt(int32_t CA_system_id,
+ const sp<ICasListener>& listener) override;
+
+ virtual Return<bool> isDescramblerSupported(int32_t CA_system_id) override;
+
+ virtual Return<sp<IDescramblerBase>> createDescrambler(int32_t CA_system_id) override;
+
+ private:
+ FactoryLoader<CasFactory> mCasLoader;
+ FactoryLoader<DescramblerFactory> mDescramblerLoader;
+
+ virtual ~MediaCasService();
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CAS_V1_1_MEDIA_CAS_SERVICE_H_
diff --git a/cas/1.1/default/SharedLibrary.cpp b/cas/1.1/default/SharedLibrary.cpp
new file mode 100644
index 0000000..ffe4bb9
--- /dev/null
+++ b/cas/1.1/default/SharedLibrary.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "android.hardware.cas@1.1-SharedLibrary"
+
+#include "SharedLibrary.h"
+#include <dlfcn.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+SharedLibrary::SharedLibrary(const String8& path) {
+ mLibHandle = dlopen(path.string(), RTLD_NOW);
+}
+
+SharedLibrary::~SharedLibrary() {
+ if (mLibHandle != NULL) {
+ dlclose(mLibHandle);
+ mLibHandle = NULL;
+ }
+}
+
+bool SharedLibrary::operator!() const {
+ return mLibHandle == NULL;
+}
+
+void* SharedLibrary::lookup(const char* symbol) const {
+ if (!mLibHandle) {
+ return NULL;
+ }
+ // Clear last error before we load the symbol again,
+ // in case the caller didn't retrieve it.
+ (void)dlerror();
+ return dlsym(mLibHandle, symbol);
+}
+
+const char* SharedLibrary::lastError() const {
+ const char* error = dlerror();
+ return error ? error : "No errors or unknown error";
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
diff --git a/cas/1.1/default/SharedLibrary.h b/cas/1.1/default/SharedLibrary.h
new file mode 100644
index 0000000..f4d2ff6
--- /dev/null
+++ b/cas/1.1/default/SharedLibrary.h
@@ -0,0 +1,50 @@
+/*
+ * 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_CAS_V1_1_SHARED_LIBRARY_H_
+#define ANDROID_HARDWARE_CAS_V1_1_SHARED_LIBRARY_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+class SharedLibrary : public RefBase {
+ public:
+ explicit SharedLibrary(const String8& path);
+ ~SharedLibrary();
+
+ bool operator!() const;
+ void* lookup(const char* symbol) const;
+ const char* lastError() const;
+
+ private:
+ void* mLibHandle;
+ DISALLOW_EVIL_CONSTRUCTORS(SharedLibrary);
+};
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CAS_V1_1_SHARED_LIBRARY_H_
diff --git a/cas/1.1/default/TypeConvert.cpp b/cas/1.1/default/TypeConvert.cpp
new file mode 100644
index 0000000..09ef41a
--- /dev/null
+++ b/cas/1.1/default/TypeConvert.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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_NDEBUG 0
+#define LOG_TAG "android.hardware.cas@1.1-TypeConvert"
+
+#include "TypeConvert.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+Status toStatus(status_t legacyStatus) {
+ Status status;
+ switch (legacyStatus) {
+ case android::OK:
+ status = Status::OK;
+ break;
+ case android::ERROR_CAS_NO_LICENSE:
+ status = Status::ERROR_CAS_NO_LICENSE;
+ break;
+ case android::ERROR_CAS_LICENSE_EXPIRED:
+ status = Status::ERROR_CAS_LICENSE_EXPIRED;
+ break;
+ case android::ERROR_CAS_SESSION_NOT_OPENED:
+ status = Status::ERROR_CAS_SESSION_NOT_OPENED;
+ break;
+ case android::ERROR_CAS_CANNOT_HANDLE:
+ status = Status::ERROR_CAS_CANNOT_HANDLE;
+ break;
+ case android::ERROR_CAS_TAMPER_DETECTED:
+ status = Status::ERROR_CAS_INVALID_STATE;
+ break;
+ case android::BAD_VALUE:
+ status = Status::BAD_VALUE;
+ break;
+ case android::ERROR_CAS_NOT_PROVISIONED:
+ status = Status::ERROR_CAS_NOT_PROVISIONED;
+ break;
+ case android::ERROR_CAS_RESOURCE_BUSY:
+ status = Status::ERROR_CAS_RESOURCE_BUSY;
+ break;
+ case android::ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION:
+ status = Status::ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION;
+ break;
+ case android::ERROR_CAS_DEVICE_REVOKED:
+ status = Status::ERROR_CAS_DEVICE_REVOKED;
+ break;
+ case android::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED:
+ status = Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED;
+ break;
+ case android::ERROR_CAS_DECRYPT:
+ status = Status::ERROR_CAS_DECRYPT;
+ break;
+ default:
+ ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN", legacyStatus);
+ status = Status::ERROR_CAS_UNKNOWN;
+ break;
+ }
+ return status;
+}
+
+String8 sessionIdToString(const CasSessionId& sessionId) {
+ String8 result;
+ for (size_t i = 0; i < sessionId.size(); i++) {
+ result.appendFormat("%02x ", sessionId[i]);
+ }
+ if (result.isEmpty()) {
+ result.append("(null)");
+ }
+ return result;
+}
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
diff --git a/cas/1.1/default/TypeConvert.h b/cas/1.1/default/TypeConvert.h
new file mode 100644
index 0000000..c4a0119
--- /dev/null
+++ b/cas/1.1/default/TypeConvert.h
@@ -0,0 +1,43 @@
+/*
+ * 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_CAS_V1_1_TYPE_CONVERT_H
+#define ANDROID_HARDWARE_CAS_V1_1_TYPE_CONVERT_H
+
+#include <android/hardware/cas/1.0/types.h>
+#include <media/cas/CasAPI.h>
+#include <media/stagefright/MediaErrors.h>
+#include <utils/String8.h>
+
+namespace android {
+namespace hardware {
+namespace cas {
+namespace V1_1 {
+namespace implementation {
+
+using ::android::hardware::cas::V1_0::Status;
+
+Status toStatus(status_t legacyStatus);
+
+String8 sessionIdToString(const CasSessionId& sessionId);
+
+} // namespace implementation
+} // namespace V1_1
+} // namespace cas
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_CAS_V1_1_TYPE_CONVERT_H
diff --git a/cas/1.1/default/android.hardware.cas@1.1-service-lazy.rc b/cas/1.1/default/android.hardware.cas@1.1-service-lazy.rc
new file mode 100644
index 0000000..9227b6f
--- /dev/null
+++ b/cas/1.1/default/android.hardware.cas@1.1-service-lazy.rc
@@ -0,0 +1,9 @@
+service vendor.cas-hal-1-1 /vendor/bin/hw/android.hardware.cas@1.1-service-lazy
+ interface android.hardware.cas@1.1::IMediaCasService default
+ oneshot
+ disabled
+ class hal
+ user media
+ group mediadrm drmrpc
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
diff --git a/cas/1.1/default/android.hardware.cas@1.1-service-lazy.xml b/cas/1.1/default/android.hardware.cas@1.1-service-lazy.xml
new file mode 100644
index 0000000..c9f13ba
--- /dev/null
+++ b/cas/1.1/default/android.hardware.cas@1.1-service-lazy.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.cas</name>
+ <transport>hwbinder</transport>
+ <version>1.1</version>
+ <interface>
+ <name>IMediaCasService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/cas/1.1/default/android.hardware.cas@1.1-service.rc b/cas/1.1/default/android.hardware.cas@1.1-service.rc
new file mode 100644
index 0000000..4081fe1
--- /dev/null
+++ b/cas/1.1/default/android.hardware.cas@1.1-service.rc
@@ -0,0 +1,6 @@
+service vendor.cas-hal-1-1 /vendor/bin/hw/android.hardware.cas@1.1-service
+ class hal
+ user media
+ group mediadrm drmrpc
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
diff --git a/cas/1.1/default/android.hardware.cas@1.1-service.xml b/cas/1.1/default/android.hardware.cas@1.1-service.xml
new file mode 100644
index 0000000..c9f13ba
--- /dev/null
+++ b/cas/1.1/default/android.hardware.cas@1.1-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.cas</name>
+ <transport>hwbinder</transport>
+ <version>1.1</version>
+ <interface>
+ <name>IMediaCasService</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/cas/1.1/default/service.cpp b/cas/1.1/default/service.cpp
new file mode 100644
index 0000000..9625303
--- /dev/null
+++ b/cas/1.1/default/service.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2017 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_NDEBUG 0
+#ifdef LAZY_SERVICE
+#define LOG_TAG "android.hardware.cas@1.1-service-lazy"
+#else
+#define LOG_TAG "android.hardware.cas@1.1-service"
+#endif
+
+#include <binder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+#include "MediaCasService.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::LazyServiceRegistrar;
+using android::hardware::cas::V1_1::IMediaCasService;
+using android::hardware::cas::V1_1::implementation::MediaCasService;
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
+int main() {
+ configureRpcThreadpool(8, true /* callerWillJoin */);
+
+ // Setup hwbinder service
+ android::sp<IMediaCasService> service = new MediaCasService();
+ android::status_t status;
+ if (kLazyService) {
+ auto serviceRegistrar = std::make_shared<LazyServiceRegistrar>();
+ status = serviceRegistrar->registerService(service);
+ } else {
+ status = service->registerAsService();
+ }
+ LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering cas service: %d", status);
+
+ joinRpcThreadpool();
+ return 0;
+}
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 94ffe80..0540ef1 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -1,5 +1,5 @@
<compatibility-matrix version="1.0" type="framework" level="4">
- <hal format="hidl" optional="false">
+ <hal format="hidl" optional="true">
<name>android.hardware.atrace</name>
<version>1.0</version>
<interface>
@@ -121,7 +121,7 @@
</hal>
<hal format="hidl" optional="true">
<name>android.hardware.cas</name>
- <version>1.0</version>
+ <version>1.0-1</version>
<interface>
<name>IMediaCasService</name>
<instance>default</instance>
diff --git a/drm/1.2/IDrmPlugin.hal b/drm/1.2/IDrmPlugin.hal
index 3c21815..7d266f4 100644
--- a/drm/1.2/IDrmPlugin.hal
+++ b/drm/1.2/IDrmPlugin.hal
@@ -74,7 +74,7 @@
* @return status the status of the call. Must be one of OK on
* success, BAD_VALUE if the license is not found or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the
- * KeySetIds can't be returned.
+ * KeySetIds can't be removed.
*/
removeOfflineLicense(KeySetId keySetId) generates (@1.0::Status status);
diff --git a/gnss/1.0/default/GnssBatching.cpp b/gnss/1.0/default/GnssBatching.cpp
index 02b38cb..f2e2e45 100644
--- a/gnss/1.0/default/GnssBatching.cpp
+++ b/gnss/1.0/default/GnssBatching.cpp
@@ -20,7 +20,7 @@
#include <Gnss.h> // for wakelock consolidation
#include <GnssUtils.h>
-#include <cutils/log.h> // for ALOGE
+#include <android/log.h> // for ALOGE
#include <vector>
namespace android {
diff --git a/gnss/1.0/default/ThreadCreationWrapper.h b/gnss/1.0/default/ThreadCreationWrapper.h
index df0a9e4..f401ce2 100644
--- a/gnss/1.0/default/ThreadCreationWrapper.h
+++ b/gnss/1.0/default/ThreadCreationWrapper.h
@@ -17,9 +17,9 @@
#ifndef ANDROID_HARDWARE_GNSS_THREADCREATIONWRAPPER_H
#define ANDROID_HARDWARE_GNSS_THREADCREATIONWRAPPER_H
+#include <log/log.h>
#include <pthread.h>
#include <vector>
-#include <cutils/log.h>
typedef void (*threadEntryFunc)(void* ret);
diff --git a/gnss/2.0/IGnssMeasurementCallback.hal b/gnss/2.0/IGnssMeasurementCallback.hal
index 226934e..fc44465 100644
--- a/gnss/2.0/IGnssMeasurementCallback.hal
+++ b/gnss/2.0/IGnssMeasurementCallback.hal
@@ -23,48 +23,48 @@
interface IGnssMeasurementCallback extends @1.1::IGnssMeasurementCallback {
/**
* Enumeration of available values for the GNSS Measurement's code type. Similar to the
- * Attribute field described in Rinex 3.03, e.g., in Tables 4-10, and Table A2 at the Rinex 3.03
+ * Attribute field described in RINEX 3.03, e.g., in Tables 4-10, and Table A2 at the RINEX 3.03
* Update 1 Document.
*/
enum GnssMeasurementCodeType : uint8_t {
/** GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA. */
- CODE_TYPE_A = 0,
+ A = 0,
/** GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB. */
- CODE_TYPE_B = 1,
+ B = 1,
/**
* GPS L1 C/A, GPS L2 C/A, GLONASS G1 C/A, GLONASS G2 C/A, GALILEO E1C, GALILEO E6C, SBAS
* L1 C/A, QZSS L1 C/A, IRNSS L5C.
*/
- CODE_TYPE_C = 2,
+ C = 2,
/**
* GPS L5 I, GLONASS G3 I, GALILEO E5a I, GALILEO E5b I, GALILEO E5a+b I, SBAS L5 I, QZSS L5
* I, BDS B1 I, BDS B2 I, BDS B3 I.
*/
- CODE_TYPE_I = 3,
+ I = 3,
/** GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L), LEX(6) L. */
- CODE_TYPE_L = 4,
+ L = 4,
/** GPS L1M, GPS L2M. */
- CODE_TYPE_M = 5,
+ M = 5,
/** GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P. */
- CODE_TYPE_P = 6,
+ P = 6,
/**
* GPS L5 Q, GLONASS G3 Q, GALILEO E5a Q, GALILEO E5b Q, GALILEO E5a+b Q, SBAS L5 Q, QZSS L5
* Q, BDS B1 Q, BDS B2 Q, BDS B3 Q.
*/
- CODE_TYPE_Q = 7,
+ Q = 7,
/** GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M), LEX(6) S. */
- CODE_TYPE_S = 8,
+ S = 8,
/** GPS L1 Z-tracking, GPS L2 Z-tracking. */
- CODE_TYPE_W = 9,
+ W = 9,
/**
* GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), GLONASS G3 (I+Q), GALILEO E1 (B+C), GALILEO
@@ -72,16 +72,366 @@
* L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q), LEX(6) (S+L), BDS B1 (I+Q), BDS B2 (I+Q), BDS
* B3 (I+Q), IRNSS L5 (B+C).
*/
- CODE_TYPE_X = 10,
+ X = 10,
/** GPS L1Y, GPS L2Y. */
- CODE_TYPE_Y = 11,
+ Y = 11,
/** GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF. */
- CODE_TYPE_Z = 12,
+ Z = 12,
/** GPS L1 codeless, GPS L2 codeless. */
- CODE_TYPE_CODELESS = 13
+ N = 13,
+
+ /**
+ * Other code type that does not belong to any of the above code types.
+ *
+ * This code type is used in the case that the above code types do not cover all the code
+ * types introduced in a new version of RINEX standard. When this code type is set, the
+ * field GnssMeasurement.otherCodeTypeName must specify the new code type.
+ */
+ OTHER = 255
+ };
+
+ /**
+ * Flags indicating the GNSS measurement state.
+ *
+ * <p>The expected behavior here is for GNSS HAL to set all the flags that apply. For example,
+ * if the state for a satellite is only C/A code locked and bit synchronized, and there is still
+ * millisecond ambiguity, the state must be set as:
+ *
+ * STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_MSEC_AMBIGUOUS
+ *
+ * <p>If GNSS is still searching for a satellite, the corresponding state must be set to
+ * STATE_UNKNOWN(0).
+ *
+ * <p>In @2.0::IGnssMeasurementCallback.GnssMeasurement, v1_1.v1_0.receivedSvTimeInNs, the
+ * received satellite time, is relative to the beginning of the system week for all
+ * constellations except for Glonass where it is relative to the beginning of the Glonass system
+ * day.
+ *
+ * <p>The table below indicates the valid range of the received GNSS satellite time. These
+ * ranges depend on the constellation and code being tracked and the state of the tracking
+ * algorithms given by the getState method. If the state flag is set, then the valid measurement
+ * range is zero to the value in the table. The state flag with the widest range indicates the
+ * range of the received GNSS satellite time value.
+ *
+ * <table>
+ * <thead>
+ * <tr>
+ * <td />
+ * <td colspan="3"><strong>GPS/QZSS</strong></td>
+ * <td><strong>GLNS</strong></td>
+ * <td colspan="2"><strong>BDS</strong></td>
+ * <td colspan="3"><strong>GAL</strong></td>
+ * <td><strong>SBAS</strong></td>
+ * </tr>
+ * <tr>
+ * <td><strong>State Flag</strong></td>
+ * <td><strong>L1 C/A</strong></td>
+ * <td><strong>L5I</strong></td>
+ * <td><strong>L5Q</strong></td>
+ * <td><strong>L1OF</strong></td>
+ * <td><strong>B1I (D1)</strong></td>
+ * <td><strong>B1I (D2)</strong></td>
+ * <td><strong>E1B</strong></td>
+ * <td><strong>E1C</strong></td>
+ * <td><strong>E5AQ</strong></td>
+ * <td><strong>L1 C/A</strong></td>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>
+ * <strong>STATE_UNKNOWN</strong>
+ * </td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * <td>0</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_CODE_LOCK</strong>
+ * </td>
+ * <td>1 ms</td>
+ * <td>1 ms</td>
+ * <td>1 ms</td>
+ * <td>1 ms</td>
+ * <td>1 ms</td>
+ * <td>1 ms</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>1 ms</td>
+ * <td>1 ms</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_SYMBOL_SYNC</strong>
+ * </td>
+ * <td>20 ms (optional)</td>
+ * <td>10 ms</td>
+ * <td>1 ms (optional)</td>
+ * <td>10 ms</td>
+ * <td>20 ms (optional)</td>
+ * <td>2 ms</td>
+ * <td>4 ms (optional)</td>
+ * <td>4 ms (optional)</td>
+ * <td>1 ms (optional)</td>
+ * <td>2 ms</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_BIT_SYNC</strong>
+ * </td>
+ * <td>20 ms</td>
+ * <td>20 ms</td>
+ * <td>1 ms (optional)</td>
+ * <td>20 ms</td>
+ * <td>20 ms</td>
+ * <td>-</td>
+ * <td>8 ms</td>
+ * <td>-</td>
+ * <td>1 ms (optional)</td>
+ * <td>4 ms</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_SUBFRAME_SYNC</strong>
+ * </td>
+ * <td>6s</td>
+ * <td>6s</td>
+ * <td>-</td>
+ * <td>2 s</td>
+ * <td>6 s</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>100 ms</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_TOW_DECODED</strong>
+ * </td>
+ * <td colspan="2">1 week</td>
+ * <td>-</td>
+ * <td>1 day</td>
+ * <td colspan="2">1 week</td>
+ * <td colspan="2">1 week</td>
+ * <td>-</td>
+ * <td>1 week</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_TOW_KNOWN</strong>
+ * </td>
+ * <td colspan="3">1 week</td>
+ * <td>1 day</td>
+ * <td colspan="2">1 week</td>
+ * <td colspan="3">1 week</td>
+ * <td>1 week</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_GLO_STRING_SYNC</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>2 s</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_GLO_TOD_DECODED</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>1 day</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_GLO_TOD_KNOWN</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>1 day</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_BDS_D2_BIT_SYNC</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>2 ms</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_BDS_D2_SUBFRAME_SYNC</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>600 ms</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_GAL_E1BC_CODE_LOCK</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>4 ms</td>
+ * <td>4 ms</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_GAL_E1C_2ND_CODE_LOCK</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>100 ms</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_2ND_CODE_LOCK</strong>
+ * </td>
+ * <td>-</td>
+ * <td>10 ms (optional)</td>
+ * <td>20 ms</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>100 ms (optional)</td>
+ * <td>100 ms</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_GAL_E1B_PAGE_SYNC</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>2 s</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * </tr>
+ * <tr>
+ * <td>
+ * <strong>STATE_SBAS_SYNC</strong>
+ * </td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>1 s</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ *
+ * <p>Note: TOW Known refers to the case where TOW is possibly not decoded over the air but has
+ * been determined from other sources. If TOW decoded is set then TOW Known must also be set.
+ *
+ * <p>Note well: if there is any ambiguity in integer millisecond, STATE_MSEC_AMBIGUOUS must be
+ * set accordingly, in the 'state' field. This value must be populated if 'state' !=
+ * STATE_UNKNOWN.
+ *
+ * <p>Note on optional flags:
+ * <ul>
+ * <li> For L1 C/A and B1I, STATE_SYMBOL_SYNC is optional since the symbol length is the
+ * same as the bit length.
+ * <li> For L5Q and E5aQ, STATE_BIT_SYNC and STATE_SYMBOL_SYNC are optional since they are
+ * implied by STATE_CODE_LOCK.
+ * <li> STATE_2ND_CODE_LOCK for L5I is optional since it is implied by STATE_SYMBOL_SYNC.
+ * <li> STATE_2ND_CODE_LOCK for E1C is optional since it is implied by
+ * STATE_GAL_E1C_2ND_CODE_LOCK.
+ * <li> For E1B and E1C, STATE_SYMBOL_SYNC is optional, because it is implied by
+ * STATE_GAL_E1BC_CODE_LOCK.
+ * </ul>
+ *
+ */
+ @export(name="", value_prefix="GNSS_MEASUREMENT_")
+ enum GnssMeasurementState : uint32_t {
+ STATE_UNKNOWN = 0,
+ STATE_CODE_LOCK = 1 << 0,
+ STATE_BIT_SYNC = 1 << 1,
+ STATE_SUBFRAME_SYNC = 1 << 2,
+ STATE_TOW_DECODED = 1 << 3,
+ STATE_MSEC_AMBIGUOUS = 1 << 4,
+ STATE_SYMBOL_SYNC = 1 << 5,
+ STATE_GLO_STRING_SYNC = 1 << 6,
+ STATE_GLO_TOD_DECODED = 1 << 7,
+ STATE_BDS_D2_BIT_SYNC = 1 << 8,
+ STATE_BDS_D2_SUBFRAME_SYNC = 1 << 9,
+ STATE_GAL_E1BC_CODE_LOCK = 1 << 10,
+ STATE_GAL_E1C_2ND_CODE_LOCK = 1 << 11,
+ STATE_GAL_E1B_PAGE_SYNC = 1 << 12,
+ STATE_SBAS_SYNC = 1 << 13,
+ STATE_TOW_KNOWN = 1 << 14,
+ STATE_GLO_TOD_KNOWN = 1 << 15,
+ STATE_2ND_CODE_LOCK = 1 << 16,
};
/**
@@ -96,6 +446,10 @@
* quarter cycle offset as they do when transmitted from the satellites. If the measurement
* is from a combination of the in-phase and quadrature phase components, then the alignment
* of the phase measurement will be aligned to the in-phase component.
+ *
+ * In this version of the HAL, the field 'state' in the v1_1.v1_0 struct is deprecated, and
+ * is no longer used by the framework. The satellite sync state is instead reported in
+ * @2.0::IGnssMeasurementCallback.GnssMeasurement.state.
*/
@1.1::IGnssMeasurementCallback.GnssMeasurement v1_1;
@@ -106,6 +460,27 @@
* in-order to properly apply code specific corrections to the psuedorange measurements.
*/
GnssMeasurementCodeType codeType;
+
+ /**
+ * The name of the code type when codeType is OTHER.
+ *
+ * This is used to specify the observation descriptor defined in GNSS Observation Data File
+ * Header Section Description in the RINEX standard (Version 3.XX). In RINEX Version 3.03,
+ * in Appendix Table A2 Attributes are listed as uppercase letters (for instance, "A" for
+ * "A channel"). In the future, if for instance a code "G" was added in the official RINEX
+ * standard, "G" could be specified here.
+ */
+ string otherCodeTypeName;
+
+ /**
+ * Per satellite sync state. It represents the current sync state for the associated
+ * satellite.
+ *
+ * Based on the sync state, the receivedSvTimeInNs field must be interpreted accordingly.
+ *
+ * This value is mandatory.
+ */
+ bitfield<GnssMeasurementState> state;
};
/**
diff --git a/gnss/2.0/default/GnssMeasurement.cpp b/gnss/2.0/default/GnssMeasurement.cpp
index dc23db3..0f707b4 100644
--- a/gnss/2.0/default/GnssMeasurement.cpp
+++ b/gnss/2.0/default/GnssMeasurement.cpp
@@ -26,7 +26,7 @@
using GnssConstellationType = V1_0::GnssConstellationType;
using GnssMeasurementFlags = V1_0::IGnssMeasurementCallback::GnssMeasurementFlags;
-using GnssMeasurementState = V1_0::IGnssMeasurementCallback::GnssMeasurementState;
+using GnssMeasurementState = V2_0::IGnssMeasurementCallback::GnssMeasurementState;
sp<V2_0::IGnssMeasurementCallback> GnssMeasurement::sCallback = nullptr;
@@ -97,11 +97,6 @@
.svid = (int16_t)6,
.constellation = GnssConstellationType::GLONASS,
.timeOffsetNs = 0.0,
- .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC |
- GnssMeasurementState::STATE_SUBFRAME_SYNC |
- GnssMeasurementState::STATE_TOW_DECODED |
- GnssMeasurementState::STATE_GLO_STRING_SYNC |
- GnssMeasurementState::STATE_GLO_TOD_DECODED,
.receivedSvTimeInNs = 8195997131077,
.receivedSvTimeUncertaintyInNs = 15,
.cN0DbHz = 30.0,
@@ -116,8 +111,14 @@
V1_0::IGnssMeasurementCallback::GnssMultipathIndicator::INDICATOR_UNKNOWN};
V1_1::IGnssMeasurementCallback::GnssMeasurement measurement_1_1 = {.v1_0 = measurement_1_0};
V2_0::IGnssMeasurementCallback::GnssMeasurement measurement_2_0 = {
- .v1_1 = measurement_1_1,
- .codeType = IGnssMeasurementCallback::GnssMeasurementCodeType::CODE_TYPE_C};
+ .v1_1 = measurement_1_1,
+ .codeType = IGnssMeasurementCallback::GnssMeasurementCodeType::C,
+ .otherCodeTypeName = "",
+ .state = GnssMeasurementState::STATE_CODE_LOCK | GnssMeasurementState::STATE_BIT_SYNC |
+ GnssMeasurementState::STATE_SUBFRAME_SYNC |
+ GnssMeasurementState::STATE_TOW_DECODED |
+ GnssMeasurementState::STATE_GLO_STRING_SYNC |
+ GnssMeasurementState::STATE_GLO_TOD_DECODED};
hidl_vec<IGnssMeasurementCallback::GnssMeasurement> measurements(1);
measurements[0] = measurement_2_0;
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 552cf1b..48f2be8 100644
--- a/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
+++ b/gnss/2.0/vts/functional/gnss_hal_test_cases.cpp
@@ -185,10 +185,16 @@
ASSERT_TRUE(last_measurement_.measurements.size() > 0);
for (auto measurement : last_measurement_.measurements) {
ASSERT_TRUE(
- (int)measurement.codeType >=
- (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::CODE_TYPE_A &&
- (int)measurement.codeType <=
- (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::CODE_TYPE_CODELESS);
+ ((int)measurement.codeType >=
+ (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::A &&
+ (int)measurement.codeType <=
+ (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::N) ||
+ (int)measurement.codeType ==
+ (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::OTHER);
+ if ((int)measurement.codeType ==
+ (int)IGnssMeasurementCallback_2_0::GnssMeasurementCodeType::OTHER) {
+ ASSERT_NE(measurement.otherCodeTypeName, "");
+ }
}
iGnssMeasurement->close();
diff --git a/keymaster/3.0/default/KeymasterDevice.cpp b/keymaster/3.0/default/KeymasterDevice.cpp
index 6fabbde..7d3e6f2 100644
--- a/keymaster/3.0/default/KeymasterDevice.cpp
+++ b/keymaster/3.0/default/KeymasterDevice.cpp
@@ -19,7 +19,7 @@
#include "KeymasterDevice.h"
-#include <cutils/log.h>
+#include <log/log.h>
#include <AndroidKeymaster3Device.h>
#include <hardware/keymaster0.h>
diff --git a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
index 2e13854..0724c09 100644
--- a/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
+++ b/neuralnetworks/1.0/vts/functional/GeneratedTestHarness.cpp
@@ -548,7 +548,7 @@
std::cout << "[ ] Early termination of test because vendor service cannot "
"prepare model that it does not support."
<< std::endl;
- GTEST_SKIP();
+ return;
}
EXPECT_EQ(ErrorStatus::NONE, prepareReturnStatus);
ASSERT_NE(nullptr, preparedModel->get());
@@ -561,6 +561,9 @@
V1_2::Model model = create_model();
sp<V1_2::IPreparedModel> preparedModel = nullptr;
PrepareModel(device, model, &preparedModel);
+ if (preparedModel == nullptr) {
+ GTEST_SKIP();
+ }
EvaluatePreparedModel(preparedModel, is_ignored, examples,
model.relaxComputationFloat32toFloat16, testDynamicOutputShape);
}
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 3eda14f..3bddbe8 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -4718,7 +4718,7 @@
* {@link OperationTypeRange::BASE_MAX} respectively should be interpreted
* as an extension operand. The low
* {@link Model::ExtensionTypeEncoding::LOW_BITS_TYPE} bits of the value
- * correspond to the value within the extension and the high
+ * correspond to the type ID within the extension and the high
* {@link Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX} bits encode
* the "prefix", which maps uniquely to the extension name.
*
diff --git a/radio/1.4/Android.bp b/radio/1.4/Android.bp
index 9fd0374..e8b8777 100644
--- a/radio/1.4/Android.bp
+++ b/radio/1.4/Android.bp
@@ -25,8 +25,10 @@
"CardStatus",
"CarrierRestrictionsWithPriority",
"CellConfigLte",
+ "CellIdentityNr",
"CellInfo",
"CellInfoLte",
+ "CellInfoNr",
"DataCallFailCause",
"DataConnActiveStatus",
"DataProfileInfo",
@@ -39,6 +41,7 @@
"LteVopsInfo",
"NetworkScanResult",
"NrIndicators",
+ "NrSignalStrength",
"PdpProtocolType",
"PhysicalChannelConfig",
"RadioAccessFamily",
@@ -46,6 +49,7 @@
"RadioFrequencyInfo",
"RadioTechnology",
"SetupDataCallResult",
+ "SignalStrength",
"SimLockMultiSimPolicy",
],
gen_java: true,
diff --git a/radio/1.4/IRadio.hal b/radio/1.4/IRadio.hal
index 21c5097..8ef1f96 100644
--- a/radio/1.4/IRadio.hal
+++ b/radio/1.4/IRadio.hal
@@ -215,4 +215,13 @@
* Response callback is IRadioResponse.getAllowedCarriersResponse_1_3()
*/
oneway getAllowedCarriers_1_4(int32_t serial);
+
+ /**
+ * Requests current signal strength and associated information. Must succeed if radio is on.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioResponse.getSignalStrengthResponse_1_4()
+ */
+ oneway getSignalStrength_1_4(int32_t serial);
};
diff --git a/radio/1.4/IRadioIndication.hal b/radio/1.4/IRadioIndication.hal
index 58b7b70..3c61f96 100644
--- a/radio/1.4/IRadioIndication.hal
+++ b/radio/1.4/IRadioIndication.hal
@@ -89,4 +89,12 @@
* 3. Unsolicited disconnect from either modem or network side.
*/
oneway dataCallListChanged_1_4(RadioIndicationType type, vec<SetupDataCallResult> dcList);
+
+ /**
+ * Indicates current signal strength of the radio.
+ *
+ * @param type Type of radio indication
+ * @param signalStrength SignalStrength information
+ */
+ oneway currentSignalStrength_1_4(RadioIndicationType type, SignalStrength signalStrength);
};
diff --git a/radio/1.4/IRadioResponse.hal b/radio/1.4/IRadioResponse.hal
index 6b8977d..f43295a 100644
--- a/radio/1.4/IRadioResponse.hal
+++ b/radio/1.4/IRadioResponse.hal
@@ -24,6 +24,7 @@
import @1.4::DataRegStateResult;
import @1.4::RadioAccessFamily;
import @1.4::SetupDataCallResult;
+import @1.4::SignalStrength;
import @1.4::SimLockMultiSimPolicy;
/**
@@ -200,4 +201,14 @@
*/
oneway getAllowedCarriersResponse_1_4(RadioResponseInfo info,
CarrierRestrictionsWithPriority carriers, SimLockMultiSimPolicy multiSimPolicy);
+
+ /**
+ * @param signalStrength Current signal strength
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ */
+ oneway getSignalStrengthResponse_1_4(RadioResponseInfo info, SignalStrength signalStrength);
};
diff --git a/radio/1.4/types.hal b/radio/1.4/types.hal
index 6fa7ebd..2747732 100644
--- a/radio/1.4/types.hal
+++ b/radio/1.4/types.hal
@@ -20,12 +20,16 @@
import @1.0::ApnTypes;
import @1.0::Carrier;
import @1.0::CellInfoType;
+import @1.0::CdmaSignalStrength;
import @1.0::DataCallFailCause;
import @1.0::DataProfileId;
import @1.0::DataProfileInfoType;
+import @1.0::EvdoSignalStrength;
+import @1.0::GsmSignalStrength;
+import @1.0::LteSignalStrength;
import @1.0::RadioAccessFamily;
import @1.0::RadioCapabilityPhase;
-import @1.0::RadioCapabilityStatus ;
+import @1.0::RadioCapabilityStatus;
import @1.0::RadioError;
import @1.0::RadioTechnology;
import @1.0::RegState;
@@ -39,10 +43,17 @@
import @1.2::CellInfoTdscdma;
import @1.2::CellInfoWcdma;
import @1.2::CardStatus;
-import @1.2::CellIdentity;
import @1.2::CellConnectionStatus;
+import @1.2::CellIdentityCdma;
+import @1.2::CellIdentityGsm;
+import @1.2::CellIdentityLte;
+import @1.2::CellIdentityTdscdma;
+import @1.2::CellIdentityWcdma;
+import @1.2::CellIdentityOperatorNames;
import @1.2::DataRegStateResult;
import @1.2::PhysicalChannelConfig;
+import @1.2::TdscdmaSignalStrength;
+import @1.2::WcdmaSignalStrength;
import android.hidl.safe_union@1.0::Monostate;
@@ -188,12 +199,12 @@
};
enum RadioTechnology : @1.0::RadioTechnology {
- /** 5G NR. */
+ /** 5G NR. This is only use in 5G Standalone mode. */
NR = 20,
};
enum RadioAccessFamily : @1.0::RadioAccessFamily {
- /** 5G NR. */
+ /** 5G NR. This is only use in 5G Standalone mode. */
NR = 1 << RadioTechnology:NR,
};
@@ -1551,9 +1562,15 @@
CellInfoWcdma wcdma;
CellInfoTdscdma tdscdma;
CellInfoLte lte;
+ CellInfoNr nr;
} info;
};
+struct CellInfoNr {
+ NrSignalStrength signalStrength;
+ CellIdentityNr cellidentity;
+};
+
/** Overwritten from @1.2::NetworkScanResult in order to update the CellInfo to 1.4 version. */
struct NetworkScanResult {
/**
@@ -1770,3 +1787,131 @@
*/
bool allowedCarriersPrioritized;
};
+
+struct CellIdentityNr {
+ /** 3-digit Mobile Country Code, in range[0, 999], INT_MAX means invalid/unreported. */
+ string mcc;
+
+ /**
+ * 2 or 3-digit Mobile Network Code, in range [0, 999], INT_MAX means invalid/unreported.
+ */
+ string mnc;
+
+ /**
+ * Physical cell id in range [0, 1007] described in 3GPP TS 38.331. This value must be valid.
+ */
+ uint32_t pci;
+
+ /** 16-bit tracking area code, INT_MAX means invalid/unreported. */
+ int32_t tac;
+
+ /**
+ * NR Absolute Radio Frequency Channel Number, in range [0, 3279165].
+ * Reference: 3GPP TS 38.101-1 and 3GPP TS 38.101-2 section 5.4.2.1.
+ * This value must be valid.
+ */
+ int32_t nrarfcn;
+
+ CellIdentityOperatorNames operatorNames;
+};
+
+struct NrSignalStrength {
+ /**
+ * SS reference signal received power, multipled by -1.
+ *
+ * Reference: 3GPP TS 38.215.
+ *
+ * Range [44, 140], INT_MAX means invalid/unreported.
+ */
+ int32_t ssRsrp;
+
+ /**
+ * SS reference signal received quality, multipled by -1.
+ *
+ * Reference: 3GPP TS 38.215.
+ *
+ * Range [3, 20], INT_MAX means invalid/unreported.
+ */
+ int32_t ssRsrq;
+
+ /**
+ * SS signal-to-noise and interference ratio.
+ *
+ * Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
+ *
+ * Range [-23, 40], INT_MAX means invalid/unreported.
+ */
+ int32_t ssSinr;
+
+ /**
+ * CSI reference signal received power, multipled by -1.
+ *
+ * Reference: 3GPP TS 38.215.
+ *
+ * Range [44, 140], INT_MAX means invalid/unreported.
+ */
+ int32_t csiRsrp;
+
+ /**
+ * CSI reference signal received quality, multipled by -1.
+ *
+ * Reference: 3GPP TS 38.215.
+ *
+ * Range [3, 20], INT_MAX means invalid/unreported.
+ */
+ int32_t csiRsrq;
+
+ /**
+ * CSI signal-to-noise and interference ratio.
+ *
+ * Reference: 3GPP TS 138.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
+ *
+ * Range [-23, 40], INT_MAX means invalid/unreported.
+ */
+ int32_t csiSinr;
+};
+
+/** Overwritten from @1.2::SignalStrength in order to add signal strength for NR. */
+struct SignalStrength {
+ /**
+ * If GSM measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ GsmSignalStrength gsm;
+
+ /**
+ * If CDMA measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ CdmaSignalStrength cdma;
+
+ /**
+ * If EvDO measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ EvdoSignalStrength evdo;
+
+ /**
+ * If LTE measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ LteSignalStrength lte;
+
+ /**
+ * If TD-SCDMA measurements are provided, this structure must contain valid measurements;
+ * otherwise all fields should be set to INT_MAX to mark them as invalid.
+ */
+ TdscdmaSignalStrength tdscdma;
+
+ /**
+ * If WCDMA measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ WcdmaSignalStrength wcdma;
+
+ /**
+ * If NR 5G measurements are provided, this structure must contain valid measurements; otherwise
+ * all fields should be set to INT_MAX to mark them as invalid.
+ */
+ NrSignalStrength nr;
+};
diff --git a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
index f290d5d..b77814f 100644
--- a/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
+++ b/radio/1.4/vts/functional/radio_hidl_hal_utils_v1_4.h
@@ -441,6 +441,9 @@
const RadioResponseInfo& info,
const ::android::hardware::radio::V1_2::SignalStrength& sig_strength);
+ Return<void> getSignalStrengthResponse_1_4(const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::SignalStrength& sig_strength);
+
Return<void> getCellInfoListResponse_1_2(
const RadioResponseInfo& info,
const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::CellInfo>&
@@ -559,6 +562,9 @@
RadioIndicationType type,
const ::android::hardware::radio::V1_2::SignalStrength& signalStrength);
+ Return<void> currentSignalStrength_1_4(RadioIndicationType type,
+ const ::android::hardware::radio::V1_4::SignalStrength& signalStrength);
+
/* 1.1 Api */
Return<void> carrierInfoForImsiEncryption(RadioIndicationType info);
@@ -730,4 +736,4 @@
/* radio indication handle */
sp<RadioIndication_v1_4> radioInd_v1_4;
-};
\ No newline at end of file
+};
diff --git a/radio/1.4/vts/functional/radio_indication.cpp b/radio/1.4/vts/functional/radio_indication.cpp
index f08b361..c3722b0 100644
--- a/radio/1.4/vts/functional/radio_indication.cpp
+++ b/radio/1.4/vts/functional/radio_indication.cpp
@@ -85,6 +85,11 @@
return Void();
}
+Return<void> RadioIndication_v1_4::currentSignalStrength_1_4(RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_4::SignalStrength& /*signalStrength*/) {
+ return Void();
+}
+
/* 1.1 Apis */
Return<void> RadioIndication_v1_4::carrierInfoForImsiEncryption(RadioIndicationType /*info*/) {
return Void();
@@ -321,4 +326,4 @@
Return<void> RadioIndication_v1_4::modemReset(RadioIndicationType /*type*/,
const ::android::hardware::hidl_string& /*reason*/) {
return Void();
-}
\ No newline at end of file
+}
diff --git a/radio/1.4/vts/functional/radio_response.cpp b/radio/1.4/vts/functional/radio_response.cpp
index 2ae5f7c..10ecead 100644
--- a/radio/1.4/vts/functional/radio_response.cpp
+++ b/radio/1.4/vts/functional/radio_response.cpp
@@ -739,6 +739,13 @@
return Void();
}
+Return<void> RadioResponse_v1_4::getSignalStrengthResponse_1_4(const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::SignalStrength& /*sig_strength*/) {
+ rspInfo = info;
+ parent_v1_4.notify(info.serial);
+ return Void();
+}
+
Return<void> RadioResponse_v1_4::getCellInfoListResponse_1_2(
const RadioResponseInfo& /*info*/,
const ::android::hardware::hidl_vec<
@@ -864,4 +871,4 @@
const RadioResponseInfo& /*info*/, const CarrierRestrictionsWithPriority& /*carriers*/,
SimLockMultiSimPolicy /*multiSimPolicy*/) {
return Void();
-}
\ No newline at end of file
+}
diff --git a/vibrator/1.3/example/Android.bp b/vibrator/1.3/example/Android.bp
new file mode 100644
index 0000000..36f2ff8
--- /dev/null
+++ b/vibrator/1.3/example/Android.bp
@@ -0,0 +1,34 @@
+//
+// 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_binary {
+ name: "android.hardware.vibrator@1.3-service.example",
+ vendor: true,
+ relative_install_path: "hw",
+ init_rc: ["android.hardware.vibrator@1.3-service.example.rc"],
+ vintf_fragments: ["android.hardware.vibrator@1.3-service.example.xml"],
+ srcs: ["service.cpp", "Vibrator.cpp"],
+ cflags: ["-Wall", "-Werror"],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ "android.hardware.vibrator@1.0",
+ "android.hardware.vibrator@1.1",
+ "android.hardware.vibrator@1.2",
+ "android.hardware.vibrator@1.3",
+ ],
+}
diff --git a/vibrator/1.3/example/Vibrator.cpp b/vibrator/1.3/example/Vibrator.cpp
new file mode 100644
index 0000000..bb9a057
--- /dev/null
+++ b/vibrator/1.3/example/Vibrator.cpp
@@ -0,0 +1,242 @@
+/*
+ * 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 "VibratorService"
+
+#include <log/log.h>
+
+#include "Vibrator.h"
+
+namespace android {
+namespace hardware {
+namespace vibrator {
+namespace V1_3 {
+namespace implementation {
+
+static constexpr uint32_t MS_PER_S = 1000;
+static constexpr uint32_t NS_PER_MS = 1000000;
+
+Vibrator::Vibrator() {
+ sigevent se{};
+ se.sigev_notify = SIGEV_THREAD;
+ se.sigev_value.sival_ptr = this;
+ se.sigev_notify_function = timerCallback;
+ se.sigev_notify_attributes = nullptr;
+
+ if (timer_create(CLOCK_REALTIME, &se, &mTimer) < 0) {
+ ALOGE("Can not create timer!%s", strerror(errno));
+ }
+}
+
+// Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
+
+Return<Status> Vibrator::on(uint32_t timeoutMs) {
+ return activate(timeoutMs);
+}
+
+Return<Status> Vibrator::off() {
+ return activate(0);
+}
+
+Return<bool> Vibrator::supportsAmplitudeControl() {
+ return true;
+}
+
+Return<Status> Vibrator::setAmplitude(uint8_t amplitude) {
+ ALOGI("Amplitude: %u -> %u\n", mAmplitude, amplitude);
+ mAmplitude = amplitude;
+ return Status::OK;
+}
+
+Return<void> Vibrator::perform(V1_0::Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
+ return perform_1_1(static_cast<V1_1::Effect_1_1>(effect), strength, _hidl_cb);
+}
+
+// Methods from ::android::hardware::vibrator::V1_1::IVibrator follow.
+
+Return<void> Vibrator::perform_1_1(V1_1::Effect_1_1 effect, EffectStrength strength,
+ perform_cb _hidl_cb) {
+ return perform_1_2(static_cast<V1_2::Effect>(effect), strength, _hidl_cb);
+}
+
+// Methods from ::android::hardware::vibrator::V1_2::IVibrator follow.
+
+Return<void> Vibrator::perform_1_2(Effect effect, EffectStrength strength, perform_cb _hidl_cb) {
+ uint8_t amplitude;
+ uint32_t ms;
+ Status status;
+
+ ALOGI("Perform: Effect %s\n", effectToName(effect));
+
+ amplitude = strengthToAmplitude(strength);
+ setAmplitude(amplitude);
+
+ ms = effectToMs(effect);
+ status = activate(ms);
+
+ _hidl_cb(status, ms);
+
+ return Void();
+}
+
+// Methods from ::android::hardware::vibrator::V1_3::IVibrator follow.
+
+Return<bool> Vibrator::supportsExternalControl() {
+ return true;
+}
+
+Return<Status> Vibrator::setExternalControl(bool enabled) {
+ if (mEnabled) {
+ ALOGW("Setting external control while the vibrator is enabled is unsupported!");
+ return Status::UNSUPPORTED_OPERATION;
+ } else {
+ ALOGI("ExternalControl: %s -> %s\n", mExternalControl ? "true" : "false",
+ enabled ? "true" : "false");
+ mExternalControl = enabled;
+ return Status::OK;
+ }
+}
+
+// Private methods follow.
+
+Status Vibrator::enable(bool enabled) {
+ if (mExternalControl) {
+ ALOGW("Enabling/disabling while the vibrator is externally controlled is unsupported!");
+ return Status::UNSUPPORTED_OPERATION;
+ } else {
+ ALOGI("Enabled: %s -> %s\n", mEnabled ? "true" : "false", enabled ? "true" : "false");
+ mEnabled = enabled;
+ return Status::OK;
+ }
+}
+
+Status Vibrator::activate(uint32_t ms) {
+ std::lock_guard<std::mutex> lock{mMutex};
+ Status status = Status::OK;
+
+ if (ms > 0) {
+ status = enable(true);
+ if (status != Status::OK) {
+ return status;
+ }
+ }
+
+ itimerspec ts{};
+ ts.it_value.tv_sec = ms / MS_PER_S;
+ ts.it_value.tv_nsec = ms % MS_PER_S * NS_PER_MS;
+
+ if (timer_settime(mTimer, 0, &ts, nullptr) < 0) {
+ ALOGE("Can not set timer!");
+ status = Status::UNKNOWN_ERROR;
+ }
+
+ if ((status != Status::OK) || !ms) {
+ Status _status;
+
+ _status = enable(false);
+
+ if (status == Status::OK) {
+ status = _status;
+ }
+ }
+
+ return status;
+}
+
+void Vibrator::timeout() {
+ std::lock_guard<std::mutex> lock{mMutex};
+ itimerspec ts{};
+
+ if (timer_gettime(mTimer, &ts) < 0) {
+ ALOGE("Can not read timer!");
+ }
+
+ if (ts.it_value.tv_sec == 0 && ts.it_value.tv_nsec == 0) {
+ enable(false);
+ }
+}
+
+void Vibrator::timerCallback(union sigval sigval) {
+ static_cast<Vibrator*>(sigval.sival_ptr)->timeout();
+}
+
+const char* Vibrator::effectToName(Effect effect) {
+ return toString(effect).c_str();
+}
+
+uint32_t Vibrator::effectToMs(Effect effect) {
+ switch (effect) {
+ case Effect::CLICK:
+ return 10;
+ case Effect::DOUBLE_CLICK:
+ return 15;
+ case Effect::TICK:
+ return 5;
+ case Effect::THUD:
+ return 5;
+ case Effect::POP:
+ return 5;
+ case Effect::HEAVY_CLICK:
+ return 10;
+ case Effect::RINGTONE_1:
+ return 30000;
+ case Effect::RINGTONE_2:
+ return 30000;
+ case Effect::RINGTONE_3:
+ return 30000;
+ case Effect::RINGTONE_4:
+ return 30000;
+ case Effect::RINGTONE_5:
+ return 30000;
+ case Effect::RINGTONE_6:
+ return 30000;
+ case Effect::RINGTONE_7:
+ return 30000;
+ case Effect::RINGTONE_8:
+ return 30000;
+ case Effect::RINGTONE_9:
+ return 30000;
+ case Effect::RINGTONE_10:
+ return 30000;
+ case Effect::RINGTONE_11:
+ return 30000;
+ case Effect::RINGTONE_12:
+ return 30000;
+ case Effect::RINGTONE_13:
+ return 30000;
+ case Effect::RINGTONE_14:
+ return 30000;
+ case Effect::RINGTONE_15:
+ return 30000;
+ }
+}
+
+uint8_t Vibrator::strengthToAmplitude(EffectStrength strength) {
+ switch (strength) {
+ case EffectStrength::LIGHT:
+ return 128;
+ case EffectStrength::MEDIUM:
+ return 192;
+ case EffectStrength::STRONG:
+ return 255;
+ }
+}
+
+} // namespace implementation
+} // namespace V1_3
+} // namespace vibrator
+} // namespace hardware
+} // namespace android
diff --git a/vibrator/1.3/example/Vibrator.h b/vibrator/1.3/example/Vibrator.h
new file mode 100644
index 0000000..a931b63
--- /dev/null
+++ b/vibrator/1.3/example/Vibrator.h
@@ -0,0 +1,78 @@
+/*
+ * 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_VIBRATOR_V1_3_VIBRATOR_H
+#define ANDROID_HARDWARE_VIBRATOR_V1_3_VIBRATOR_H
+
+#include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace vibrator {
+namespace V1_3 {
+namespace implementation {
+
+using android::hardware::vibrator::V1_0::EffectStrength;
+using android::hardware::vibrator::V1_0::Status;
+using android::hardware::vibrator::V1_2::Effect;
+
+class Vibrator : public IVibrator {
+ public:
+ Vibrator();
+
+ // Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
+ Return<Status> on(uint32_t timeoutMs) override;
+ Return<Status> off() override;
+ Return<bool> supportsAmplitudeControl() override;
+ Return<Status> setAmplitude(uint8_t amplitude) override;
+ Return<void> perform(V1_0::Effect effect, EffectStrength strength,
+ perform_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::vibrator::V1_1::IVibrator follow.
+ Return<void> perform_1_1(V1_1::Effect_1_1 effect, EffectStrength strength,
+ perform_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::vibrator::V1_2::IVibrator follow.
+ Return<void> perform_1_2(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
+
+ // Methods from ::android::hardware::vibrator::V1_3::IVibrator follow.
+ Return<bool> supportsExternalControl() override;
+ Return<Status> setExternalControl(bool enabled) override;
+
+ private:
+ Status enable(bool enabled);
+ Status activate(uint32_t ms);
+ void timeout();
+
+ static void timerCallback(union sigval sigval);
+ static const char* effectToName(Effect effect);
+ static uint32_t effectToMs(Effect effect);
+ static uint8_t strengthToAmplitude(EffectStrength strength);
+
+ private:
+ bool mEnabled{false};
+ uint8_t mAmplitude{UINT8_MAX};
+ bool mExternalControl{false};
+ std::mutex mMutex;
+ timer_t mTimer{nullptr};
+};
+} // namespace implementation
+} // namespace V1_3
+} // namespace vibrator
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_VIBRATOR_V1_3_VIBRATOR_H
diff --git a/vibrator/1.3/example/android.hardware.vibrator@1.3-service.example.rc b/vibrator/1.3/example/android.hardware.vibrator@1.3-service.example.rc
new file mode 100644
index 0000000..ed7a562
--- /dev/null
+++ b/vibrator/1.3/example/android.hardware.vibrator@1.3-service.example.rc
@@ -0,0 +1,4 @@
+service vendor.vibrator-1-3 /vendor/bin/hw/android.hardware.vibrator@1.3-service.example
+ class hal
+ user system
+ group system
diff --git a/vibrator/1.3/example/android.hardware.vibrator@1.3-service.example.xml b/vibrator/1.3/example/android.hardware.vibrator@1.3-service.example.xml
new file mode 100644
index 0000000..172aa21
--- /dev/null
+++ b/vibrator/1.3/example/android.hardware.vibrator@1.3-service.example.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.vibrator</name>
+ <transport>hwbinder</transport>
+ <version>1.3</version>
+ <interface>
+ <name>IVibrator</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/vibrator/1.3/example/service.cpp b/vibrator/1.3/example/service.cpp
new file mode 100644
index 0000000..449996e
--- /dev/null
+++ b/vibrator/1.3/example/service.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 "android.hardware.vibrator@1.3-service.example"
+
+#include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "Vibrator.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::vibrator::V1_3::IVibrator;
+using android::hardware::vibrator::V1_3::implementation::Vibrator;
+using namespace android;
+
+status_t registerVibratorService() {
+ sp<IVibrator> vibrator = new Vibrator();
+
+ return vibrator->registerAsService();
+}
+
+int main() {
+ configureRpcThreadpool(1, true);
+ status_t status = registerVibratorService();
+
+ if (status != OK) {
+ return status;
+ }
+
+ joinRpcThreadpool();
+
+ return 1;
+}
diff --git a/wifi/1.3/default/Android.mk b/wifi/1.3/default/Android.mk
index 8312c31..01fa934 100644
--- a/wifi/1.3/default/Android.mk
+++ b/wifi/1.3/default/Android.mk
@@ -98,6 +98,37 @@
include $(BUILD_EXECUTABLE)
###
+### android.hardware.wifi daemon
+###
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.wifi@1.0-service-lazy
+LOCAL_OVERRIDES_MODULES := android.hardware.wifi@1.0-service
+LOCAL_CFLAGS := -DLAZY_SERVICE
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_CPPFLAGS := -Wall -Werror -Wextra
+LOCAL_SRC_FILES := \
+ service.cpp
+LOCAL_SHARED_LIBRARIES := \
+ libbase \
+ libcutils \
+ libhidlbase \
+ libhidltransport \
+ liblog \
+ libnl \
+ libutils \
+ libwifi-hal \
+ libwifi-system-iface \
+ android.hardware.wifi@1.0 \
+ android.hardware.wifi@1.1 \
+ android.hardware.wifi@1.2 \
+ android.hardware.wifi@1.3
+LOCAL_STATIC_LIBRARIES := \
+ android.hardware.wifi@1.0-service-lib
+LOCAL_INIT_RC := android.hardware.wifi@1.0-service-lazy.rc
+include $(BUILD_EXECUTABLE)
+
+###
### android.hardware.wifi unit tests.
###
include $(CLEAR_VARS)
diff --git a/wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc b/wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc
new file mode 100644
index 0000000..cf917b5
--- /dev/null
+++ b/wifi/1.3/default/android.hardware.wifi@1.0-service-lazy.rc
@@ -0,0 +1,8 @@
+service vendor.wifi_hal_legacy /vendor/bin/hw/android.hardware.wifi@1.0-service-lazy
+ interface android.hardware.wifi@1.0::IWifi default
+ oneshot
+ disabled
+ class hal
+ capabilities NET_ADMIN NET_RAW SYS_MODULE
+ user wifi
+ group wifi gps
diff --git a/wifi/1.3/default/service.cpp b/wifi/1.3/default/service.cpp
index 5fd83c1..5daf659 100644
--- a/wifi/1.3/default/service.cpp
+++ b/wifi/1.3/default/service.cpp
@@ -15,6 +15,7 @@
*/
#include <android-base/logging.h>
+#include <hidl/HidlLazyUtils.h>
#include <hidl/HidlTransportSupport.h>
#include <utils/Looper.h>
#include <utils/StrongPointer.h>
@@ -26,12 +27,19 @@
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
+using android::hardware::LazyServiceRegistrar;
using android::hardware::wifi::V1_3::implementation::feature_flags::
WifiFeatureFlags;
using android::hardware::wifi::V1_3::implementation::legacy_hal::WifiLegacyHal;
using android::hardware::wifi::V1_3::implementation::mode_controller::
WifiModeController;
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
int main(int /*argc*/, char** argv) {
android::base::InitLogging(
argv, android::base::LogdLogger(android::base::SYSTEM));
@@ -45,8 +53,14 @@
std::make_shared<WifiLegacyHal>(),
std::make_shared<WifiModeController>(),
std::make_shared<WifiFeatureFlags>());
- CHECK_EQ(service->registerAsService(), android::NO_ERROR)
- << "Failed to register wifi HAL";
+ if (kLazyService) {
+ LazyServiceRegistrar registrar;
+ CHECK_EQ(registrar.registerService(service), android::NO_ERROR)
+ << "Failed to register wifi HAL";
+ } else {
+ CHECK_EQ(service->registerAsService(), android::NO_ERROR)
+ << "Failed to register wifi HAL";
+ }
joinRpcThreadpool();