From b13605bb30e94ce912dcb4970779f7cd391505ac Mon Sep 17 00:00:00 2001 From: DIPARTH SHAH Date: Sat, 20 Feb 2016 00:54:07 -0800 Subject: [PATCH 1/6] GENERIC MEDIATEK : GPS BRINGUP MT6582 || MT6592 --- location/java/android/location/GpsStatus.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java index 4af55a65b0e..8ae76127116 100644 --- a/location/java/android/location/GpsStatus.java +++ b/location/java/android/location/GpsStatus.java @@ -177,6 +177,37 @@ void setStatus(GpsStatus status) { mSatellites[i].setStatus(status.mSatellites[i]); } } + + /** + * Used internally within {@link LocationManager} to copy GNSS status + * data from the Location Manager Service to its cached GnssStatus instance. + * Is synchronized to ensure that GNSS status updates are atomic. + */ + synchronized void setGnssStatus(int svCount, int[] prns, float[] snrs, + float[] elevations, float[] azimuths, boolean[] ephemeris, + boolean[] almanac, boolean[] usedInFix) { + int i; + + for (i = 0; i < mSatellites.length; i++) { + mSatellites[i].mValid = false; + } + + for (i = 0; i < svCount; i++) { + int prn = prns[i] - 1; + if (prn >= 0 && prn < mSatellites.length) { + GpsSatellite satellite = mSatellites[prn]; + + satellite.mValid = true; + satellite.mSnr = snrs[i]; + satellite.mElevation = elevations[i]; + satellite.mAzimuth = azimuths[i]; + satellite.mHasEphemeris = ephemeris[i]; + satellite.mHasAlmanac = almanac[i]; + satellite.mUsedInFix = usedInFix[i]; + } + } + } + void setTimeToFirstFix(int ttff) { mTimeToFirstFix = ttff; From 6b03d2f36c31119d2f6c52dd071b0e813827342f Mon Sep 17 00:00:00 2001 From: DIPARTH SHAH Date: Sat, 20 Feb 2016 00:57:38 -0800 Subject: [PATCH 2/6] GPS : GENERIC MTK 82-92 --- location/java/android/location/IGpsStatusListener.aidl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/location/java/android/location/IGpsStatusListener.aidl b/location/java/android/location/IGpsStatusListener.aidl index 62b1c6b9b35..b80619ab7ff 100644 --- a/location/java/android/location/IGpsStatusListener.aidl +++ b/location/java/android/location/IGpsStatusListener.aidl @@ -29,5 +29,8 @@ oneway interface IGpsStatusListener void onSvStatusChanged(int svCount, in int[] prns, in float[] snrs, in float[] elevations, in float[] azimuths, int ephemerisMask, int almanacMask, int usedInFixMask); + void onGnssSvStatusChanged(int svCount, in int[] prns, in float[] snrs, + in float[] elevations, in float[] azimuths, + in boolean[] ephemeris, in boolean[] almanac, in boolean[] usedInFix); void onNmeaReceived(long timestamp, String nmea); } From 73d008f94ca9422c6d8c80d17a0011642e7fa719 Mon Sep 17 00:00:00 2001 From: DIPARTH SHAH Date: Sat, 20 Feb 2016 01:01:51 -0800 Subject: [PATCH 3/6] GPS :: LOCATION MANAGER :: GENERIC MEDIATEK --- .../java/android/location/LocationManager.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index 0eb4fdc6cb2..c6922b5a122 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -1432,6 +1432,22 @@ public void onFirstFix(int ttff) { } @Override + public void onGnssSvStatusChanged(int svCount, int[] prns, float[] snrs, + float[] elevations, float[] azimuths, boolean[] ephemeris, + boolean[] almanac, boolean[] usedInFix) { + if (mListener != null) { + mGpsStatus.setGnssStatus(svCount, prns, snrs, elevations, azimuths, + ephemeris, almanac, usedInFix); + + Message msg = Message.obtain(); + msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS; + // remove any SV status messages already in the queue + mGpsHandler.removeMessages(GpsStatus.GPS_EVENT_SATELLITE_STATUS); + mGpsHandler.sendMessage(msg); + } + } + + @Override public void onSvStatusChanged(int svCount, int[] prns, float[] snrs, float[] elevations, float[] azimuths, int ephemerisMask, int almanacMask, int usedInFixMask) { From f73a48e429d4143933c1f77a4298032ed0fd4af5 Mon Sep 17 00:00:00 2001 From: DIPARTH SHAH Date: Sat, 20 Feb 2016 01:13:09 -0800 Subject: [PATCH 4/6] GPS !! --- .../server/location/GpsLocationProvider.java | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java index 4e58c6c2821..11118941bcf 100644 --- a/services/core/java/com/android/server/location/GpsLocationProvider.java +++ b/services/core/java/com/android/server/location/GpsLocationProvider.java @@ -1677,7 +1677,56 @@ private void reportStatus(int status) { /** * called from native code to update SV info - */ + */ private void reportGnssSvStatus() { + int svCount = native_read_gnss_sv_status(mGnssSvs, mGnssSnrs, mGnssSvElevations + , mGnssSvAzimuths, mGnssSvEphemeris, mGnssSvAlmanac, mGnssSvInFix); + mListenerHelper.onGnssSvStatusChanged( + svCount, + mGnssSvs, + mGnssSnrs, + mGnssSvElevations, + mGnssSvAzimuths, + mGnssSvEphemeris, + mGnssSvAlmanac, + mGnssSvInFix); + + if (VERBOSE) { + Log.v(TAG, "GNSS SV count: " + svCount + + " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + + " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); + for (int i = 0; i < svCount; i++) { + Log.v(TAG, "sv: " + mGnssSvs[i] + + " snr: " + mGnssSnrs[i] / 10 + + " elev: " + mGnssSvElevations[i] + + " azimuth: " + mGnssSvAzimuths[i] + + ((mGnssSvEphemeris[i]) ? " E" : " ") + + ((mGnssSvAlmanac[i]) ? " A" : " ") + + ((mGnssSvInFix[i]) ? " U" : " ")); + } + } + int svFixCount = 0; + for (boolean value : mGnssSvInFix) { + if (value) { + svFixCount++; + } + } + updateStatus(mStatus, svFixCount); + + + if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && + System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { + // send an intent to notify that the GPS is no longer receiving fixes. + Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); + intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false); + mContext.sendBroadcastAsUser(intent, UserHandle.ALL); + updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); + } + } + + /** + * called from native code to update SV info + */ + private void reportSvStatus() { int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); mListenerHelper.onSvStatusChanged( @@ -2348,6 +2397,7 @@ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { // for GPS SV statistics private static final int MAX_SVS = 32; + private static final int MAX_GNSS_SVS = 256; private static final int EPHEMERIS_MASK = 0; private static final int ALMANAC_MASK = 1; private static final int USED_FOR_FIX_MASK = 2; @@ -2359,6 +2409,16 @@ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { private float mSvAzimuths[] = new float[MAX_SVS]; private int mSvMasks[] = new int[3]; private int mSvCount; + + // preallocated arrays, to avoid memory allocation in reportStatus() + private int mGnssSvs[] = new int[MAX_GNSS_SVS]; + private float mGnssSnrs[] = new float[MAX_GNSS_SVS]; + private float mGnssSvElevations[] = new float[MAX_GNSS_SVS]; + private float mGnssSvAzimuths[] = new float[MAX_GNSS_SVS]; + private boolean mGnssSvEphemeris[] = new boolean[MAX_GNSS_SVS]; + private boolean mGnssSvAlmanac[] = new boolean[MAX_GNSS_SVS]; + private boolean mGnssSvInFix[] = new boolean[MAX_GNSS_SVS]; + // preallocated to avoid memory allocation in reportNmea() private byte[] mNmeaBuffer = new byte[120]; @@ -2379,6 +2439,9 @@ private native int native_read_sv_status(int[] svs, float[] snrs, float[] elevations, float[] azimuths, int[] masks); private native int native_read_nmea(byte[] buffer, int bufferSize); private native void native_inject_location(double latitude, double longitude, float accuracy); + private native int native_read_gnss_sv_status(int[] svs, float[] snrs, + float[] elevations, float[] azimuths, boolean[] ephemeris, boolean[] almanac, + boolean[] infix); // XTRA Support private native void native_inject_time(long time, long timeReference, int uncertainty); From 412e4c2252ca42bb3de1a62222e3a1f1e79f59a8 Mon Sep 17 00:00:00 2001 From: DIPARTH SHAH Date: Sat, 20 Feb 2016 01:18:23 -0800 Subject: [PATCH 5/6] ANOTHER GPS FIX FOR MEDIATEK --- .../location/GpsStatusListenerHelper.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/services/core/java/com/android/server/location/GpsStatusListenerHelper.java b/services/core/java/com/android/server/location/GpsStatusListenerHelper.java index 376b4a534ff..2d97b6d9f00 100644 --- a/services/core/java/com/android/server/location/GpsStatusListenerHelper.java +++ b/services/core/java/com/android/server/location/GpsStatusListenerHelper.java @@ -104,6 +104,32 @@ public void execute(IGpsStatusListener listener) throws RemoteException { foreach(operation); } + public void onGnssSvStatusChanged( + final int svCount, + final int[] prns, + final float[] snrs, + final float[] elevations, + final float[] azimuths, + final boolean[] ephemeris, + final boolean[] almanac, + final boolean[] usedInFix) { + Operation operation = new Operation() { + @Override + public void execute(IGpsStatusListener listener) throws RemoteException { + listener.onGnssSvStatusChanged( + svCount, + prns, + snrs, + elevations, + azimuths, + ephemeris, + almanac, + usedInFix); + } + }; + + foreach(operation); + } public void onNmeaReceived(final long timestamp, final String nmea) { Operation operation = new Operation() { @Override From 4520691be589524de3af60b9224db7d3ea4e3dff Mon Sep 17 00:00:00 2001 From: DIPARTH SHAH Date: Sat, 20 Feb 2016 01:39:30 -0800 Subject: [PATCH 6/6] GPS FOR GENERIC MTK --- ...id_server_location_GpsLocationProvider.cpp | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp index 0d3fdf6ac38..eaeff49b68c 100644 --- a/services/core/jni/com_android_server_location_GpsLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GpsLocationProvider.cpp @@ -39,6 +39,7 @@ static jobject mCallbacksObj = NULL; static jmethodID method_reportLocation; static jmethodID method_reportStatus; static jmethodID method_reportSvStatus; +static jmethodID method_reportGnssSvStatus; static jmethodID method_reportAGpsStatus; static jmethodID method_reportNmea; static jmethodID method_setEngineCapabilities; @@ -69,6 +70,7 @@ static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL; // temporary storage for GPS callbacks static GpsSvStatus sGpsSvStatus; +static GnssSvStatus sGnssSvStatus; static const char* sNmeaString; static int sNmeaStringLength; @@ -110,6 +112,14 @@ static void sv_status_callback(GpsSvStatus* sv_status) checkAndClearExceptionFromCallback(env, __FUNCTION__); } +static void gnss_sv_status_callback(GnssSvStatus* sv_status) + { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + memcpy(&sGnssSvStatus, sv_status, sizeof(sGnssSvStatus)); + env->CallVoidMethod(mCallbacksObj, method_reportGnssSvStatus); + checkAndClearExceptionFromCallback(env, __FUNCTION__); + } + static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length) { JNIEnv* env = AndroidRuntime::getJNIEnv(); @@ -156,6 +166,7 @@ GpsCallbacks sGpsCallbacks = { location_callback, status_callback, sv_status_callback, + gnss_sv_status_callback, nmea_callback, set_capabilities_callback, acquire_wakelock_callback, @@ -446,6 +457,7 @@ static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V"); method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V"); method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V"); + method_reportGnssSvStatus = env->GetMethodID(clazz, "reportGnssSvStatus", "()V"); method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V"); method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V"); method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V"); @@ -601,6 +613,12 @@ static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, job jintArray maskArray) { // this should only be called from within a call to reportSvStatus + + size_t status_size = sGpsSvStatus.size; + if (status_size != sizeof(GpsSvStatus)) { + jniThrowException(env, "java/lang/IllegalArgumentException ", "size wrong"); + return (jint)0; + } jint* prns = env->GetIntArrayElements(prnArray, 0); jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); @@ -627,6 +645,48 @@ static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, job return (jint) num_svs; } +static jint android_location_GpsLocationProvider_read_gnss_sv_status(JNIEnv* env, jobject obj, + jintArray prnArray, jfloatArray snrArray, jfloatArray elevArray, jfloatArray azumArray, + jbooleanArray ephmArray,jbooleanArray almArray,jbooleanArray fixArray) + { + // this should only be called from within a call to reportGnssSvStatus + size_t status_size = sGnssSvStatus.size; + if (status_size != sizeof(GnssSvStatus)) { + jniThrowException(env, "java/lang/IllegalArgumentException ", "size wrong"); + return (jint)0; + } + + jint* prns = env->GetIntArrayElements(prnArray, 0); + jfloat* snrs = env->GetFloatArrayElements(snrArray, 0); + jfloat* elev = env->GetFloatArrayElements(elevArray, 0); + jfloat* azim = env->GetFloatArrayElements(azumArray, 0); + jboolean* ephm = env->GetBooleanArrayElements(ephmArray, 0); + jboolean* alm = env->GetBooleanArrayElements(almArray, 0); + jboolean* fix = env->GetBooleanArrayElements(fixArray, 0); + + int num_svs = sGnssSvStatus.num_svs; + for (int i = 0; i < num_svs; i++) { + prns[i] = sGnssSvStatus.sv_list[i].prn; + snrs[i] = sGnssSvStatus.sv_list[i].snr; + elev[i] = sGnssSvStatus.sv_list[i].elevation; + azim[i] = sGnssSvStatus.sv_list[i].azimuth; + ephm[i] = sGnssSvStatus.sv_list[i].has_ephemeris; + alm[i] = sGnssSvStatus.sv_list[i].has_almanac; + fix[i] = sGnssSvStatus.sv_list[i].used_in_fix; + } + + env->ReleaseIntArrayElements(prnArray, prns, 0); + env->ReleaseFloatArrayElements(snrArray, snrs, 0); + env->ReleaseFloatArrayElements(elevArray, elev, 0); + env->ReleaseFloatArrayElements(azumArray, azim, 0); + env->ReleaseBooleanArrayElements(ephmArray, ephm, 0); + env->ReleaseBooleanArrayElements(almArray, alm, 0); + env->ReleaseBooleanArrayElements(fixArray, fix, 0); + + return (jint) num_svs; + } + + static void android_location_GpsLocationProvider_agps_set_reference_location_cellid(JNIEnv* env, jobject obj, jint type, jint mcc, jint mnc, jint lac, jint psc, jint cid) { @@ -1517,6 +1577,10 @@ static JNINativeMethod sMethods[] = { {"native_configuration_update", "(Ljava/lang/String;)V", (void*)android_location_GpsLocationProvider_configuration_update}, + {"native_read_gnss_sv_status", + "([I[F[F[F[Z[Z[Z)I", + (void*) android_location_GpsLocationProvider_read_gnss_sv_status}, + }; int register_android_server_location_GpsLocationProvider(JNIEnv* env)