Add GnssVisibilityControl AIDL HAL (frameworks/base)

Bug: 208728105
Test: atest VtsHalGnssTargetTest
Change-Id: Id05a7462762779b54afbfbf573d9b64874b806d9
This commit is contained in:
Edwin Tung
2021-12-17 18:51:35 +08:00
parent dc97de5820
commit 454aff8180
7 changed files with 403 additions and 76 deletions

View File

@@ -160,7 +160,6 @@ cc_defaults {
"android.hardware.gnss@2.0",
"android.hardware.gnss@2.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
"android.hardware.graphics.bufferqueue@1.0",
"android.hardware.graphics.bufferqueue@2.0",
"android.hardware.graphics.common@1.2",

View File

@@ -37,7 +37,6 @@
#include <android/hardware/gnss/BnGnssPsdsCallback.h>
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
#include <binder/IServiceManager.h>
#include <nativehelper/JNIHelp.h>
#include <pthread.h>
@@ -59,6 +58,7 @@
#include "gnss/GnssGeofence.h"
#include "gnss/GnssMeasurement.h"
#include "gnss/GnssNavigationMessage.h"
#include "gnss/GnssVisibilityControl.h"
#include "gnss/Utils.h"
#include "hardware_legacy/power.h"
#include "jni.h"
@@ -162,9 +162,6 @@ using IMeasurementCorrections_V1_1 = android::hardware::gnss::measurement_correc
using android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrectionsCallback;
using android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback;
using android::hardware::gnss::BlocklistedSource;
using android::hardware::gnss::GnssConstellationType;
using android::hardware::gnss::GnssPowerStats;
@@ -210,7 +207,6 @@ sp<IGnssNi> gnssNiIface = nullptr;
sp<IGnssPowerIndication> gnssPowerIndicationIface = nullptr;
sp<IMeasurementCorrections_V1_0> gnssCorrectionsIface_V1_0 = nullptr;
sp<IMeasurementCorrections_V1_1> gnssCorrectionsIface_V1_1 = nullptr;
sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;
sp<IGnssAntennaInfo> gnssAntennaInfoIface = nullptr;
std::unique_ptr<GnssConfigurationInterface> gnssConfigurationIface = nullptr;
@@ -221,6 +217,7 @@ std::unique_ptr<android::gnss::GnssGeofenceInterface> gnssGeofencingIface = null
std::unique_ptr<android::gnss::AGnssInterface> agnssIface = nullptr;
std::unique_ptr<android::gnss::GnssDebugInterface> gnssDebugIface = nullptr;
std::unique_ptr<android::gnss::AGnssRilInterface> agnssRilIface = nullptr;
std::unique_ptr<android::gnss::GnssVisibilityControlInterface> gnssVisibilityControlIface = nullptr;
#define WAKE_LOCK_NAME "GPS"
@@ -858,54 +855,6 @@ Return<void> GnssNiCallback::niNotifyCb(
return Void();
}
/*
* GnssVisibilityControlCallback implements callback methods of IGnssVisibilityControlCallback.hal.
*/
struct GnssVisibilityControlCallback : public IGnssVisibilityControlCallback {
Return<void> nfwNotifyCb(const IGnssVisibilityControlCallback::NfwNotification& notification)
override;
Return<bool> isInEmergencySession() override;
};
Return<void> GnssVisibilityControlCallback::nfwNotifyCb(
const IGnssVisibilityControlCallback::NfwNotification& notification) {
JNIEnv* env = getJniEnv();
jstring proxyAppPackageName = env->NewStringUTF(notification.proxyAppPackageName.c_str());
jstring otherProtocolStackName = env->NewStringUTF(notification.otherProtocolStackName.c_str());
jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
if (proxyAppPackageName && otherProtocolStackName && requestorId) {
env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName,
notification.protocolStack, otherProtocolStackName,
notification.requestor, requestorId, notification.responseType,
notification.inEmergencyMode, notification.isCachedLocation);
} else {
ALOGE("%s: OOM Error\n", __func__);
}
if (requestorId) {
env->DeleteLocalRef(requestorId);
}
if (otherProtocolStackName) {
env->DeleteLocalRef(otherProtocolStackName);
}
if (proxyAppPackageName) {
env->DeleteLocalRef(proxyAppPackageName);
}
checkAndClearExceptionFromCallback(env, __FUNCTION__);
return Void();
}
Return<bool> GnssVisibilityControlCallback::isInEmergencySession() {
JNIEnv* env = getJniEnv();
auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
return result;
}
/* Initializes the GNSS service handle. */
static void android_location_gnss_hal_GnssNative_set_gps_service_handle() {
gnssHalAidl = waitForVintfService<IGnssAidl>();
@@ -1322,12 +1271,21 @@ static void android_location_gnss_hal_GnssNative_init_once(JNIEnv* env, jobject
}
}
if (gnssHal_V2_0 != nullptr) {
auto gnssVisibilityControl = gnssHal_V2_0->getExtensionVisibilityControl();
if (!gnssVisibilityControl.isOk()) {
ALOGD("Unable to get a handle to GnssVisibilityControl interface");
} else {
gnssVisibilityControlIface = gnssVisibilityControl;
if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
sp<android::hardware::gnss::visibility_control::IGnssVisibilityControl>
gnssVisibilityControlAidl;
auto status = gnssHalAidl->getExtensionGnssVisibilityControl(&gnssVisibilityControlAidl);
if (checkAidlStatus(status,
"Unable to get a handle to GnssVisibilityControl AIDL interface.")) {
gnssVisibilityControlIface =
std::make_unique<gnss::GnssVisibilityControlAidl>(gnssVisibilityControlAidl);
}
} else if (gnssHal_V2_0 != nullptr) {
auto gnssVisibilityControlHidl = gnssHal_V2_0->getExtensionVisibilityControl();
if (checkHidlReturn(gnssVisibilityControlHidl,
"Unable to get a handle to GnssVisibilityControl HIDL interface")) {
gnssVisibilityControlIface =
std::make_unique<gnss::GnssVisibilityControlHidl>(gnssVisibilityControlHidl);
}
}
@@ -1452,12 +1410,12 @@ static jboolean android_location_gnss_hal_GnssNative_init(JNIEnv* /* env */, jcl
ALOGI("Unable to initialize IAGnssRil interface.");
}
// Set IGnssVisibilityControl.hal callback.
// Set IGnssVisibilityControl callback.
if (gnssVisibilityControlIface != nullptr) {
sp<IGnssVisibilityControlCallback> gnssVisibilityControlCbIface =
new GnssVisibilityControlCallback();
auto result = gnssVisibilityControlIface->setCallback(gnssVisibilityControlCbIface);
checkHidlReturn(result, "IGnssVisibilityControl setCallback() failed.");
gnssVisibilityControlIface->setCallback(
std::make_unique<gnss::GnssVisibilityControlCallback>());
} else {
ALOGI("Unable to initialize IGnssVisibilityControl interface.");
}
// Set IMeasurementCorrections.hal callback.
@@ -2301,17 +2259,7 @@ static jboolean android_location_GnssVisibilityControl_enable_nfw_location_acces
ALOGI("IGnssVisibilityControl interface not available.");
return JNI_FALSE;
}
const jsize length = env->GetArrayLength(proxyApps);
hidl_vec<hidl_string> hidlProxyApps(length);
for (int i = 0; i < length; ++i) {
jstring proxyApp = (jstring) (env->GetObjectArrayElement(proxyApps, i));
ScopedJniString jniProxyApp(env, proxyApp);
hidlProxyApps[i] = jniProxyApp;
}
auto result = gnssVisibilityControlIface->enableNfwLocationAccess(hidlProxyApps);
return checkHidlReturn(result, "IGnssVisibilityControl enableNfwLocationAccess() failed.");
return gnssVisibilityControlIface->enableNfwLocationAccess(env, proxyApps);
}
static const JNINativeMethod sCoreMethods[] = {

View File

@@ -38,6 +38,8 @@ cc_library_shared {
"GnssMeasurementCallback.cpp",
"GnssNavigationMessage.cpp",
"GnssNavigationMessageCallback.cpp",
"GnssVisibilityControl.cpp",
"GnssVisibilityControlCallback.cpp",
"Utils.cpp",
],
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Define LOG_TAG before <log/log.h> to overwrite the default value.
#define LOG_TAG "GnssVisibilityControlJni"
#include "GnssVisibilityControl.h"
#include "Utils.h"
using IGnssVisibilityControlAidl =
android::hardware::gnss::visibility_control::IGnssVisibilityControl;
using IGnssVisibilityControlHidl =
android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
namespace android::gnss {
// Implementation of GnssVisibilityControl (AIDL HAL)
GnssVisibilityControlAidl::GnssVisibilityControlAidl(
const sp<IGnssVisibilityControlAidl>& iGnssVisibilityControl)
: mIGnssVisibilityControlAidl(iGnssVisibilityControl) {
assert(mIGnssVisibilityControlAidl != nullptr);
}
jboolean GnssVisibilityControlAidl::setCallback(
const std::unique_ptr<GnssVisibilityControlCallback>& callback) {
auto status = mIGnssVisibilityControlAidl->setCallback(callback->getAidl());
return checkAidlStatus(status, "IGnssVisibilityControlAidl setCallback() failed.");
}
jboolean GnssVisibilityControlAidl::enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) {
int length = env->GetArrayLength(proxyApps);
std::vector<std::string> aidlProxyApps(length);
for (int i = 0; i < length; ++i) {
jstring proxyApp = (jstring)(env->GetObjectArrayElement(proxyApps, i));
ScopedJniString jniProxyApp(env, proxyApp);
aidlProxyApps[i] = std::string(jniProxyApp.c_str());
}
auto status = mIGnssVisibilityControlAidl->enableNfwLocationAccess(aidlProxyApps);
return checkAidlStatus(status, "IGnssVisibilityControlAidl enableNfwLocationAccess() failed");
}
// Implementation of GnssVisibilityControlHidl
GnssVisibilityControlHidl::GnssVisibilityControlHidl(
const sp<IGnssVisibilityControlHidl>& iGnssVisibilityControl)
: mIGnssVisibilityControlHidl(iGnssVisibilityControl) {
assert(mIGnssVisibilityControlHidl != nullptr);
}
jboolean GnssVisibilityControlHidl::setCallback(
const std::unique_ptr<GnssVisibilityControlCallback>& callback) {
auto result = mIGnssVisibilityControlHidl->setCallback(callback->getHidl());
return checkHidlReturn(result, "IGnssVisibilityControlHidl setCallback() failed.");
}
jboolean GnssVisibilityControlHidl::enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) {
const jsize length = env->GetArrayLength(proxyApps);
hardware::hidl_vec<hardware::hidl_string> hidlProxyApps(length);
for (int i = 0; i < length; ++i) {
jstring proxyApp = (jstring)(env->GetObjectArrayElement(proxyApps, i));
ScopedJniString jniProxyApp(env, proxyApp);
hidlProxyApps[i] = jniProxyApp;
}
auto result = mIGnssVisibilityControlHidl->enableNfwLocationAccess(hidlProxyApps);
return checkHidlReturn(result, "IGnssVisibilityControlHidl enableNfwLocationAccess() failed.");
}
} // namespace android::gnss

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ANDROID_SERVER_GNSS_VISIBILITYCONTROL_H
#define _ANDROID_SERVER_GNSS_VISIBILITYCONTROL_H
#pragma once
#ifndef LOG_TAG
#error LOG_TAG must be defined before including this file.
#endif
#include <android/hardware/gnss/visibility_control/BnGnssVisibilityControl.h>
#include <log/log.h>
#include "GnssVisibilityControlCallback.h"
#include "jni.h"
namespace android::gnss {
class GnssVisibilityControlInterface {
public:
virtual ~GnssVisibilityControlInterface() {}
virtual jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) = 0;
virtual jboolean setCallback(
const std::unique_ptr<GnssVisibilityControlCallback>& callback) = 0;
};
class GnssVisibilityControlAidl : public GnssVisibilityControlInterface {
public:
GnssVisibilityControlAidl(
const sp<android::hardware::gnss::visibility_control::IGnssVisibilityControl>&
iGnssVisibilityControl);
jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) override;
jboolean setCallback(const std::unique_ptr<GnssVisibilityControlCallback>& callback) override;
private:
const sp<android::hardware::gnss::visibility_control::IGnssVisibilityControl>
mIGnssVisibilityControlAidl;
};
class GnssVisibilityControlHidl : public GnssVisibilityControlInterface {
public:
GnssVisibilityControlHidl(
const sp<android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>&
iGnssVisibilityControl);
jboolean enableNfwLocationAccess(JNIEnv* env, jobjectArray proxyApps) override;
jboolean setCallback(const std::unique_ptr<GnssVisibilityControlCallback>& callback) override;
private:
const sp<android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl>
mIGnssVisibilityControlHidl;
};
} // namespace android::gnss
#endif // _ANDROID_SERVER_GNSS_VISIBILITYCONTROL_H

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "GnssVisibilityControlCbJni"
#include "GnssVisibilityControlCallback.h"
namespace android::gnss {
// using android::hardware::hidl_vec;
using binder::Status;
using hardware::Return;
namespace {
jmethodID method_reportNfwNotification;
jmethodID method_isInEmergencySession;
} // anonymous namespace
void GnssVisibilityControl_class_init_once(JNIEnv* env, jclass clazz) {
method_reportNfwNotification =
env->GetMethodID(clazz, "reportNfwNotification",
"(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
}
// Implementation of GnssVisibilityControlCallbackAidl class.
Status GnssVisibilityControlCallbackAidl::nfwNotifyCb(
const android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback::
NfwNotification& notification) {
GnssVisibilityControlCallbackUtil::nfwNotifyCb(notification);
return Status::ok();
}
Status GnssVisibilityControlCallbackAidl::isInEmergencySession(bool* _aidl_return) {
*_aidl_return = GnssVisibilityControlCallbackUtil::isInEmergencySession();
return Status::ok();
}
// Implementation of GnssVisibilityControlCallbackHidl class.
Return<void> GnssVisibilityControlCallbackHidl::nfwNotifyCb(
const IGnssVisibilityControlCallback::NfwNotification& notification) {
GnssVisibilityControlCallbackUtil::nfwNotifyCb(notification);
return hardware::Void();
}
Return<bool> GnssVisibilityControlCallbackHidl::isInEmergencySession() {
return GnssVisibilityControlCallbackUtil::isInEmergencySession();
}
// Implementation of GnssVisibilityControlCallbackUtil class.
bool GnssVisibilityControlCallbackUtil::isInEmergencySession() {
JNIEnv* env = getJniEnv();
auto result = env->CallBooleanMethod(mCallbacksObj, method_isInEmergencySession);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
return result;
}
template <>
jstring ToJstring(JNIEnv* env, const String16& value) {
const char16_t* str = value.string();
size_t len = value.size();
return env->NewString(reinterpret_cast<const jchar*>(str), len);
}
template <>
jstring ToJstring(JNIEnv* env, const hardware::hidl_string& value) {
return env->NewStringUTF(value.c_str());
}
} // namespace android::gnss

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H
#define _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H
#pragma once
#ifndef LOG_TAG
#error LOG_TAG must be defined before including this file.
#endif
#include <android/hardware/gnss/visibility_control/1.0/IGnssVisibilityControl.h>
#include <android/hardware/gnss/visibility_control/BnGnssVisibilityControlCallback.h>
#include <log/log.h>
#include "Utils.h"
#include "jni.h"
namespace android::gnss {
namespace {
extern jmethodID method_reportNfwNotification;
} // anonymous namespace
void GnssNavigationMessage_class_init_once(JNIEnv* env, jclass clazz);
/*
* GnssVisibilityControlCallbackAidl class implements the callback methods required by the
* android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback interface.
*/
class GnssVisibilityControlCallbackAidl
: public hardware::gnss::visibility_control::BnGnssVisibilityControlCallback {
public:
GnssVisibilityControlCallbackAidl() {}
binder::Status nfwNotifyCb(
const android::hardware::gnss::visibility_control::IGnssVisibilityControlCallback::
NfwNotification& notification) override;
binder::Status isInEmergencySession(bool* _aidl_return) override;
};
/*
* GnssVisibilityControlCallbackHidl implements callback methods of
* IGnssVisibilityControlCallback 1.0 interface.
*/
class GnssVisibilityControlCallbackHidl
: public android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback {
public:
GnssVisibilityControlCallbackHidl() {}
hardware::Return<void> nfwNotifyCb(
const IGnssVisibilityControlCallback::NfwNotification& notification) override;
hardware::Return<bool> isInEmergencySession() override;
};
class GnssVisibilityControlCallback {
public:
GnssVisibilityControlCallback() {}
sp<GnssVisibilityControlCallbackAidl> getAidl() {
if (callbackAidl == nullptr) {
callbackAidl = sp<GnssVisibilityControlCallbackAidl>::make();
}
return callbackAidl;
}
sp<GnssVisibilityControlCallbackHidl> getHidl() {
if (callbackHidl == nullptr) {
callbackHidl = sp<GnssVisibilityControlCallbackHidl>::make();
}
return callbackHidl;
}
private:
sp<GnssVisibilityControlCallbackAidl> callbackAidl;
sp<GnssVisibilityControlCallbackHidl> callbackHidl;
};
struct GnssVisibilityControlCallbackUtil {
template <class T>
static void nfwNotifyCb(const T& notification);
static bool isInEmergencySession();
private:
GnssVisibilityControlCallbackUtil() = delete;
};
template <class T>
static jstring ToJstring(JNIEnv* env, const T& value);
template <class T>
void GnssVisibilityControlCallbackUtil::nfwNotifyCb(const T& notification) {
JNIEnv* env = getJniEnv();
jstring proxyAppPackageName = ToJstring(env, notification.proxyAppPackageName);
jstring otherProtocolStackName = ToJstring(env, notification.otherProtocolStackName);
jstring requestorId = ToJstring(env, notification.requestorId);
if (proxyAppPackageName && otherProtocolStackName && requestorId) {
env->CallVoidMethod(mCallbacksObj, method_reportNfwNotification, proxyAppPackageName,
notification.protocolStack, otherProtocolStackName,
notification.requestor, requestorId, notification.responseType,
notification.inEmergencyMode, notification.isCachedLocation);
} else {
ALOGE("%s: OOM Error\n", __func__);
}
if (requestorId) {
env->DeleteLocalRef(requestorId);
}
if (otherProtocolStackName) {
env->DeleteLocalRef(otherProtocolStackName);
}
if (proxyAppPackageName) {
env->DeleteLocalRef(proxyAppPackageName);
}
checkAndClearExceptionFromCallback(env, __FUNCTION__);
}
} // namespace android::gnss
#endif // _ANDROID_SERVER_GNSS_VISIBILITYCONTROLCALLBACK_H