Merge "Implements GNSS satellite blacklist" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b1bcab2210
@@ -12541,6 +12541,19 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public static final String SWAP_ENABLED = "swap_enabled";
|
public static final String SWAP_ENABLED = "swap_enabled";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blacklist of GNSS satellites.
|
||||||
|
*
|
||||||
|
* This is a list of integers separated by commas to represent pairs of (constellation,
|
||||||
|
* svid). Thus, the number of integers should be even.
|
||||||
|
*
|
||||||
|
* E.g.: "3,0,5,24" denotes (constellation=3, svid=0) and (constellation=5, svid=24) are
|
||||||
|
* blacklisted. Note that svid=0 denotes all svids in the
|
||||||
|
* constellation are blacklisted.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final String GNSS_SATELLITE_BLACKLIST = "gnss_satellite_blacklist";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -451,6 +451,7 @@ message GlobalSettingsProto {
|
|||||||
// If set to 1, {@link Secure#LOCATION_MODE} will be set to {@link
|
// If set to 1, {@link Secure#LOCATION_MODE} will be set to {@link
|
||||||
// Secure#LOCATION_MODE_OFF} temporarily for all users.
|
// Secure#LOCATION_MODE_OFF} temporarily for all users.
|
||||||
optional SettingProto global_kill_switch = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
optional SettingProto global_kill_switch = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
||||||
|
optional SettingProto gnss_satellite_blacklist = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
|
||||||
}
|
}
|
||||||
optional Location location = 69;
|
optional Location location = 69;
|
||||||
|
|
||||||
|
|||||||
@@ -239,6 +239,7 @@ public class SettingsBackupTest {
|
|||||||
Settings.Global.GLOBAL_HTTP_PROXY_HOST,
|
Settings.Global.GLOBAL_HTTP_PROXY_HOST,
|
||||||
Settings.Global.GLOBAL_HTTP_PROXY_PAC,
|
Settings.Global.GLOBAL_HTTP_PROXY_PAC,
|
||||||
Settings.Global.GLOBAL_HTTP_PROXY_PORT,
|
Settings.Global.GLOBAL_HTTP_PROXY_PORT,
|
||||||
|
Settings.Global.GNSS_SATELLITE_BLACKLIST,
|
||||||
Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS,
|
Settings.Global.GPRS_REGISTER_CHECK_PERIOD_MS,
|
||||||
Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
|
Settings.Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED,
|
||||||
Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
|
Settings.Global.HDMI_CONTROL_AUTO_WAKEUP_ENABLED,
|
||||||
|
|||||||
@@ -742,6 +742,9 @@ class SettingsProtoDumpUtil {
|
|||||||
dumpSetting(s, p,
|
dumpSetting(s, p,
|
||||||
Settings.Global.LOCATION_GLOBAL_KILL_SWITCH,
|
Settings.Global.LOCATION_GLOBAL_KILL_SWITCH,
|
||||||
GlobalSettingsProto.Location.GLOBAL_KILL_SWITCH);
|
GlobalSettingsProto.Location.GLOBAL_KILL_SWITCH);
|
||||||
|
dumpSetting(s, p,
|
||||||
|
Settings.Global.GNSS_SATELLITE_BLACKLIST,
|
||||||
|
GlobalSettingsProto.Location.GNSS_SATELLITE_BLACKLIST);
|
||||||
p.end(locationToken);
|
p.end(locationToken);
|
||||||
|
|
||||||
final long lpmToken = p.start(GlobalSettingsProto.LOW_POWER_MODE);
|
final long lpmToken = p.start(GlobalSettingsProto.LOW_POWER_MODE);
|
||||||
|
|||||||
@@ -83,7 +83,11 @@ import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
|
|||||||
import com.android.internal.location.ProviderProperties;
|
import com.android.internal.location.ProviderProperties;
|
||||||
import com.android.internal.location.ProviderRequest;
|
import com.android.internal.location.ProviderRequest;
|
||||||
import com.android.internal.location.gnssmetrics.GnssMetrics;
|
import com.android.internal.location.gnssmetrics.GnssMetrics;
|
||||||
|
import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
|
||||||
import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
|
import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
|
||||||
|
|
||||||
|
import libcore.io.IoUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -99,14 +103,13 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import libcore.io.IoUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A GNSS implementation of LocationProvider used by LocationManager.
|
* A GNSS implementation of LocationProvider used by LocationManager.
|
||||||
*
|
*
|
||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
public class GnssLocationProvider implements LocationProviderInterface, InjectNtpTimeCallback {
|
public class GnssLocationProvider implements LocationProviderInterface, InjectNtpTimeCallback,
|
||||||
|
GnssSatelliteBlacklistCallback {
|
||||||
|
|
||||||
private static final String TAG = "GnssLocationProvider";
|
private static final String TAG = "GnssLocationProvider";
|
||||||
|
|
||||||
@@ -308,7 +311,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object mLock = new Object();
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
// current status
|
// current status
|
||||||
private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
|
private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
|
||||||
@@ -411,6 +414,7 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
|||||||
private final ILocationManager mILocationManager;
|
private final ILocationManager mILocationManager;
|
||||||
private final LocationExtras mLocationExtras = new LocationExtras();
|
private final LocationExtras mLocationExtras = new LocationExtras();
|
||||||
private final GnssStatusListenerHelper mListenerHelper;
|
private final GnssStatusListenerHelper mListenerHelper;
|
||||||
|
private final GnssSatelliteBlacklistHelper mGnssSatelliteBlacklistHelper;
|
||||||
private final GnssMeasurementsProvider mGnssMeasurementsProvider;
|
private final GnssMeasurementsProvider mGnssMeasurementsProvider;
|
||||||
private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
|
private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
|
||||||
private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
|
private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
|
||||||
@@ -577,6 +581,16 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
|
||||||
|
mHandler.post(()->{
|
||||||
|
native_set_satellite_blacklist(constellations, svids);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void subscriptionOrSimChanged(Context context) {
|
private void subscriptionOrSimChanged(Context context) {
|
||||||
if (DEBUG) Log.d(TAG, "received SIM related action: ");
|
if (DEBUG) Log.d(TAG, "received SIM related action: ");
|
||||||
TelephonyManager phone = (TelephonyManager)
|
TelephonyManager phone = (TelephonyManager)
|
||||||
@@ -869,7 +883,10 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
|||||||
};
|
};
|
||||||
mGnssMetrics = new GnssMetrics(mBatteryStats);
|
mGnssMetrics = new GnssMetrics(mBatteryStats);
|
||||||
|
|
||||||
mNtpTimeHelper = new NtpTimeHelper(mContext, Looper.myLooper(), this);
|
mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
|
||||||
|
mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
|
||||||
|
looper, this);
|
||||||
|
mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2900,6 +2917,8 @@ public class GnssLocationProvider implements LocationProviderInterface, InjectNt
|
|||||||
|
|
||||||
private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
|
private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
|
||||||
|
|
||||||
|
private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds);
|
||||||
|
|
||||||
// GNSS Batching
|
// GNSS Batching
|
||||||
private static native int native_get_batch_size();
|
private static native int native_get_batch_size();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package com.android.server.location;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.ContentObserver;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects blacklist change and updates the blacklist.
|
||||||
|
*/
|
||||||
|
class GnssSatelliteBlacklistHelper {
|
||||||
|
|
||||||
|
private static final String TAG = "GnssBlacklistHelper";
|
||||||
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
|
private static final String BLACKLIST_DELIMITER = ",";
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final GnssSatelliteBlacklistCallback mCallback;
|
||||||
|
|
||||||
|
interface GnssSatelliteBlacklistCallback {
|
||||||
|
void onUpdateSatelliteBlacklist(int[] constellations, int[] svids);
|
||||||
|
}
|
||||||
|
|
||||||
|
GnssSatelliteBlacklistHelper(Context context, Looper looper,
|
||||||
|
GnssSatelliteBlacklistCallback callback) {
|
||||||
|
mContext = context;
|
||||||
|
mCallback = callback;
|
||||||
|
ContentObserver contentObserver = new ContentObserver(new Handler(looper)) {
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
updateSatelliteBlacklist();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
mContext.getContentResolver().registerContentObserver(
|
||||||
|
Settings.Global.getUriFor(
|
||||||
|
Settings.Global.GNSS_SATELLITE_BLACKLIST),
|
||||||
|
true,
|
||||||
|
contentObserver, UserHandle.USER_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSatelliteBlacklist() {
|
||||||
|
ContentResolver resolver = mContext.getContentResolver();
|
||||||
|
String blacklist = Settings.Global.getString(
|
||||||
|
resolver,
|
||||||
|
Settings.Global.GNSS_SATELLITE_BLACKLIST);
|
||||||
|
if (blacklist == null) {
|
||||||
|
blacklist = "";
|
||||||
|
}
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, String.format("Update GNSS satellite blacklist: %s", blacklist));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> blacklistValues;
|
||||||
|
try {
|
||||||
|
blacklistValues = parseSatelliteBlacklist(blacklist);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Log.e(TAG, "Exception thrown when parsing blacklist string.", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blacklistValues.size() % 2 != 0) {
|
||||||
|
Log.e(TAG, "blacklist string has odd number of values."
|
||||||
|
+ "Aborting updateSatelliteBlacklist");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = blacklistValues.size() / 2;
|
||||||
|
int[] constellations = new int[length];
|
||||||
|
int[] svids = new int[length];
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
constellations[i] = blacklistValues.get(i * 2);
|
||||||
|
svids[i] = blacklistValues.get(i * 2 + 1);
|
||||||
|
}
|
||||||
|
mCallback.onUpdateSatelliteBlacklist(constellations, svids);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static List<Integer> parseSatelliteBlacklist(String blacklist) throws NumberFormatException {
|
||||||
|
String[] strings = blacklist.split(BLACKLIST_DELIMITER);
|
||||||
|
List<Integer> parsed = new ArrayList<>(strings.length);
|
||||||
|
for (String string : strings) {
|
||||||
|
string = string.trim();
|
||||||
|
if (!"".equals(string)) {
|
||||||
|
int value = Integer.parseInt(string);
|
||||||
|
if (value < 0) {
|
||||||
|
throw new NumberFormatException("Negative value is invalid.");
|
||||||
|
}
|
||||||
|
parsed.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -81,6 +81,7 @@ using android::hardware::Return;
|
|||||||
using android::hardware::Void;
|
using android::hardware::Void;
|
||||||
using android::hardware::hidl_vec;
|
using android::hardware::hidl_vec;
|
||||||
using android::hardware::hidl_death_recipient;
|
using android::hardware::hidl_death_recipient;
|
||||||
|
using android::hardware::gnss::V1_0::GnssConstellationType;
|
||||||
using android::hardware::gnss::V1_0::GnssLocation;
|
using android::hardware::gnss::V1_0::GnssLocation;
|
||||||
using android::hardware::gnss::V1_0::GnssLocationFlags;
|
using android::hardware::gnss::V1_0::GnssLocationFlags;
|
||||||
|
|
||||||
@@ -91,7 +92,6 @@ using android::hardware::gnss::V1_0::IAGnssRil;
|
|||||||
using android::hardware::gnss::V1_0::IAGnssRilCallback;
|
using android::hardware::gnss::V1_0::IAGnssRilCallback;
|
||||||
using android::hardware::gnss::V1_0::IGnssBatching;
|
using android::hardware::gnss::V1_0::IGnssBatching;
|
||||||
using android::hardware::gnss::V1_0::IGnssBatchingCallback;
|
using android::hardware::gnss::V1_0::IGnssBatchingCallback;
|
||||||
using android::hardware::gnss::V1_0::IGnssConfiguration;
|
|
||||||
using android::hardware::gnss::V1_0::IGnssDebug;
|
using android::hardware::gnss::V1_0::IGnssDebug;
|
||||||
using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
|
using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
|
||||||
using android::hardware::gnss::V1_0::IGnssGeofencing;
|
using android::hardware::gnss::V1_0::IGnssGeofencing;
|
||||||
@@ -108,6 +108,8 @@ using android::hidl::base::V1_0::IBase;
|
|||||||
|
|
||||||
using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
|
using IGnss_V1_0 = android::hardware::gnss::V1_0::IGnss;
|
||||||
using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
|
using IGnss_V1_1 = android::hardware::gnss::V1_1::IGnss;
|
||||||
|
using IGnssConfiguration_V1_0 = android::hardware::gnss::V1_0::IGnssConfiguration;
|
||||||
|
using IGnssConfiguration_V1_1 = android::hardware::gnss::V1_1::IGnssConfiguration;
|
||||||
using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
|
using IGnssMeasurement_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurement;
|
||||||
using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
|
using IGnssMeasurement_V1_1 = android::hardware::gnss::V1_1::IGnssMeasurement;
|
||||||
using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
|
using IGnssMeasurementCallback_V1_0 = android::hardware::gnss::V1_0::IGnssMeasurementCallback;
|
||||||
@@ -137,7 +139,8 @@ sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
|
|||||||
sp<IAGnss> agnssIface = nullptr;
|
sp<IAGnss> agnssIface = nullptr;
|
||||||
sp<IGnssBatching> gnssBatchingIface = nullptr;
|
sp<IGnssBatching> gnssBatchingIface = nullptr;
|
||||||
sp<IGnssDebug> gnssDebugIface = nullptr;
|
sp<IGnssDebug> gnssDebugIface = nullptr;
|
||||||
sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
|
sp<IGnssConfiguration_V1_0> gnssConfigurationIface = nullptr;
|
||||||
|
sp<IGnssConfiguration_V1_1> gnssConfigurationIface_V1_1 = nullptr;
|
||||||
sp<IGnssNi> gnssNiIface = nullptr;
|
sp<IGnssNi> gnssNiIface = nullptr;
|
||||||
sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
|
sp<IGnssMeasurement_V1_0> gnssMeasurementIface = nullptr;
|
||||||
sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
|
sp<IGnssMeasurement_V1_1> gnssMeasurementIface_V1_1 = nullptr;
|
||||||
@@ -1098,13 +1101,11 @@ struct GnssBatchingCallback : public IGnssBatchingCallback {
|
|||||||
* Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
|
* Methods from ::android::hardware::gps::V1_0::IGnssBatchingCallback
|
||||||
* follow.
|
* follow.
|
||||||
*/
|
*/
|
||||||
Return<void> gnssLocationBatchCb(
|
Return<void> gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations)
|
||||||
const ::android::hardware::hidl_vec<GnssLocation> & locations)
|
|
||||||
override;
|
override;
|
||||||
};
|
};
|
||||||
|
|
||||||
Return<void> GnssBatchingCallback::gnssLocationBatchCb(
|
Return<void> GnssBatchingCallback::gnssLocationBatchCb(const hidl_vec<GnssLocation> & locations) {
|
||||||
const ::android::hardware::hidl_vec<GnssLocation> & locations) {
|
|
||||||
JNIEnv* env = getJniEnv();
|
JNIEnv* env = getJniEnv();
|
||||||
|
|
||||||
jobjectArray jLocations = env->NewObjectArray(locations.size(),
|
jobjectArray jLocations = env->NewObjectArray(locations.size(),
|
||||||
@@ -1257,11 +1258,21 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass
|
|||||||
gnssNiIface = gnssNi;
|
gnssNiIface = gnssNi;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
|
if (gnssHal_V1_1 != nullptr) {
|
||||||
|
auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
|
||||||
if (!gnssConfiguration.isOk()) {
|
if (!gnssConfiguration.isOk()) {
|
||||||
ALOGD("Unable to get a handle to GnssConfiguration");
|
ALOGD("Unable to get a handle to GnssConfiguration");
|
||||||
} else {
|
} else {
|
||||||
gnssConfigurationIface = gnssConfiguration;
|
gnssConfigurationIface_V1_1 = gnssConfiguration;
|
||||||
|
gnssConfigurationIface = gnssConfigurationIface_V1_1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
auto gnssConfiguration_V1_0 = gnssHal->getExtensionGnssConfiguration();
|
||||||
|
if (!gnssConfiguration_V1_0.isOk()) {
|
||||||
|
ALOGD("Unable to get a handle to GnssConfiguration");
|
||||||
|
} else {
|
||||||
|
gnssConfigurationIface = gnssConfiguration_V1_0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
|
auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
|
||||||
@@ -1997,6 +2008,48 @@ static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_sele
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static jboolean android_location_GnssLocationProvider_set_satellite_blacklist(
|
||||||
|
JNIEnv* env, jobject, jintArray constellations, jintArray sv_ids) {
|
||||||
|
if (gnssConfigurationIface_V1_1 == nullptr) {
|
||||||
|
ALOGI("No GNSS Satellite Blacklist interface available");
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
jint *constellation_array = env->GetIntArrayElements(constellations, 0);
|
||||||
|
if (NULL == constellation_array) {
|
||||||
|
ALOGI("GetIntArrayElements returns NULL.");
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
jsize length = env->GetArrayLength(constellations);
|
||||||
|
|
||||||
|
jint *sv_id_array = env->GetIntArrayElements(sv_ids, 0);
|
||||||
|
if (NULL == sv_id_array) {
|
||||||
|
ALOGI("GetIntArrayElements returns NULL.");
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length != env->GetArrayLength(sv_ids)) {
|
||||||
|
ALOGI("Lengths of constellations and sv_ids are inconsistent.");
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hidl_vec<IGnssConfiguration_V1_1::BlacklistedSource> sources;
|
||||||
|
sources.resize(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
sources[i].constellation = static_cast<GnssConstellationType>(constellation_array[i]);
|
||||||
|
sources[i].svid = sv_id_array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
auto result = gnssConfigurationIface_V1_1->setBlacklist(sources);
|
||||||
|
if (result.isOk()) {
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
|
static jint android_location_GnssLocationProvider_get_batch_size(JNIEnv*, jclass) {
|
||||||
if (gnssBatchingIface == nullptr) {
|
if (gnssBatchingIface == nullptr) {
|
||||||
return 0; // batching not supported, size = 0
|
return 0; // batching not supported, size = 0
|
||||||
@@ -2185,6 +2238,9 @@ static const JNINativeMethod sMethods[] = {
|
|||||||
{"native_set_emergency_supl_pdn",
|
{"native_set_emergency_supl_pdn",
|
||||||
"(I)Z",
|
"(I)Z",
|
||||||
reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
|
reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
|
||||||
|
{"native_set_satellite_blacklist",
|
||||||
|
"([I[I)Z",
|
||||||
|
reinterpret_cast<void *>(android_location_GnssLocationProvider_set_satellite_blacklist)},
|
||||||
{"native_get_batch_size",
|
{"native_get_batch_size",
|
||||||
"()I",
|
"()I",
|
||||||
reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
|
reinterpret_cast<void *>(android_location_GnssLocationProvider_get_batch_size)},
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
package com.android.server.location;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.ContentObserver;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import com.android.server.testing.FrameworkRobolectricTestRunner;
|
||||||
|
import com.android.server.testing.SystemLoaderPackages;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.Shadows;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link GnssSatelliteBlacklistHelper}.
|
||||||
|
*/
|
||||||
|
@RunWith(FrameworkRobolectricTestRunner.class)
|
||||||
|
@Config(
|
||||||
|
manifest = Config.NONE,
|
||||||
|
shadows = {
|
||||||
|
},
|
||||||
|
sdk = 27
|
||||||
|
)
|
||||||
|
@SystemLoaderPackages({"com.android.server.location"})
|
||||||
|
@Presubmit
|
||||||
|
public class GnssSatelliteBlacklistHelperTest {
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private ContentResolver mContentResolver;
|
||||||
|
@Mock
|
||||||
|
private GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback mCallback;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
mContext = RuntimeEnvironment.application;
|
||||||
|
mContentResolver = mContext.getContentResolver();
|
||||||
|
new GnssSatelliteBlacklistHelper(mContext, Looper.myLooper(), mCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void blacklistOf2Satellites_callbackIsCalled() {
|
||||||
|
String blacklist = "3,0,5,24";
|
||||||
|
updateBlacklistAndVerifyCallbackIsCalled(blacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void blacklistWithSpaces_callbackIsCalled() {
|
||||||
|
String blacklist = "3, 11";
|
||||||
|
updateBlacklistAndVerifyCallbackIsCalled(blacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void emptyBlacklist_callbackIsCalled() {
|
||||||
|
String blacklist = "";
|
||||||
|
updateBlacklistAndVerifyCallbackIsCalled(blacklist);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void blacklistWithOddNumberOfValues_callbackIsNotCalled() {
|
||||||
|
String blacklist = "3,0,5";
|
||||||
|
updateBlacklistAndNotifyContentObserver(blacklist);
|
||||||
|
verify(mCallback, never()).onUpdateSatelliteBlacklist(any(int[].class), any(int[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void blacklistWithNegativeValue_callbackIsNotCalled() {
|
||||||
|
String blacklist = "3,-11";
|
||||||
|
updateBlacklistAndNotifyContentObserver(blacklist);
|
||||||
|
verify(mCallback, never()).onUpdateSatelliteBlacklist(any(int[].class), any(int[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void blacklistWithNonDigitCharacter_callbackIsNotCalled() {
|
||||||
|
String blacklist = "3,1a,5,11";
|
||||||
|
updateBlacklistAndNotifyContentObserver(blacklist);
|
||||||
|
verify(mCallback, never()).onUpdateSatelliteBlacklist(any(int[].class), any(int[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBlacklistAndNotifyContentObserver(String blacklist) {
|
||||||
|
Settings.Global.putString(mContentResolver,
|
||||||
|
Settings.Global.GNSS_SATELLITE_BLACKLIST, blacklist);
|
||||||
|
notifyContentObserverFor(Settings.Global.GNSS_SATELLITE_BLACKLIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBlacklistAndVerifyCallbackIsCalled(String blacklist) {
|
||||||
|
updateBlacklistAndNotifyContentObserver(blacklist);
|
||||||
|
|
||||||
|
ArgumentCaptor<int[]> constellationsCaptor = ArgumentCaptor.forClass(int[].class);
|
||||||
|
ArgumentCaptor<int[]> svIdsCaptor = ArgumentCaptor.forClass(int[].class);
|
||||||
|
verify(mCallback).onUpdateSatelliteBlacklist(constellationsCaptor.capture(),
|
||||||
|
svIdsCaptor.capture());
|
||||||
|
|
||||||
|
int[] constellations = constellationsCaptor.getValue();
|
||||||
|
int[] svIds = svIdsCaptor.getValue();
|
||||||
|
List<Integer> values = GnssSatelliteBlacklistHelper.parseSatelliteBlacklist(blacklist);
|
||||||
|
assertThat(values.size()).isEqualTo(constellations.length * 2);
|
||||||
|
assertThat(svIds.length).isEqualTo(constellations.length);
|
||||||
|
for (int i = 0; i < constellations.length; i++) {
|
||||||
|
assertThat(constellations[i]).isEqualTo(values.get(i * 2));
|
||||||
|
assertThat(svIds[i]).isEqualTo(values.get(i * 2 + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void notifyContentObserverFor(String globalSetting) {
|
||||||
|
Collection<ContentObserver> contentObservers =
|
||||||
|
Shadows.shadowOf(RuntimeEnvironment.application.getContentResolver())
|
||||||
|
.getContentObservers(Settings.Global.getUriFor(globalSetting));
|
||||||
|
assertThat(contentObservers).isNotEmpty();
|
||||||
|
contentObservers.iterator().next().onChange(false /* selfChange */);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user