summaryrefslogtreecommitdiffstats
path: root/location/java
diff options
context:
space:
mode:
authordestradaa <destradaa@google.com>2015-01-30 16:11:20 -0800
committerdestradaa <destradaa@google.com>2015-02-03 13:17:14 -0800
commit6bde4683ae1f70f7b5e53f853b6a7479bcebd5d5 (patch)
tree3804ff0a8b55fff0a506d7f5b2328c0e355d68ba /location/java
parentad575295918dba197dcf61bfb81d56348ed1f073 (diff)
downloadframeworks_base-6bde4683ae1f70f7b5e53f853b6a7479bcebd5d5.zip
frameworks_base-6bde4683ae1f70f7b5e53f853b6a7479bcebd5d5.tar.gz
frameworks_base-6bde4683ae1f70f7b5e53f853b6a7479bcebd5d5.tar.bz2
Reduce memory usage of GpsStatus objects.
A simple GpsStatus object uses 9K of space, given that it initializes an array of 255 GpsSatellite objects. This change reduces the memory footprint in the average case, and keeps the semantics of the API and its GpsSatellite sibling objects without any changes. In a best case scenario it brings the memory usage per object to 1K. It's likely in most cases that only 20-50 satellites will be in view. So the usage should not exceeed half of the original memory usage. It was considered to keep the internal array but a SparseArray provided bigger memory savings in the test scenario of ~700B. Change-Id: Ie2d2144d776a74d4904a08c0d6c5aec6d3bba7cc
Diffstat (limited to 'location/java')
-rw-r--r--location/java/android/location/GpsSatellite.java18
-rw-r--r--location/java/android/location/GpsStatus.java97
2 files changed, 79 insertions, 36 deletions
diff --git a/location/java/android/location/GpsSatellite.java b/location/java/android/location/GpsSatellite.java
index 17af4a6..820f574 100644
--- a/location/java/android/location/GpsSatellite.java
+++ b/location/java/android/location/GpsSatellite.java
@@ -40,13 +40,17 @@ public final class GpsSatellite {
* cached GpsStatus instance to the client's copy.
*/
void setStatus(GpsSatellite satellite) {
- mValid = satellite.mValid;
- mHasEphemeris = satellite.mHasEphemeris;
- mHasAlmanac = satellite.mHasAlmanac;
- mUsedInFix = satellite.mUsedInFix;
- mSnr = satellite.mSnr;
- mElevation = satellite.mElevation;
- mAzimuth = satellite.mAzimuth;
+ if (satellite == null) {
+ mValid = false;
+ } else {
+ mValid = satellite.mValid;
+ mHasEphemeris = satellite.mHasEphemeris;
+ mHasAlmanac = satellite.mHasAlmanac;
+ mUsedInFix = satellite.mUsedInFix;
+ mSnr = satellite.mSnr;
+ mElevation = satellite.mElevation;
+ mAzimuth = satellite.mAzimuth;
+ }
}
/**
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 4af55a6..323f326 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -16,6 +16,8 @@
package android.location;
+import android.util.SparseArray;
+
import java.util.Iterator;
import java.util.NoSuchElementException;
@@ -29,20 +31,24 @@ public final class GpsStatus {
/* These package private values are modified by the LocationManager class */
private int mTimeToFirstFix;
- private GpsSatellite mSatellites[] = new GpsSatellite[NUM_SATELLITES];
+ private final SparseArray<GpsSatellite> mSatellites = new SparseArray<>();
private final class SatelliteIterator implements Iterator<GpsSatellite> {
- private GpsSatellite[] mSatellites;
- int mIndex = 0;
+ private final SparseArray<GpsSatellite> mSatellites;
+ private final int mSatellitesCount;
+
+ private int mIndex = 0;
- SatelliteIterator(GpsSatellite[] satellites) {
+ SatelliteIterator(SparseArray<GpsSatellite> satellites) {
mSatellites = satellites;
+ mSatellitesCount = satellites.size();
}
public boolean hasNext() {
- for (int i = mIndex; i < mSatellites.length; i++) {
- if (mSatellites[i].mValid) {
+ for (; mIndex < mSatellitesCount; ++mIndex) {
+ GpsSatellite satellite = mSatellites.valueAt(mIndex);
+ if (satellite.mValid) {
return true;
}
}
@@ -50,8 +56,9 @@ public final class GpsStatus {
}
public GpsSatellite next() {
- while (mIndex < mSatellites.length) {
- GpsSatellite satellite = mSatellites[mIndex++];
+ while (mIndex < mSatellitesCount) {
+ GpsSatellite satellite = mSatellites.valueAt(mIndex);
+ ++mIndex;
if (satellite.mValid) {
return satellite;
}
@@ -106,7 +113,7 @@ public final class GpsStatus {
* <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS}
* </ul>
*
- * When this method is called, the client should call
+ * When this method is called, the client should call
* {@link LocationManager#getGpsStatus} to get additional
* status information.
*
@@ -127,11 +134,8 @@ public final class GpsStatus {
void onNmeaReceived(long timestamp, String nmea);
}
- GpsStatus() {
- for (int i = 0; i < mSatellites.length; i++) {
- mSatellites[i] = new GpsSatellite(i + 1);
- }
- }
+ // For API-compat a public ctor() is not available
+ GpsStatus() {}
/**
* Used internally within {@link LocationManager} to copy GPS status
@@ -141,18 +145,17 @@ public final class GpsStatus {
synchronized void setStatus(int svCount, int[] prns, float[] snrs,
float[] elevations, float[] azimuths, int ephemerisMask,
int almanacMask, int usedInFixMask) {
- int i;
+ clearSatellites();
+ for (int i = 0; i < svCount; i++) {
+ int prn = prns[i];
+ int prnShift = (1 << (prn - 1));
+ if (prn > 0 && prn <= NUM_SATELLITES) {
+ GpsSatellite satellite = mSatellites.get(prn);
+ if (satellite == null) {
+ satellite = new GpsSatellite(prn);
+ mSatellites.put(prn, satellite);
+ }
- for (i = 0; i < mSatellites.length; i++) {
- mSatellites[i].mValid = false;
- }
-
- for (i = 0; i < svCount; i++) {
- int prn = prns[i] - 1;
- int prnShift = (1 << prn);
- if (prn >= 0 && prn < mSatellites.length) {
- GpsSatellite satellite = mSatellites[prn];
-
satellite.mValid = true;
satellite.mSnr = snrs[i];
satellite.mElevation = elevations[i];
@@ -172,10 +175,38 @@ public final class GpsStatus {
*/
void setStatus(GpsStatus status) {
mTimeToFirstFix = status.getTimeToFirstFix();
+ clearSatellites();
+
+ SparseArray<GpsSatellite> otherSatellites = status.mSatellites;
+ int otherSatellitesCount = otherSatellites.size();
+ int satelliteIndex = 0;
+ // merge both sparse arrays, note that we have already invalidated the elements in the
+ // receiver array
+ for (int i = 0; i < otherSatellitesCount; ++i) {
+ GpsSatellite otherSatellite = otherSatellites.valueAt(i);
+ int otherSatellitePrn = otherSatellite.getPrn();
+
+ int satellitesCount = mSatellites.size();
+ while (satelliteIndex < satellitesCount
+ && mSatellites.valueAt(satelliteIndex).getPrn() < otherSatellitePrn) {
+ ++satelliteIndex;
+ }
- for (int i = 0; i < mSatellites.length; i++) {
- mSatellites[i].setStatus(status.mSatellites[i]);
- }
+ if (satelliteIndex < mSatellites.size()) {
+ GpsSatellite satellite = mSatellites.valueAt(satelliteIndex);
+ if (satellite.getPrn() == otherSatellitePrn) {
+ satellite.setStatus(otherSatellite);
+ } else {
+ satellite = new GpsSatellite(otherSatellitePrn);
+ satellite.setStatus(otherSatellite);
+ mSatellites.put(otherSatellitePrn, satellite);
+ }
+ } else {
+ GpsSatellite satellite = new GpsSatellite(otherSatellitePrn);
+ satellite.setStatus(otherSatellite);
+ mSatellites.append(otherSatellitePrn, satellite);
+ }
+ }
}
void setTimeToFirstFix(int ttff) {
@@ -183,7 +214,7 @@ public final class GpsStatus {
}
/**
- * Returns the time required to receive the first fix since the most recent
+ * Returns the time required to receive the first fix since the most recent
* restart of the GPS engine.
*
* @return time to first fix in milliseconds
@@ -211,4 +242,12 @@ public final class GpsStatus {
public int getMaxSatellites() {
return NUM_SATELLITES;
}
+
+ private void clearSatellites() {
+ int satellitesCount = mSatellites.size();
+ for (int i = 0; i < satellitesCount; i++) {
+ GpsSatellite satellite = mSatellites.valueAt(i);
+ satellite.mValid = false;
+ }
+ }
}