diff --git a/android/location/AbstractListenerManager.java b/android/location/AbstractListenerManager.java
new file mode 100644
index 0000000..36b8689
--- /dev/null
+++ b/android/location/AbstractListenerManager.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * A base class to manage listeners that have a 1:N -> source:listener relationship.
+ *
+ * @hide
+ */
+abstract class AbstractListenerManager<TRequest, TListener> {
+
+    private static class Registration<TRequest, TListener> {
+        private final Executor mExecutor;
+        @Nullable private TRequest mRequest;
+        @Nullable private volatile TListener mListener;
+
+        private Registration(@Nullable TRequest request, Executor executor, TListener listener) {
+            Preconditions.checkArgument(listener != null, "invalid null listener/callback");
+            Preconditions.checkArgument(executor != null, "invalid null executor");
+            mExecutor = executor;
+            mListener = listener;
+            mRequest = request;
+        }
+
+        @Nullable
+        public TRequest getRequest() {
+            return mRequest;
+        }
+
+        private void unregister() {
+            mRequest = null;
+            mListener = null;
+        }
+
+        private void execute(Consumer<TListener> operation) {
+            mExecutor.execute(
+                    obtainRunnable(Registration<TRequest, TListener>::accept, this, operation)
+                            .recycleOnUse());
+        }
+
+        private void accept(Consumer<TListener> operation) {
+            TListener listener = mListener;
+            if (listener == null) {
+                return;
+            }
+
+            // we may be under the binder identity if a direct executor is used
+            long identity = Binder.clearCallingIdentity();
+            try {
+                operation.accept(listener);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private volatile ArrayMap<Object, Registration<TRequest, TListener>> mListeners =
+            new ArrayMap<>();
+
+    @GuardedBy("mLock")
+    @Nullable
+    private TRequest mMergedRequest;
+
+    public boolean addListener(@NonNull TListener listener, @NonNull Handler handler)
+            throws RemoteException {
+        return addInternal(/* request= */ null, listener, handler);
+    }
+
+    public boolean addListener(@NonNull TListener listener, @NonNull Executor executor)
+            throws RemoteException {
+        return addInternal(/* request= */ null, listener, executor);
+    }
+
+    public boolean addListener(@Nullable TRequest request, @NonNull TListener listener,
+            @NonNull Handler handler) throws RemoteException {
+        return addInternal(request, listener, handler);
+    }
+
+    public boolean addListener(@Nullable TRequest request, @NonNull TListener listener,
+            @NonNull Executor executor) throws RemoteException {
+        return addInternal(request, listener, executor);
+    }
+
+    protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener,
+            @NonNull Handler handler) throws RemoteException {
+        return addInternal(request, listener, new HandlerExecutor(handler));
+    }
+
+    protected final boolean addInternal(@Nullable TRequest request, @NonNull Object listener,
+            @NonNull Executor executor)
+            throws RemoteException {
+        Preconditions.checkArgument(listener != null, "invalid null listener/callback");
+        return addInternal(listener, new Registration<>(request, executor, convertKey(listener)));
+    }
+
+    private boolean addInternal(Object key, Registration<TRequest, TListener> registration)
+            throws RemoteException {
+        Preconditions.checkNotNull(registration);
+
+        synchronized (mLock) {
+            boolean initialRequest = mListeners.isEmpty();
+
+            ArrayMap<Object, Registration<TRequest, TListener>> newListeners = new ArrayMap<>(
+                    mListeners.size() + 1);
+            newListeners.putAll(mListeners);
+            Registration<TRequest, TListener> oldRegistration = newListeners.put(key,
+                    registration);
+            mListeners = newListeners;
+
+            if (oldRegistration != null) {
+                oldRegistration.unregister();
+            }
+            TRequest merged = mergeRequests();
+
+            if (initialRequest || !Objects.equals(merged, mMergedRequest)) {
+                mMergedRequest = merged;
+                if (!initialRequest) {
+                    unregisterService();
+                }
+                registerService(mMergedRequest);
+            }
+
+            return true;
+        }
+    }
+
+    public void removeListener(Object listener) throws RemoteException {
+        synchronized (mLock) {
+            ArrayMap<Object, Registration<TRequest, TListener>> newListeners = new ArrayMap<>(
+                    mListeners);
+            Registration<TRequest, TListener> oldRegistration = newListeners.remove(listener);
+            mListeners = newListeners;
+
+            if (oldRegistration == null) {
+                return;
+            }
+            oldRegistration.unregister();
+
+            boolean lastRequest = mListeners.isEmpty();
+            TRequest merged = lastRequest ? null : mergeRequests();
+            boolean newRequest = !lastRequest && !Objects.equals(merged, mMergedRequest);
+
+            if (lastRequest || newRequest) {
+                unregisterService();
+                mMergedRequest = merged;
+                if (newRequest) {
+                    registerService(mMergedRequest);
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    protected TListener convertKey(@NonNull Object listener) {
+        return (TListener) listener;
+    }
+
+    protected abstract boolean registerService(TRequest request) throws RemoteException;
+    protected abstract void unregisterService() throws RemoteException;
+
+    @Nullable
+    protected TRequest merge(@NonNull TRequest[] requests) {
+        for (TRequest request : requests) {
+            Preconditions.checkArgument(request == null,
+                    "merge() has to be overridden for non-null requests.");
+        }
+        return null;
+    }
+
+    protected void execute(Consumer<TListener> operation) {
+        for (Registration<TRequest, TListener> registration : mListeners.values()) {
+            registration.execute(operation);
+        }
+    }
+
+    @GuardedBy("mLock")
+    @SuppressWarnings("unchecked")
+    @Nullable
+    private TRequest mergeRequests() {
+        Preconditions.checkState(Thread.holdsLock(mLock));
+
+        if (mListeners.isEmpty()) {
+            return null;
+        }
+
+        if (mListeners.size() == 1) {
+            return mListeners.valueAt(0).getRequest();
+        }
+
+        TRequest[] requests = (TRequest[]) new Object[mListeners.size()];
+        for (int index = 0; index < mListeners.size(); index++) {
+            requests[index] = mListeners.valueAt(index).getRequest();
+        }
+        return merge(requests);
+    }
+}
diff --git a/android/location/Address.java b/android/location/Address.java
new file mode 100644
index 0000000..bb97c78
--- /dev/null
+++ b/android/location/Address.java
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2007 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.location;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class representing an Address, i.e, a set of Strings describing a location.
+ *
+ * The address format is a simplified version of xAL (eXtensible Address Language)
+ * http://www.oasis-open.org/committees/ciq/ciq.html#6
+ */
+public class Address implements Parcelable {
+
+    private Locale mLocale;
+
+    private String mFeatureName;
+    private HashMap<Integer, String> mAddressLines;
+    private int mMaxAddressLineIndex = -1;
+    private String mAdminArea;
+    private String mSubAdminArea;
+    private String mLocality;
+    private String mSubLocality;
+    private String mThoroughfare;
+    private String mSubThoroughfare;
+    private String mPremises;
+    private String mPostalCode;
+    private String mCountryCode;
+    private String mCountryName;
+    private double mLatitude;
+    private double mLongitude;
+    private boolean mHasLatitude = false;
+    private boolean mHasLongitude = false;
+    private String mPhone;
+    private String mUrl;
+    private Bundle mExtras = null;
+
+    /**
+     * Constructs a new Address object set to the given Locale and with all
+     * other fields initialized to null or false.
+     */
+    public Address(Locale locale) {
+        mLocale = locale;
+    }
+
+    /**
+     * Returns the Locale associated with this address.
+     */
+    public Locale getLocale() {
+        return mLocale;
+    }
+
+    /**
+     * Returns the largest index currently in use to specify an address line.
+     * If no address lines are specified, -1 is returned.
+     */
+    public int getMaxAddressLineIndex() {
+        return mMaxAddressLineIndex;
+    }
+
+    /**
+     * Returns a line of the address numbered by the given index
+     * (starting at 0), or null if no such line is present.
+     *
+     * @throws IllegalArgumentException if index < 0
+     */
+    public String getAddressLine(int index) {
+        if (index < 0) {
+            throw new IllegalArgumentException("index = " + index + " < 0");
+        }
+        return mAddressLines == null? null :  mAddressLines.get(index);
+    }
+
+    /**
+     * Sets the line of the address numbered by index (starting at 0) to the
+     * given String, which may be null.
+     *
+     * @throws IllegalArgumentException if index < 0
+     */
+    public void setAddressLine(int index, String line) {
+        if (index < 0) {
+            throw new IllegalArgumentException("index = " + index + " < 0");
+        }
+        if (mAddressLines == null) {
+            mAddressLines = new HashMap<Integer, String>();
+        }
+        mAddressLines.put(index, line);
+
+        if (line == null) {
+            // We've eliminated a line, recompute the max index
+            mMaxAddressLineIndex = -1;
+            for (Integer i : mAddressLines.keySet()) {
+                mMaxAddressLineIndex = Math.max(mMaxAddressLineIndex, i);
+            }
+        } else {
+            mMaxAddressLineIndex = Math.max(mMaxAddressLineIndex, index);
+        }
+    }
+
+    /**
+     * Returns the feature name of the address, for example, "Golden Gate Bridge", or null
+     * if it is unknown
+     */
+    public String getFeatureName() {
+        return mFeatureName;
+    }
+
+    /**
+     * Sets the feature name of the address to the given String, which may be null
+     */
+    public void setFeatureName(String featureName) {
+        mFeatureName = featureName;
+    }
+
+    /**
+     * Returns the administrative area name of the address, for example, "CA", or null if
+     * it is unknown
+     */
+    public String getAdminArea() {
+        return mAdminArea;
+    }
+
+    /**
+     * Sets the administrative area name of the address to the given String, which may be null
+     */
+    public void setAdminArea(String adminArea) {
+        this.mAdminArea = adminArea;
+    }
+
+    /**
+     * Returns the sub-administrative area name of the address, for example, "Santa Clara County",
+     * or null if it is unknown
+     */
+    public String getSubAdminArea() {
+        return mSubAdminArea;
+    }
+
+    /**
+     * Sets the sub-administrative area name of the address to the given String, which may be null
+     */
+    public void setSubAdminArea(String subAdminArea) {
+        this.mSubAdminArea = subAdminArea;
+    }
+
+    /**
+     * Returns the locality of the address, for example "Mountain View", or null if it is unknown.
+     */
+    public String getLocality() {
+        return mLocality;
+    }
+
+    /**
+     * Sets the locality of the address to the given String, which may be null.
+     */
+    public void setLocality(String locality) {
+        mLocality = locality;
+    }
+
+    /**
+     * Returns the sub-locality of the address, or null if it is unknown.
+     * For example, this may correspond to the neighborhood of the locality.
+     */
+    public String getSubLocality() {
+        return mSubLocality;
+    }
+
+    /**
+     * Sets the sub-locality of the address to the given String, which may be null.
+     */
+    public void setSubLocality(String sublocality) {
+        mSubLocality = sublocality;
+    }
+
+    /**
+     * Returns the thoroughfare name of the address, for example, "1600 Ampitheater Parkway",
+     * which may be null
+     */
+    public String getThoroughfare() {
+        return mThoroughfare;
+    }
+
+    /**
+     * Sets the thoroughfare name of the address, which may be null.
+     */
+    public void setThoroughfare(String thoroughfare) {
+        this.mThoroughfare = thoroughfare;
+    }
+
+    /**
+     * Returns the sub-thoroughfare name of the address, which may be null.
+     * This may correspond to the street number of the address.
+     */
+    public String getSubThoroughfare() {
+        return mSubThoroughfare;
+    }
+
+    /**
+     * Sets the sub-thoroughfare name of the address, which may be null.
+     */
+    public void setSubThoroughfare(String subthoroughfare) {
+        this.mSubThoroughfare = subthoroughfare;
+    }
+
+    /**
+     * Returns the premises of the address, or null if it is unknown.
+     */
+    public String getPremises() {
+        return mPremises;
+    }
+
+    /**
+     * Sets the premises of the address to the given String, which may be null.
+     */
+    public void setPremises(String premises) {
+        mPremises = premises;
+    }
+
+    /**
+     * Returns the postal code of the address, for example "94110",
+     * or null if it is unknown.
+     */
+    public String getPostalCode() {
+        return mPostalCode;
+    }
+
+    /**
+     * Sets the postal code of the address to the given String, which may
+     * be null.
+     */
+    public void setPostalCode(String postalCode) {
+        mPostalCode = postalCode;
+    }
+
+    /**
+     * Returns the country code of the address, for example "US",
+     * or null if it is unknown.
+     */
+    public String getCountryCode() {
+        return mCountryCode;
+    }
+
+    /**
+     * Sets the country code of the address to the given String, which may
+     * be null.
+     */
+    public void setCountryCode(String countryCode) {
+        mCountryCode = countryCode;
+    }
+
+    /**
+     * Returns the localized country name of the address, for example "Iceland",
+     * or null if it is unknown.
+     */
+    public String getCountryName() {
+        return mCountryName;
+    }
+
+    /**
+     * Sets the country name of the address to the given String, which may
+     * be null.
+     */
+    public void setCountryName(String countryName) {
+        mCountryName = countryName;
+    }
+
+    /**
+     * Returns true if a latitude has been assigned to this Address,
+     * false otherwise.
+     */
+    public boolean hasLatitude() {
+        return mHasLatitude;
+    }
+
+    /**
+     * Returns the latitude of the address if known.
+     *
+     * @throws IllegalStateException if this Address has not been assigned
+     * a latitude.
+     */
+    public double getLatitude() {
+        if (mHasLatitude) {
+            return mLatitude;
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Sets the latitude associated with this address.
+     */
+    public void setLatitude(double latitude) {
+        mLatitude = latitude;
+        mHasLatitude = true;
+    }
+
+    /**
+     * Removes any latitude associated with this address.
+     */
+    public void clearLatitude() {
+        mHasLatitude = false;
+    }
+
+    /**
+     * Returns true if a longitude has been assigned to this Address,
+     * false otherwise.
+     */
+    public boolean hasLongitude() {
+        return mHasLongitude;
+    }
+
+    /**
+     * Returns the longitude of the address if known.
+     *
+     * @throws IllegalStateException if this Address has not been assigned
+     * a longitude.
+     */
+    public double getLongitude() {
+        if (mHasLongitude) {
+            return mLongitude;
+        } else {
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Sets the longitude associated with this address.
+     */
+    public void setLongitude(double longitude) {
+        mLongitude = longitude;
+        mHasLongitude = true;
+    }
+
+    /**
+     * Removes any longitude associated with this address.
+     */
+    public void clearLongitude() {
+        mHasLongitude = false;
+    }
+
+    /**
+     * Returns the phone number of the address if known,
+     * or null if it is unknown.
+     *
+     * @throws IllegalStateException if this Address has not been assigned
+     * a phone number.
+     */
+    public String getPhone() {
+        return mPhone;
+    }
+
+    /**
+     * Sets the phone number associated with this address.
+     */
+    public void setPhone(String phone) {
+        mPhone = phone;
+    }
+
+    /**
+     * Returns the public URL for the address if known,
+     * or null if it is unknown.
+     */
+    public String getUrl() {
+        return mUrl;
+    }
+
+    /**
+     * Sets the public URL associated with this address.
+     */
+    public void setUrl(String Url) {
+        mUrl = Url;
+    }
+
+    /**
+     * Returns additional provider-specific information about the
+     * address as a Bundle.  The keys and values are determined
+     * by the provider.  If no additional information is available,
+     * null is returned.
+     *
+     * <!--
+     * <p> A number of common key/value pairs are listed
+     * below. Providers that use any of the keys on this list must
+     * provide the corresponding value as described below.
+     *
+     * <ul>
+     * </ul>
+     * -->
+     */
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Sets the extra information associated with this fix to the
+     * given Bundle.
+     */
+    public void setExtras(Bundle extras) {
+        mExtras = (extras == null) ? null : new Bundle(extras);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Address[addressLines=[");
+        for (int i = 0; i <= mMaxAddressLineIndex; i++) {
+            if (i > 0) {
+                sb.append(',');
+            }
+            sb.append(i);
+            sb.append(':');
+            String line = mAddressLines.get(i);
+            if (line == null) {
+                sb.append("null");
+            } else {
+                sb.append('\"');
+                sb.append(line);
+                sb.append('\"');
+            }
+        }
+        sb.append(']');
+        sb.append(",feature=");
+        sb.append(mFeatureName);
+        sb.append(",admin=");
+        sb.append(mAdminArea);
+        sb.append(",sub-admin=");
+        sb.append(mSubAdminArea);
+        sb.append(",locality=");
+        sb.append(mLocality);
+        sb.append(",thoroughfare=");
+        sb.append(mThoroughfare);
+        sb.append(",postalCode=");
+        sb.append(mPostalCode);
+        sb.append(",countryCode=");
+        sb.append(mCountryCode);
+        sb.append(",countryName=");
+        sb.append(mCountryName);
+        sb.append(",hasLatitude=");
+        sb.append(mHasLatitude);
+        sb.append(",latitude=");
+        sb.append(mLatitude);
+        sb.append(",hasLongitude=");
+        sb.append(mHasLongitude);
+        sb.append(",longitude=");
+        sb.append(mLongitude);
+        sb.append(",phone=");
+        sb.append(mPhone);
+        sb.append(",url=");
+        sb.append(mUrl);
+        sb.append(",extras=");
+        sb.append(mExtras);
+        sb.append(']');
+        return sb.toString();
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Address> CREATOR =
+        new Parcelable.Creator<Address>() {
+        public Address createFromParcel(Parcel in) {
+            String language = in.readString();
+            String country = in.readString();
+            Locale locale = country.length() > 0 ?
+                new Locale(language, country) :
+                new Locale(language);
+            Address a = new Address(locale);
+
+            int N = in.readInt();
+            if (N > 0) {
+                a.mAddressLines = new HashMap<Integer, String>(N);
+                for (int i = 0; i < N; i++) {
+                    int index = in.readInt();
+                    String line = in.readString();
+                    a.mAddressLines.put(index, line);
+                    a.mMaxAddressLineIndex =
+                        Math.max(a.mMaxAddressLineIndex, index);
+                }
+            } else {
+                a.mAddressLines = null;
+                a.mMaxAddressLineIndex = -1;
+            }
+            a.mFeatureName = in.readString();
+            a.mAdminArea = in.readString();
+            a.mSubAdminArea = in.readString();
+            a.mLocality = in.readString();
+            a.mSubLocality = in.readString();
+            a.mThoroughfare = in.readString();
+            a.mSubThoroughfare = in.readString();
+            a.mPremises = in.readString();
+            a.mPostalCode = in.readString();
+            a.mCountryCode = in.readString();
+            a.mCountryName = in.readString();
+            a.mHasLatitude = in.readInt() == 0 ? false : true;
+            if (a.mHasLatitude) {
+                a.mLatitude = in.readDouble();
+            }
+            a.mHasLongitude = in.readInt() == 0 ? false : true;
+            if (a.mHasLongitude) {
+                a.mLongitude = in.readDouble();
+            }
+            a.mPhone = in.readString();
+            a.mUrl = in.readString();
+            a.mExtras = in.readBundle();
+            return a;
+        }
+
+        public Address[] newArray(int size) {
+            return new Address[size];
+        }
+    };
+
+    public int describeContents() {
+        return (mExtras != null) ? mExtras.describeContents() : 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mLocale.getLanguage());
+        parcel.writeString(mLocale.getCountry());
+        if (mAddressLines == null) {
+            parcel.writeInt(0);
+        } else {
+            Set<Map.Entry<Integer, String>> entries = mAddressLines.entrySet();
+            parcel.writeInt(entries.size());
+            for (Map.Entry<Integer, String> e : entries) {
+                parcel.writeInt(e.getKey());
+                parcel.writeString(e.getValue());
+            }
+        }
+        parcel.writeString(mFeatureName);
+        parcel.writeString(mAdminArea);
+        parcel.writeString(mSubAdminArea);
+        parcel.writeString(mLocality);
+        parcel.writeString(mSubLocality);
+        parcel.writeString(mThoroughfare);
+        parcel.writeString(mSubThoroughfare);
+        parcel.writeString(mPremises);
+        parcel.writeString(mPostalCode);
+        parcel.writeString(mCountryCode);
+        parcel.writeString(mCountryName);
+        parcel.writeInt(mHasLatitude ? 1 : 0);
+        if (mHasLatitude) {
+            parcel.writeDouble(mLatitude);
+        }
+        parcel.writeInt(mHasLongitude ? 1 : 0);
+        if (mHasLongitude){
+            parcel.writeDouble(mLongitude);
+        }
+        parcel.writeString(mPhone);
+        parcel.writeString(mUrl);
+        parcel.writeBundle(mExtras);
+    }
+}
diff --git a/android/location/BatchedLocationCallback.java b/android/location/BatchedLocationCallback.java
new file mode 100644
index 0000000..f1c40ae
--- /dev/null
+++ b/android/location/BatchedLocationCallback.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.location;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Used for receiving notifications from the LocationManager when
+ * the a batch of location is ready. These methods are called if the
+ * BatchedLocationCallback has been registered with the location manager service
+ * using the
+ * {@link LocationManager#registerGnssBatchedLocationCallback#startGnssBatch(long,
+ * boolean, BatchedLocationCallback, android.os.Handler)} method.
+ * @hide
+ */
+@SystemApi
+public abstract class BatchedLocationCallback {
+
+    /**
+     * Called when a new batch of locations is ready
+     *
+     * @param locations A list of all new locations (possibly zero of them.)
+     */
+    public void onLocationBatch(List<Location> locations) {}
+}
diff --git a/android/location/Country.java b/android/location/Country.java
new file mode 100644
index 0000000..8c40338
--- /dev/null
+++ b/android/location/Country.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2010 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.location;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+
+import java.util.Locale;
+
+/**
+ * This class wraps the country information.
+ *
+ * @hide
+ */
+public class Country implements Parcelable {
+    /**
+     * The country code came from the mobile network
+     */
+    public static final int COUNTRY_SOURCE_NETWORK = 0;
+
+    /**
+     * The country code came from the location service
+     */
+    public static final int COUNTRY_SOURCE_LOCATION = 1;
+
+    /**
+     * The country code was read from the SIM card
+     */
+    public static final int COUNTRY_SOURCE_SIM = 2;
+
+    /**
+     * The country code came from the system locale setting
+     */
+    public static final int COUNTRY_SOURCE_LOCALE = 3;
+
+    /**
+     * The ISO 3166-1 two letters country code.
+     */
+    private final String mCountryIso;
+
+    /**
+     * Where the country code came from.
+     */
+    private final int mSource;
+
+    private int mHashCode;
+
+    /**
+     * Time that this object was created (which we assume to be the time that the source was
+     * consulted). This time is in milliseconds since boot up.
+     */
+    private final long mTimestamp;
+
+    /**
+     * @param countryIso the ISO 3166-1 two letters country code.
+     * @param source where the countryIso came from, could be one of below
+     *        values
+     *        <p>
+     *        <ul>
+     *        <li>{@link #COUNTRY_SOURCE_NETWORK}</li>
+     *        <li>{@link #COUNTRY_SOURCE_LOCATION}</li>
+     *        <li>{@link #COUNTRY_SOURCE_SIM}</li>
+     *        <li>{@link #COUNTRY_SOURCE_LOCALE}</li>
+     *        </ul>
+     */
+    @UnsupportedAppUsage
+    public Country(final String countryIso, final int source) {
+        if (countryIso == null || source < COUNTRY_SOURCE_NETWORK
+                || source > COUNTRY_SOURCE_LOCALE) {
+            throw new IllegalArgumentException();
+        }
+        mCountryIso = countryIso.toUpperCase(Locale.US);
+        mSource = source;
+        mTimestamp = SystemClock.elapsedRealtime();
+    }
+
+    private Country(final String countryIso, final int source, long timestamp) {
+        if (countryIso == null || source < COUNTRY_SOURCE_NETWORK
+                || source > COUNTRY_SOURCE_LOCALE) {
+            throw new IllegalArgumentException();
+        }
+        mCountryIso = countryIso.toUpperCase(Locale.US);
+        mSource = source;
+        mTimestamp = timestamp;
+    }
+
+    public Country(Country country) {
+        mCountryIso = country.mCountryIso;
+        mSource = country.mSource;
+        mTimestamp = country.mTimestamp;
+    }
+
+    /**
+     * @return the ISO 3166-1 two letters country code
+     */
+    @UnsupportedAppUsage
+    public final String getCountryIso() {
+        return mCountryIso;
+    }
+
+    /**
+     * @return where the country code came from, could be one of below values
+     *         <p>
+     *         <ul>
+     *         <li>{@link #COUNTRY_SOURCE_NETWORK}</li>
+     *         <li>{@link #COUNTRY_SOURCE_LOCATION}</li>
+     *         <li>{@link #COUNTRY_SOURCE_SIM}</li>
+     *         <li>{@link #COUNTRY_SOURCE_LOCALE}</li>
+     *         </ul>
+     */
+    @UnsupportedAppUsage
+    public final int getSource() {
+        return mSource;
+    }
+
+    /**
+     * Returns the time that this object was created (which we assume to be the time that the source
+     * was consulted).
+     */
+    public final long getTimestamp() {
+        return mTimestamp;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Country> CREATOR = new Parcelable.Creator<Country>() {
+        public Country createFromParcel(Parcel in) {
+            return new Country(in.readString(), in.readInt(), in.readLong());
+        }
+
+        public Country[] newArray(int size) {
+            return new Country[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mCountryIso);
+        parcel.writeInt(mSource);
+        parcel.writeLong(mTimestamp);
+    }
+
+    /**
+     * Returns true if this {@link Country} is equivalent to the given object. This ignores
+     * the timestamp value and just checks for equivalence of countryIso and source values.
+     * Returns false otherwise.
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object instanceof Country) {
+            Country c = (Country) object;
+            // No need to check the equivalence of the timestamp
+            return mCountryIso.equals(c.getCountryIso()) && mSource == c.getSource();
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = mHashCode;
+        if (hash == 0) {
+            hash = 17;
+            hash = hash * 13 + mCountryIso.hashCode();
+            hash = hash * 13 + mSource;
+            mHashCode = hash;
+        }
+        return mHashCode;
+    }
+
+    /**
+     * Compare the specified country to this country object ignoring the source
+     * and timestamp fields, return true if the countryIso fields are equal
+     *
+     * @param country the country to compare
+     * @return true if the specified country's countryIso field is equal to this
+     *         country's, false otherwise.
+     */
+    public boolean equalsIgnoreSource(Country country) {
+        return country != null && mCountryIso.equals(country.getCountryIso());
+    }
+
+    @Override
+    public String toString() {
+        return "Country {ISO=" + mCountryIso + ", source=" + mSource + ", time=" + mTimestamp + "}";
+    }
+}
diff --git a/android/location/CountryDetector.java b/android/location/CountryDetector.java
new file mode 100644
index 0000000..e344b82
--- /dev/null
+++ b/android/location/CountryDetector.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2010 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.location;
+
+import android.annotation.SystemService;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * This class provides access to the system country detector service. This
+ * service allows applications to obtain the country that the user is in.
+ * <p>
+ * The country will be detected in order of reliability, like
+ * <ul>
+ * <li>Mobile network</li>
+ * <li>Location</li>
+ * <li>SIM's country</li>
+ * <li>Phone's locale</li>
+ * </ul>
+ * <p>
+ * Call the {@link #detectCountry()} to get the available country immediately.
+ * <p>
+ * To be notified of the future country change, use the
+ * {@link #addCountryListener}
+ * <p>
+ *
+ * @hide
+ */
+@SystemService(Context.COUNTRY_DETECTOR)
+public class CountryDetector {
+
+    /**
+     * The class to wrap the ICountryListener.Stub and CountryListener objects
+     * together. The CountryListener will be notified through the specific
+     * looper once the country changed and detected.
+     */
+    private final static class ListenerTransport extends ICountryListener.Stub {
+
+        private final CountryListener mListener;
+
+        private final Handler mHandler;
+
+        public ListenerTransport(CountryListener listener, Looper looper) {
+            mListener = listener;
+            if (looper != null) {
+                mHandler = new Handler(looper);
+            } else {
+                mHandler = new Handler();
+            }
+        }
+
+        public void onCountryDetected(final Country country) {
+            mHandler.post(new Runnable() {
+                public void run() {
+                    mListener.onCountryDetected(country);
+                }
+            });
+        }
+    }
+
+    private final static String TAG = "CountryDetector";
+    private final ICountryDetector mService;
+    private final HashMap<CountryListener, ListenerTransport> mListeners;
+
+    /**
+     * @hide - hide this constructor because it has a parameter of type
+     *       ICountryDetector, which is a system private class. The right way to
+     *       create an instance of this class is using the factory
+     *       Context.getSystemService.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    public CountryDetector(ICountryDetector service) {
+        mService = service;
+        mListeners = new HashMap<CountryListener, ListenerTransport>();
+    }
+
+    /**
+     * Start detecting the country that the user is in.
+     *
+     * @return the country if it is available immediately, otherwise null will
+     *         be returned.
+     */
+    @UnsupportedAppUsage
+    public Country detectCountry() {
+        try {
+            return mService.detectCountry();
+        } catch (RemoteException e) {
+            Log.e(TAG, "detectCountry: RemoteException", e);
+            return null;
+        }
+    }
+
+    /**
+     * Add a listener to receive the notification when the country is detected
+     * or changed.
+     *
+     * @param listener will be called when the country is detected or changed.
+     * @param looper a Looper object whose message queue will be used to
+     *        implement the callback mechanism. If looper is null then the
+     *        callbacks will be called on the main thread.
+     */
+    @UnsupportedAppUsage
+    public void addCountryListener(CountryListener listener, Looper looper) {
+        synchronized (mListeners) {
+            if (!mListeners.containsKey(listener)) {
+                ListenerTransport transport = new ListenerTransport(listener, looper);
+                try {
+                    mService.addCountryListener(transport);
+                    mListeners.put(listener, transport);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "addCountryListener: RemoteException", e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove the listener
+     */
+    @UnsupportedAppUsage
+    public void removeCountryListener(CountryListener listener) {
+        synchronized (mListeners) {
+            ListenerTransport transport = mListeners.get(listener);
+            if (transport != null) {
+                try {
+                    mListeners.remove(listener);
+                    mService.removeCountryListener(transport);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "removeCountryListener: RemoteException", e);
+                }
+            }
+        }
+    }
+}
diff --git a/android/location/CountryListener.java b/android/location/CountryListener.java
new file mode 100644
index 0000000..eb67205
--- /dev/null
+++ b/android/location/CountryListener.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 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.location;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+/**
+ * The listener for receiving the notification when the country is detected or
+ * changed
+ *
+ * @hide
+ */
+public interface CountryListener {
+    /**
+     * @param country the changed or detected country.
+     */
+    @UnsupportedAppUsage
+    void onCountryDetected(Country country);
+}
diff --git a/android/location/Criteria.java b/android/location/Criteria.java
new file mode 100644
index 0000000..26f73f7
--- /dev/null
+++ b/android/location/Criteria.java
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2007 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.location;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A class indicating the application criteria for selecting a
+ * location provider. Providers may be ordered according to accuracy,
+ * power usage, ability to report altitude, speed, bearing, and monetary
+ * cost.
+ */
+public class Criteria implements Parcelable {
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NO_REQUIREMENT, POWER_LOW, POWER_MEDIUM, POWER_HIGH})
+    public @interface PowerRequirement {
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NO_REQUIREMENT, ACCURACY_LOW, ACCURACY_MEDIUM, ACCURACY_HIGH})
+    public @interface AccuracyRequirement {
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NO_REQUIREMENT, ACCURACY_FINE, ACCURACY_COARSE})
+    public @interface LocationAccuracyRequirement {
+    }
+
+    /**
+     * A constant indicating that the application does not choose to
+     * place requirement on a particular feature.
+     */
+    public static final int NO_REQUIREMENT = 0;
+
+    /**
+     * A constant indicating a low power requirement.
+     */
+    public static final int POWER_LOW = 1;
+
+    /**
+     * A constant indicating a medium power requirement.
+     */
+    public static final int POWER_MEDIUM = 2;
+
+    /**
+     * A constant indicating a high power requirement.
+     */
+    public static final int POWER_HIGH = 3;
+
+    /**
+     * A constant indicating a finer location accuracy requirement
+     */
+    public static final int ACCURACY_FINE = 1;
+
+    /**
+     * A constant indicating an approximate accuracy requirement
+     */
+    public static final int ACCURACY_COARSE = 2;
+
+    /**
+     * A constant indicating a low location accuracy requirement
+     * - may be used for horizontal, altitude, speed or bearing accuracy.
+     * For horizontal and vertical position this corresponds roughly to
+     * an accuracy of greater than 500 meters.
+     */
+    public static final int ACCURACY_LOW = 1;
+
+    /**
+     * A constant indicating a medium accuracy requirement
+     * - currently used only for horizontal accuracy.
+     * For horizontal position this corresponds roughly to to an accuracy
+     * of between 100 and 500 meters.
+     */
+    public static final int ACCURACY_MEDIUM = 2;
+
+    /**
+     * a constant indicating a high accuracy requirement
+     * - may be used for horizontal, altitude, speed or bearing accuracy.
+     * For horizontal and vertical position this corresponds roughly to
+     * an accuracy of less than 100 meters.
+     */
+    public static final int ACCURACY_HIGH = 3;
+
+    private int mHorizontalAccuracy = NO_REQUIREMENT;
+    private int mVerticalAccuracy = NO_REQUIREMENT;
+    private int mSpeedAccuracy = NO_REQUIREMENT;
+    private int mBearingAccuracy = NO_REQUIREMENT;
+    private int mPowerRequirement = NO_REQUIREMENT;
+    private boolean mAltitudeRequired = false;
+    private boolean mBearingRequired = false;
+    private boolean mSpeedRequired = false;
+    private boolean mCostAllowed = false;
+
+    /**
+     * Constructs a new Criteria object.  The new object will have no
+     * requirements on accuracy, power, or response time; will not
+     * require altitude, speed, or bearing; and will not allow monetary
+     * cost.
+     */
+    public Criteria() {
+    }
+
+    /**
+     * Constructs a new Criteria object that is a copy of the given criteria.
+     */
+    public Criteria(Criteria criteria) {
+        mHorizontalAccuracy = criteria.mHorizontalAccuracy;
+        mVerticalAccuracy = criteria.mVerticalAccuracy;
+        mSpeedAccuracy = criteria.mSpeedAccuracy;
+        mBearingAccuracy = criteria.mBearingAccuracy;
+        mPowerRequirement = criteria.mPowerRequirement;
+        mAltitudeRequired = criteria.mAltitudeRequired;
+        mBearingRequired = criteria.mBearingRequired;
+        mSpeedRequired = criteria.mSpeedRequired;
+        mCostAllowed = criteria.mCostAllowed;
+    }
+
+    /**
+     * Indicates the desired horizontal accuracy (latitude and longitude). Accuracy may be
+     * {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM}, {@link #ACCURACY_HIGH} or
+     * {@link #NO_REQUIREMENT}. More accurate location may consume more power and may take longer.
+     *
+     * @throws IllegalArgumentException if accuracy is not one of the supported constants
+     */
+    public void setHorizontalAccuracy(@AccuracyRequirement int accuracy) {
+        mHorizontalAccuracy = Preconditions.checkArgumentInRange(accuracy, NO_REQUIREMENT,
+                ACCURACY_HIGH, "accuracy");
+    }
+
+    /**
+     * Returns a constant indicating the desired horizontal accuracy (latitude and longitude).
+     *
+     * @see #setHorizontalAccuracy(int)
+     */
+    @AccuracyRequirement
+    public int getHorizontalAccuracy() {
+        return mHorizontalAccuracy;
+    }
+
+    /**
+     * Indicates the desired vertical accuracy (altitude). Accuracy may be {@link #ACCURACY_LOW},
+     * {@link #ACCURACY_MEDIUM}, {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}. More accurate
+     * location may consume more power and may take longer.
+     *
+     * @throws IllegalArgumentException if accuracy is not one of the supported constants
+     */
+    public void setVerticalAccuracy(@AccuracyRequirement int accuracy) {
+        mVerticalAccuracy = Preconditions.checkArgumentInRange(accuracy, NO_REQUIREMENT,
+                ACCURACY_HIGH, "accuracy");
+    }
+
+    /**
+     * Returns a constant indicating the desired vertical accuracy (altitude).
+     *
+     * @see #setVerticalAccuracy(int)
+     */
+    @AccuracyRequirement
+    public int getVerticalAccuracy() {
+        return mVerticalAccuracy;
+    }
+
+    /**
+     * Indicates the desired speed accuracy. Accuracy may be {@link #ACCURACY_LOW},
+     * {@link #ACCURACY_MEDIUM}, {@link #ACCURACY_HIGH}, or {@link #NO_REQUIREMENT}. More accurate
+     * location may consume more power and may take longer.
+     *
+     * @throws IllegalArgumentException if accuracy is not one of the supported constants
+     */
+    public void setSpeedAccuracy(@AccuracyRequirement int accuracy) {
+        mSpeedAccuracy = Preconditions.checkArgumentInRange(accuracy, NO_REQUIREMENT, ACCURACY_HIGH,
+                "accuracy");
+    }
+
+    /**
+     * Returns a constant indicating the desired speed accuracy.
+     *
+     * @see #setSpeedAccuracy(int)
+     */
+    @AccuracyRequirement
+    public int getSpeedAccuracy() {
+        return mSpeedAccuracy;
+    }
+
+    /**
+     * Indicates the desired bearing accuracy. Accuracy may be {@link #ACCURACY_LOW},
+     * {@link #ACCURACY_MEDIUM}, {@link #ACCURACY_HIGH}, or {@link #NO_REQUIREMENT}. More accurate
+     * location may consume more power and may take longer.
+     *
+     * @throws IllegalArgumentException if accuracy is not one of the supported constants
+     */
+    public void setBearingAccuracy(@AccuracyRequirement int accuracy) {
+        mBearingAccuracy = Preconditions.checkArgumentInRange(accuracy, NO_REQUIREMENT,
+                ACCURACY_HIGH, "accuracy");
+    }
+
+    /**
+     * Returns a constant indicating the desired bearing accuracy.
+     *
+     * @see #setBearingAccuracy(int)
+     */
+    @AccuracyRequirement
+    public int getBearingAccuracy() {
+        return mBearingAccuracy;
+    }
+
+    /**
+     * Indicates the desired accuracy for latitude and longitude. Accuracy may be
+     * {@link #ACCURACY_FINE} or {@link #ACCURACY_COARSE}. More accurate location may consume more
+     * power and may take longer.
+     *
+     * @throws IllegalArgumentException if accuracy is not one of the supported constants
+     */
+    public void setAccuracy(@LocationAccuracyRequirement int accuracy) {
+        Preconditions.checkArgumentInRange(accuracy, NO_REQUIREMENT, ACCURACY_COARSE, "accuracy");
+        switch (accuracy) {
+            case NO_REQUIREMENT:
+                setHorizontalAccuracy(NO_REQUIREMENT);
+                break;
+            case ACCURACY_FINE:
+                setHorizontalAccuracy(ACCURACY_HIGH);
+                break;
+            case ACCURACY_COARSE:
+                setHorizontalAccuracy(ACCURACY_LOW);
+                break;
+        }
+    }
+
+    /**
+     * Returns a constant indicating desired accuracy of location.
+     *
+     * @see #setAccuracy(int)
+     */
+    @LocationAccuracyRequirement
+    public int getAccuracy() {
+        if (mHorizontalAccuracy >= ACCURACY_HIGH) {
+            return ACCURACY_FINE;
+        } else {
+            return ACCURACY_COARSE;
+        }
+    }
+
+    /**
+     * Indicates the desired maximum power requirement. The power requirement parameter may be
+     * {@link #NO_REQUIREMENT}, {@link #POWER_LOW}, {@link #POWER_MEDIUM}, or {@link #POWER_HIGH}.
+     */
+    public void setPowerRequirement(@PowerRequirement int powerRequirement) {
+        mPowerRequirement = Preconditions.checkArgumentInRange(powerRequirement, NO_REQUIREMENT,
+                POWER_HIGH, "powerRequirement");
+    }
+
+    /**
+     * Returns a constant indicating the desired maximum power requirement.
+     *
+     * @see #setPowerRequirement(int)
+     */
+    @PowerRequirement
+    public int getPowerRequirement() {
+        return mPowerRequirement;
+    }
+
+    /**
+     * Indicates whether the provider is allowed to incur monetary cost.
+     */
+    public void setCostAllowed(boolean costAllowed) {
+        mCostAllowed = costAllowed;
+    }
+
+    /**
+     * Returns whether the provider is allowed to incur monetary cost.
+     */
+    public boolean isCostAllowed() {
+        return mCostAllowed;
+    }
+
+    /**
+     * Indicates whether the provider must provide altitude information. Not all fixes are
+     * guaranteed to contain such information.
+     */
+    public void setAltitudeRequired(boolean altitudeRequired) {
+        mAltitudeRequired = altitudeRequired;
+    }
+
+    /**
+     * Returns whether the provider must provide altitude information.
+     *
+     * @see #setAltitudeRequired(boolean)
+     */
+    public boolean isAltitudeRequired() {
+        return mAltitudeRequired;
+    }
+
+    /**
+     * Indicates whether the provider must provide speed information. Not all fixes are guaranteed
+     * to contain such information.
+     */
+    public void setSpeedRequired(boolean speedRequired) {
+        mSpeedRequired = speedRequired;
+    }
+
+    /**
+     * Returns whether the provider must provide speed information.
+     *
+     * @see #setSpeedRequired(boolean)
+     */
+    public boolean isSpeedRequired() {
+        return mSpeedRequired;
+    }
+
+    /**
+     * Indicates whether the provider must provide bearing information. Not all fixes are guaranteed
+     * to contain such information.
+     */
+    public void setBearingRequired(boolean bearingRequired) {
+        mBearingRequired = bearingRequired;
+    }
+
+    /**
+     * Returns whether the provider must provide bearing information.
+     *
+     * @see #setBearingRequired(boolean)
+     */
+    public boolean isBearingRequired() {
+        return mBearingRequired;
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<Criteria> CREATOR =
+            new Parcelable.Creator<Criteria>() {
+                @Override
+                public Criteria createFromParcel(Parcel in) {
+                    Criteria c = new Criteria();
+                    c.mHorizontalAccuracy = in.readInt();
+                    c.mVerticalAccuracy = in.readInt();
+                    c.mSpeedAccuracy = in.readInt();
+                    c.mBearingAccuracy = in.readInt();
+                    c.mPowerRequirement = in.readInt();
+                    c.mAltitudeRequired = in.readInt() != 0;
+                    c.mBearingRequired = in.readInt() != 0;
+                    c.mSpeedRequired = in.readInt() != 0;
+                    c.mCostAllowed = in.readInt() != 0;
+                    return c;
+                }
+
+                @Override
+                public Criteria[] newArray(int size) {
+                    return new Criteria[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mHorizontalAccuracy);
+        parcel.writeInt(mVerticalAccuracy);
+        parcel.writeInt(mSpeedAccuracy);
+        parcel.writeInt(mBearingAccuracy);
+        parcel.writeInt(mPowerRequirement);
+        parcel.writeInt(mAltitudeRequired ? 1 : 0);
+        parcel.writeInt(mBearingRequired ? 1 : 0);
+        parcel.writeInt(mSpeedRequired ? 1 : 0);
+        parcel.writeInt(mCostAllowed ? 1 : 0);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("Criteria[");
+        s.append("power=").append(requirementToString(mPowerRequirement)).append(", ");
+        s.append("accuracy=").append(requirementToString(mHorizontalAccuracy));
+        if (mVerticalAccuracy != NO_REQUIREMENT) {
+            s.append(", verticalAccuracy=").append(requirementToString(mVerticalAccuracy));
+        }
+        if (mSpeedAccuracy != NO_REQUIREMENT) {
+            s.append(", speedAccuracy=").append(requirementToString(mSpeedAccuracy));
+        }
+        if (mBearingAccuracy != NO_REQUIREMENT) {
+            s.append(", bearingAccuracy=").append(requirementToString(mBearingAccuracy));
+        }
+        if (mAltitudeRequired || mBearingRequired || mSpeedRequired) {
+            s.append(", required=[");
+            if (mAltitudeRequired) {
+                s.append("altitude, ");
+            }
+            if (mBearingRequired) {
+                s.append("bearing, ");
+            }
+            if (mSpeedRequired) {
+                s.append("speed, ");
+            }
+            s.setLength(s.length() - 2);
+            s.append("]");
+        }
+        if (mCostAllowed) {
+            s.append(", costAllowed");
+        }
+        s.append(']');
+        return s.toString();
+    }
+
+    private static String requirementToString(int power) {
+        switch (power) {
+            case NO_REQUIREMENT:
+                return "None";
+            //case ACCURACY_LOW:
+            case POWER_LOW:
+                return "Low";
+            //case ACCURACY_MEDIUM:
+            case POWER_MEDIUM:
+                return "Medium";
+            //case ACCURACY_HIGH:
+            case POWER_HIGH:
+                return "High";
+            default:
+                return "???";
+        }
+    }
+}
diff --git a/android/location/FusedBatchOptions.java b/android/location/FusedBatchOptions.java
new file mode 100644
index 0000000..4a022c3
--- /dev/null
+++ b/android/location/FusedBatchOptions.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2013 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.location;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A data class representing a set of options to configure batching sessions.
+ * @hide
+ */
+public class FusedBatchOptions implements Parcelable {
+    private volatile long mPeriodInNS = 0;
+    private volatile int mSourcesToUse = 0;
+    private volatile int mFlags = 0;
+
+    // the default value is set to request fixes at no cost
+    private volatile double mMaxPowerAllocationInMW = 0;
+    // If non-zero can be used for power savings by throttling location when device hasn't moved.
+    private volatile float mSmallestDisplacementMeters = 0;
+
+    /*
+     * Getters and setters for properties needed to hold the options.
+     */
+    public void setMaxPowerAllocationInMW(double value) {
+        mMaxPowerAllocationInMW = value;
+    }
+
+    public double getMaxPowerAllocationInMW() {
+        return mMaxPowerAllocationInMW;
+    }
+
+    public void setPeriodInNS(long value) {
+        mPeriodInNS = value;
+    }
+
+    public long getPeriodInNS() {
+        return mPeriodInNS;
+    }
+
+    public void setSmallestDisplacementMeters(float value) {
+        mSmallestDisplacementMeters = value;
+    }
+
+    public float getSmallestDisplacementMeters() {
+        return mSmallestDisplacementMeters;
+    }
+
+    public void setSourceToUse(int source) {
+        mSourcesToUse |= source;
+    }
+
+    public void resetSourceToUse(int source) {
+        mSourcesToUse &= ~source;
+    }
+
+    public boolean isSourceToUseSet(int source) {
+        return (mSourcesToUse & source) != 0;
+    }
+
+    public int getSourcesToUse() {
+        return mSourcesToUse;
+    }
+
+    public void setFlag(int flag) {
+        mFlags |= flag;
+    }
+
+    public void resetFlag(int flag) {
+        mFlags &= ~flag;
+    }
+
+    public boolean isFlagSet(int flag) {
+        return (mFlags & flag) != 0;
+    }
+
+    public int getFlags() {
+        return mFlags;
+    }
+
+    /**
+     * Definition of enum flag sets needed by this class.
+     * Such values need to be kept in sync with the ones in fused_location.h
+     */
+    public static final class SourceTechnologies {
+        public static int GNSS = 1<<0;
+        public static int WIFI = 1<<1;
+        public static int SENSORS = 1<<2;
+        public static int CELL = 1<<3;
+        public static int BLUETOOTH = 1<<4;
+    }
+
+    public static final class BatchFlags {
+        // follow the definitions to the letter in fused_location.h
+        public static int WAKEUP_ON_FIFO_FULL = 0x0000001;
+        public static int CALLBACK_ON_LOCATION_FIX =0x0000002;
+    }
+
+    /*
+     * Method definitions to support Parcelable operations.
+     */
+    public static final @android.annotation.NonNull Parcelable.Creator<FusedBatchOptions> CREATOR =
+            new Parcelable.Creator<FusedBatchOptions>() {
+        @Override
+        public FusedBatchOptions createFromParcel(Parcel parcel) {
+            FusedBatchOptions options = new FusedBatchOptions();
+            options.setMaxPowerAllocationInMW(parcel.readDouble());
+            options.setPeriodInNS(parcel.readLong());
+            options.setSourceToUse(parcel.readInt());
+            options.setFlag(parcel.readInt());
+            options.setSmallestDisplacementMeters(parcel.readFloat());
+            return options;
+        }
+
+        @Override
+        public FusedBatchOptions[] newArray(int size) {
+            return new FusedBatchOptions[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeDouble(mMaxPowerAllocationInMW);
+        parcel.writeLong(mPeriodInNS);
+        parcel.writeInt(mSourcesToUse);
+        parcel.writeInt(mFlags);
+        parcel.writeFloat(mSmallestDisplacementMeters);
+    }
+}
diff --git a/android/location/Geocoder.java b/android/location/Geocoder.java
new file mode 100644
index 0000000..ac7eb8b
--- /dev/null
+++ b/android/location/Geocoder.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2007 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.location;
+
+import android.content.Context;
+import android.location.Address;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A class for handling geocoding and reverse geocoding.  Geocoding is
+ * the process of transforming a street address or other description
+ * of a location into a (latitude, longitude) coordinate.  Reverse
+ * geocoding is the process of transforming a (latitude, longitude)
+ * coordinate into a (partial) address.  The amount of detail in a
+ * reverse geocoded location description may vary, for example one
+ * might contain the full street address of the closest building, while
+ * another might contain only a city name and postal code.
+ *
+ * The Geocoder class requires a backend service that is not included in
+ * the core android framework.  The Geocoder query methods will return an
+ * empty list if there no backend service in the platform.  Use the
+ * isPresent() method to determine whether a Geocoder implementation
+ * exists.
+ */
+public final class Geocoder {
+    private static final String TAG = "Geocoder";
+
+    private GeocoderParams mParams;
+    private ILocationManager mService;
+
+    /**
+     * Returns true if the Geocoder methods getFromLocation and
+     * getFromLocationName are implemented.  Lack of network
+     * connectivity may still cause these methods to return null or
+     * empty lists.
+     */
+    public static boolean isPresent() {
+        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
+        ILocationManager lm = ILocationManager.Stub.asInterface(b);
+        try {
+            return lm.geocoderIsPresent();
+        } catch (RemoteException e) {
+            Log.e(TAG, "isPresent: got RemoteException", e);
+            return false;
+        }
+    }
+
+    /**
+     * Constructs a Geocoder whose responses will be localized for the
+     * given Locale.
+     *
+     * @param context the Context of the calling Activity
+     * @param locale the desired Locale for the query results
+     *
+     * @throws NullPointerException if Locale is null
+     */
+    public Geocoder(Context context, Locale locale) {
+        if (locale == null) {
+            throw new NullPointerException("locale == null");
+        }
+        mParams = new GeocoderParams(context, locale);
+        IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
+        mService = ILocationManager.Stub.asInterface(b);
+    }
+
+    /**
+     * Constructs a Geocoder whose responses will be localized for the
+     * default system Locale.
+     *
+     * @param context the Context of the calling Activity
+     */
+    public Geocoder(Context context) {
+        this(context, Locale.getDefault());
+    }
+
+    /**
+     * Returns an array of Addresses that are known to describe the
+     * area immediately surrounding the given latitude and longitude.
+     * The returned addresses will be localized for the locale
+     * provided to this class's constructor.
+     *
+     * <p> The returned values may be obtained by means of a network lookup.
+     * The results are a best guess and are not guaranteed to be meaningful or
+     * correct. It may be useful to call this method from a thread separate from your
+     * primary UI thread.
+     *
+     * @param latitude the latitude a point for the search
+     * @param longitude the longitude a point for the search
+     * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
+     *
+     * @return a list of Address objects. Returns null or empty list if no matches were
+     * found or there is no backend service available.
+     *
+     * @throws IllegalArgumentException if latitude is
+     * less than -90 or greater than 90
+     * @throws IllegalArgumentException if longitude is
+     * less than -180 or greater than 180
+     * @throws IOException if the network is unavailable or any other
+     * I/O problem occurs
+     */
+    public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
+        throws IOException {
+        if (latitude < -90.0 || latitude > 90.0) {
+            throw new IllegalArgumentException("latitude == " + latitude);
+        }
+        if (longitude < -180.0 || longitude > 180.0) {
+            throw new IllegalArgumentException("longitude == " + longitude);
+        }
+        try {
+            List<Address> results = new ArrayList<Address>();
+            String ex =  mService.getFromLocation(latitude, longitude, maxResults,
+                mParams, results);
+            if (ex != null) {
+                throw new IOException(ex);
+            } else {
+                return results;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "getFromLocation: got RemoteException", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns an array of Addresses that are known to describe the
+     * named location, which may be a place name such as "Dalvik,
+     * Iceland", an address such as "1600 Amphitheatre Parkway,
+     * Mountain View, CA", an airport code such as "SFO", etc..  The
+     * returned addresses will be localized for the locale provided to
+     * this class's constructor.
+     *
+     * <p> The query will block and returned values will be obtained by means of a network lookup.
+     * The results are a best guess and are not guaranteed to be meaningful or
+     * correct. It may be useful to call this method from a thread separate from your
+     * primary UI thread.
+     *
+     * @param locationName a user-supplied description of a location
+     * @param maxResults max number of results to return. Smaller numbers (1 to 5) are recommended
+     *
+     * @return a list of Address objects. Returns null or empty list if no matches were
+     * found or there is no backend service available.
+     *
+     * @throws IllegalArgumentException if locationName is null
+     * @throws IOException if the network is unavailable or any other
+     * I/O problem occurs
+     */
+    public List<Address> getFromLocationName(String locationName, int maxResults) throws IOException {
+        if (locationName == null) {
+            throw new IllegalArgumentException("locationName == null");
+        }
+        try {
+            List<Address> results = new ArrayList<Address>();
+            String ex = mService.getFromLocationName(locationName,
+                0, 0, 0, 0, maxResults, mParams, results);
+            if (ex != null) {
+                throw new IOException(ex);
+            } else {
+                return results;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "getFromLocationName: got RemoteException", e);
+            return null;
+        }
+    }
+
+    /**
+     * Returns an array of Addresses that are known to describe the
+     * named location, which may be a place name such as "Dalvik,
+     * Iceland", an address such as "1600 Amphitheatre Parkway,
+     * Mountain View, CA", an airport code such as "SFO", etc..  The
+     * returned addresses will be localized for the locale provided to
+     * this class's constructor.
+     *
+     * <p> You may specify a bounding box for the search results by including
+     * the Latitude and Longitude of the Lower Left point and Upper Right
+     * point of the box.
+     *
+     * <p> The query will block and returned values will be obtained by means of a network lookup.
+     * The results are a best guess and are not guaranteed to be meaningful or
+     * correct. It may be useful to call this method from a thread separate from your
+     * primary UI thread.
+     *
+     * @param locationName a user-supplied description of a location
+     * @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
+     * @param lowerLeftLatitude the latitude of the lower left corner of the bounding box
+     * @param lowerLeftLongitude the longitude of the lower left corner of the bounding box
+     * @param upperRightLatitude the latitude of the upper right corner of the bounding box
+     * @param upperRightLongitude the longitude of the upper right corner of the bounding box
+     *
+     * @return a list of Address objects. Returns null or empty list if no matches were
+     * found or there is no backend service available.
+     *
+     * @throws IllegalArgumentException if locationName is null
+     * @throws IllegalArgumentException if any latitude is
+     * less than -90 or greater than 90
+     * @throws IllegalArgumentException if any longitude is
+     * less than -180 or greater than 180
+     * @throws IOException if the network is unavailable or any other
+     * I/O problem occurs
+     */
+    public List<Address> getFromLocationName(String locationName, int maxResults,
+        double lowerLeftLatitude, double lowerLeftLongitude,
+        double upperRightLatitude, double upperRightLongitude) throws IOException {
+        if (locationName == null) {
+            throw new IllegalArgumentException("locationName == null");
+        }
+        if (lowerLeftLatitude < -90.0 || lowerLeftLatitude > 90.0) {
+            throw new IllegalArgumentException("lowerLeftLatitude == "
+                + lowerLeftLatitude);
+        }
+        if (lowerLeftLongitude < -180.0 || lowerLeftLongitude > 180.0) {
+            throw new IllegalArgumentException("lowerLeftLongitude == "
+                + lowerLeftLongitude);
+        }
+        if (upperRightLatitude < -90.0 || upperRightLatitude > 90.0) {
+            throw new IllegalArgumentException("upperRightLatitude == "
+                + upperRightLatitude);
+        }
+        if (upperRightLongitude < -180.0 || upperRightLongitude > 180.0) {
+            throw new IllegalArgumentException("upperRightLongitude == "
+                + upperRightLongitude);
+        }
+        try {
+            ArrayList<Address> result = new ArrayList<Address>();
+            String ex =  mService.getFromLocationName(locationName,
+                lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
+                maxResults, mParams, result);
+            if (ex != null) {
+                throw new IOException(ex);
+            } else {
+                return result;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "getFromLocationName: got RemoteException", e);
+            return null;
+        }
+    }
+}
diff --git a/android/location/GeocoderParams.java b/android/location/GeocoderParams.java
new file mode 100644
index 0000000..1c6e9b6
--- /dev/null
+++ b/android/location/GeocoderParams.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 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.location;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Locale;
+
+/**
+ * This class contains extra parameters to pass to an IGeocodeProvider
+ * implementation from the Geocoder class.  Currently this contains the
+ * language, country and variant information from the Geocoder's locale
+ * as well as the Geocoder client's package name for geocoder server
+ * logging.  This information is kept in a separate class to allow for
+ * future expansion of the IGeocodeProvider interface.
+ *
+ * @hide
+ */
+public class GeocoderParams implements Parcelable {
+    private Locale mLocale;
+    private String mPackageName;
+
+    // used only for parcelling
+    private GeocoderParams() {
+    }
+
+    /**
+     * This object is only constructed by the Geocoder class
+     *
+     * @hide
+     */
+    public GeocoderParams(Context context, Locale locale) {
+        mLocale = locale;
+        mPackageName = context.getPackageName();
+    }
+
+    /**
+     * returns the Geocoder's locale
+     */
+    @UnsupportedAppUsage
+    public Locale getLocale() {
+        return mLocale;
+    }
+
+    /**
+     * returns the package name of the Geocoder's client
+     */
+    @UnsupportedAppUsage
+    public String getClientPackage() {
+        return mPackageName;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<GeocoderParams> CREATOR =
+        new Parcelable.Creator<GeocoderParams>() {
+        public GeocoderParams createFromParcel(Parcel in) {
+            GeocoderParams gp = new GeocoderParams();
+            String language = in.readString();
+            String country = in.readString();
+            String variant = in.readString();
+            gp.mLocale = new Locale(language, country, variant);
+            gp.mPackageName = in.readString();
+            return gp;
+        }
+
+        public GeocoderParams[] newArray(int size) {
+            return new GeocoderParams[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mLocale.getLanguage());
+        parcel.writeString(mLocale.getCountry());
+        parcel.writeString(mLocale.getVariant());
+        parcel.writeString(mPackageName);
+    }
+}
diff --git a/android/location/Geofence.java b/android/location/Geofence.java
new file mode 100644
index 0000000..af57bfd
--- /dev/null
+++ b/android/location/Geofence.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2012 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.location;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a geographical boundary, also known as a geofence.
+ *
+ * <p>Currently only circular geofences are supported and they do not support altitude changes.
+ *
+ * @hide
+ */
+public final class Geofence implements Parcelable {
+    /** @hide */
+    public static final int TYPE_HORIZONTAL_CIRCLE = 1;
+
+    private final int mType;
+    private final double mLatitude;
+    private final double mLongitude;
+    private final float mRadius;
+
+    /**
+     * Create a circular geofence (on a flat, horizontal plane).
+     *
+     * @param latitude latitude in degrees, between -90 and +90 inclusive
+     * @param longitude longitude in degrees, between -180 and +180 inclusive
+     * @param radius radius in meters
+     * @return a new geofence
+     * @throws IllegalArgumentException if any parameters are out of range
+     */
+    public static Geofence createCircle(double latitude, double longitude, float radius) {
+        return new Geofence(latitude, longitude, radius);
+    }
+
+    private Geofence(double latitude, double longitude, float radius) {
+        checkRadius(radius);
+        checkLatLong(latitude, longitude);
+        mType = TYPE_HORIZONTAL_CIRCLE;
+        mLatitude = latitude;
+        mLongitude = longitude;
+        mRadius = radius;
+    }
+
+    /** @hide */
+    public int getType() {
+        return mType;
+    }
+
+    /** @hide */
+    public double getLatitude() {
+        return mLatitude;
+    }
+
+    /** @hide */
+    public double getLongitude() {
+        return mLongitude;
+    }
+
+    /** @hide */
+    public float getRadius() {
+        return mRadius;
+    }
+
+    private static void checkRadius(float radius) {
+        if (radius <= 0) {
+            throw new IllegalArgumentException("invalid radius: " + radius);
+        }
+    }
+
+    private static void checkLatLong(double latitude, double longitude) {
+        if (latitude > 90.0 || latitude < -90.0) {
+            throw new IllegalArgumentException("invalid latitude: " + latitude);
+        }
+        if (longitude > 180.0 || longitude < -180.0) {
+            throw new IllegalArgumentException("invalid longitude: " + longitude);
+        }
+    }
+
+    private static void checkType(int type) {
+        if (type != TYPE_HORIZONTAL_CIRCLE) {
+            throw new IllegalArgumentException("invalid type: " + type);
+        }
+    }
+
+    @UnsupportedAppUsage
+    public static final @android.annotation.NonNull Parcelable.Creator<Geofence> CREATOR = new Parcelable.Creator<Geofence>() {
+        @Override
+        public Geofence createFromParcel(Parcel in) {
+            int type = in.readInt();
+            double latitude = in.readDouble();
+            double longitude = in.readDouble();
+            float radius = in.readFloat();
+            checkType(type);
+            return Geofence.createCircle(latitude, longitude, radius);
+        }
+        @Override
+        public Geofence[] newArray(int size) {
+            return new Geofence[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mType);
+        parcel.writeDouble(mLatitude);
+        parcel.writeDouble(mLongitude);
+        parcel.writeFloat(mRadius);
+    }
+
+    private static String typeToString(int type) {
+        switch (type) {
+            case TYPE_HORIZONTAL_CIRCLE:
+                return "CIRCLE";
+            default:
+                checkType(type);
+                return null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return String.format("Geofence[%s %.6f, %.6f %.0fm]",
+                typeToString(mType), mLatitude, mLongitude, mRadius);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        long temp;
+        temp = Double.doubleToLongBits(mLatitude);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        temp = Double.doubleToLongBits(mLongitude);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        result = prime * result + Float.floatToIntBits(mRadius);
+        result = prime * result + mType;
+        return result;
+    }
+
+    /**
+     * Two geofences are equal if they have identical properties.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (!(obj instanceof Geofence))
+            return false;
+        Geofence other = (Geofence) obj;
+        if (mRadius != other.mRadius)
+            return false;
+        if (mLatitude != other.mLatitude)
+            return false;
+        if (mLongitude != other.mLongitude)
+            return false;
+        if (mType != other.mType)
+            return false;
+        return true;
+    }
+}
diff --git a/android/location/GnssAntennaInfo.java b/android/location/GnssAntennaInfo.java
new file mode 100644
index 0000000..b2f9a0f
--- /dev/null
+++ b/android/location/GnssAntennaInfo.java
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2020 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.location;
+
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A class that contains information about a GNSS antenna. GNSS antenna characteristics can change
+ * with device configuration, such as when a device is folded open or closed. Antenna information is
+ * delivered to registered instances of {@link Listener}.
+ */
+public final class GnssAntennaInfo implements Parcelable {
+    private final double mCarrierFrequencyMHz;
+    private final PhaseCenterOffset mPhaseCenterOffset;
+    private final SphericalCorrections mPhaseCenterVariationCorrections;
+    private final SphericalCorrections mSignalGainCorrections;
+
+    /**
+     * Used for receiving GNSS antenna info from the GNSS engine. You can implement this interface
+     * and call {@link LocationManager#registerAntennaInfoListener};
+     */
+    public interface Listener {
+        /**
+         * Returns the latest GNSS antenna info. This event is triggered when a listener is
+         * registered, and whenever the antenna info changes (due to a device configuration change).
+         */
+        void onGnssAntennaInfoReceived(@NonNull List<GnssAntennaInfo> gnssAntennaInfos);
+    }
+
+    /**
+     * Class containing information about the antenna phase center offset (PCO). PCO is defined with
+     * respect to the origin of the Android sensor coordinate system, e.g., center of primary screen
+     * for mobiles - see sensor or form factor documents for details. Uncertainties are reported
+     *  to 1-sigma.
+     */
+    public static final class PhaseCenterOffset implements Parcelable {
+        private final double mOffsetXMm;
+        private final double mOffsetXUncertaintyMm;
+        private final double mOffsetYMm;
+        private final double mOffsetYUncertaintyMm;
+        private final double mOffsetZMm;
+        private final double mOffsetZUncertaintyMm;
+
+        public PhaseCenterOffset(
+                double offsetXMm, double offsetXUncertaintyMm,
+                double offsetYMm, double offsetYUncertaintyMm,
+                double offsetZMm, double offsetZUncertaintyMm) {
+            mOffsetXMm = offsetXMm;
+            mOffsetYMm = offsetYMm;
+            mOffsetZMm = offsetZMm;
+            mOffsetXUncertaintyMm = offsetXUncertaintyMm;
+            mOffsetYUncertaintyMm = offsetYUncertaintyMm;
+            mOffsetZUncertaintyMm = offsetZUncertaintyMm;
+        }
+
+        public static final @NonNull Creator<PhaseCenterOffset> CREATOR =
+                new Creator<PhaseCenterOffset>() {
+                    @Override
+                    public PhaseCenterOffset createFromParcel(Parcel in) {
+                        return new PhaseCenterOffset(
+                                in.readDouble(),
+                                in.readDouble(),
+                                in.readDouble(),
+                                in.readDouble(),
+                                in.readDouble(),
+                                in.readDouble()
+                        );
+                    }
+
+                    @Override
+                    public PhaseCenterOffset[] newArray(int size) {
+                        return new PhaseCenterOffset[size];
+                    }
+                };
+
+        @FloatRange()
+        public double getXOffsetMm() {
+            return mOffsetXMm;
+        }
+
+        @FloatRange()
+        public double getXOffsetUncertaintyMm() {
+            return mOffsetXUncertaintyMm;
+        }
+
+        @FloatRange()
+        public double getYOffsetMm() {
+            return mOffsetYMm;
+        }
+
+        @FloatRange()
+        public double getYOffsetUncertaintyMm() {
+            return mOffsetYUncertaintyMm;
+        }
+
+        @FloatRange()
+        public double getZOffsetMm() {
+            return mOffsetZMm;
+        }
+
+        @FloatRange()
+        public double getZOffsetUncertaintyMm() {
+            return mOffsetZUncertaintyMm;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeDouble(mOffsetXMm);
+            dest.writeDouble(mOffsetXUncertaintyMm);
+            dest.writeDouble(mOffsetYMm);
+            dest.writeDouble(mOffsetYUncertaintyMm);
+            dest.writeDouble(mOffsetZMm);
+            dest.writeDouble(mOffsetZUncertaintyMm);
+        }
+
+        @Override
+        public String toString() {
+            return "PhaseCenterOffset{"
+                    + "OffsetXMm=" + mOffsetXMm + " +/-" + mOffsetXUncertaintyMm
+                    + ", OffsetYMm=" + mOffsetYMm + " +/-" + mOffsetYUncertaintyMm
+                    + ", OffsetZMm=" + mOffsetZMm + " +/-" + mOffsetZUncertaintyMm
+                    + '}';
+        }
+    }
+
+    /**
+     * Represents corrections on a spherical mapping. Corrections are added to measurements to
+     * obtain the corrected values.
+     *
+     * The corrections and associated (1-sigma) uncertainties are represented by respect 2D arrays.
+     *
+     * Each row (major indices) represents a fixed theta. The first row corresponds to a
+     * theta angle of 0 degrees. The last row corresponds to a theta angle of (360 - deltaTheta)
+     * degrees, where deltaTheta is the regular spacing between azimuthal angles, i.e., deltaTheta
+     * = 360 / (number of rows).
+     *
+     * The columns (minor indices) represent fixed zenith angles, beginning at 0 degrees and ending
+     * at 180 degrees. They are separated by deltaPhi, the regular spacing between zenith angles,
+     * i.e., deltaPhi = 180 / (number of columns - 1).
+     */
+    public static final class SphericalCorrections implements Parcelable{
+        private final double[][] mCorrections;
+        private final double[][] mCorrectionUncertainties;
+        private final double mDeltaTheta;
+        private final double mDeltaPhi;
+        private final int mNumRows;
+        private final int mNumColumns;
+
+        public SphericalCorrections(@NonNull double[][] corrections,
+                @NonNull double[][] correctionUncertainties) {
+            if (corrections.length != correctionUncertainties.length
+                    || corrections[0].length != correctionUncertainties[0].length) {
+                throw new IllegalArgumentException("Correction and correction uncertainty arrays "
+                        + "must have the same dimensions.");
+            }
+
+            mNumRows = corrections.length;
+            if (mNumRows < 1) {
+                throw new IllegalArgumentException("Arrays must have at least one row.");
+            }
+
+            mNumColumns = corrections[0].length;
+            if (mNumColumns < 2) {
+                throw new IllegalArgumentException("Arrays must have at least two columns.");
+            }
+
+            mCorrections = corrections;
+            mCorrectionUncertainties = correctionUncertainties;
+            mDeltaTheta = 360.0d / mNumRows;
+            mDeltaPhi = 180.0d / (mNumColumns - 1);
+        }
+
+        SphericalCorrections(Parcel in) {
+            int numRows = in.readInt();
+            int numColumns = in.readInt();
+
+            double[][] corrections =
+                    new double[numRows][numColumns];
+            double[][] correctionUncertainties =
+                    new double[numRows][numColumns];
+
+            for (int row = 0; row < numRows; row++) {
+                in.readDoubleArray(corrections[row]);
+            }
+
+            for (int row = 0; row < numRows; row++) {
+                in.readDoubleArray(correctionUncertainties[row]);
+            }
+
+            mNumRows = numRows;
+            mNumColumns = numColumns;
+            mCorrections = corrections;
+            mCorrectionUncertainties = correctionUncertainties;
+            mDeltaTheta = 360.0d / mNumRows;
+            mDeltaPhi = 180.0d / (mNumColumns - 1);
+        }
+
+        /**
+         * Array representing corrections on a spherical mapping. Corrections are added to
+         * measurements to obtain the corrected values.
+         *
+         * Each row (major indices) represents a fixed theta. The first row corresponds to a
+         * theta angle of 0 degrees. The last row corresponds to a theta angle of (360 - deltaTheta)
+         * degrees, where deltaTheta is the regular spacing between azimuthal angles, i.e.,
+         * deltaTheta = 360 / (number of rows).
+         *
+         * The columns (minor indices) represent fixed zenith angles, beginning at 0 degrees and
+         * ending at 180 degrees. They are separated by deltaPhi, the regular spacing between zenith
+         * angles, i.e., deltaPhi = 180 / (number of columns - 1).
+         */
+        @NonNull
+        public double[][] getCorrectionsArray() {
+            return mCorrections;
+        }
+
+        /**
+         * Array representing uncertainty on corrections on a spherical mapping.
+         *
+         * Each row (major indices) represents a fixed theta. The first row corresponds to a
+         * theta angle of 0 degrees. The last row corresponds to a theta angle of (360 - deltaTheta)
+         * degrees, where deltaTheta is the regular spacing between azimuthal angles, i.e.,
+         * deltaTheta = 360 / (number of rows).
+         *
+         * The columns (minor indices) represent fixed zenith angles, beginning at 0 degrees and
+         * ending at 180 degrees. They are separated by deltaPhi, the regular spacing between zenith
+         * angles, i.e., deltaPhi = 180 / (number of columns - 1).
+         */
+        @NonNull
+        public double[][] getCorrectionUncertaintiesArray() {
+            return mCorrectionUncertainties;
+        }
+
+        /**
+         * The fixed theta angle separation between successive rows.
+         */
+        @FloatRange(from = 0.0f, to = 360.0f)
+        public double getDeltaTheta() {
+            return mDeltaTheta;
+        }
+
+        /**
+         * The fixed phi angle separation between successive columns.
+         */
+        @FloatRange(from = 0.0f, to = 180.0f)
+        public double getDeltaPhi() {
+            return mDeltaPhi;
+        }
+
+
+        public static final @NonNull Creator<SphericalCorrections> CREATOR =
+                new Creator<SphericalCorrections>() {
+                    @Override
+                    public SphericalCorrections createFromParcel(Parcel in) {
+                        return new SphericalCorrections(in);
+                    }
+
+                    @Override
+                    public SphericalCorrections[] newArray(int size) {
+                        return new SphericalCorrections[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mNumRows);
+            dest.writeInt(mNumColumns);
+            for (double[] row: mCorrections) {
+                dest.writeDoubleArray(row);
+            }
+            for (double[] row: mCorrectionUncertainties) {
+                dest.writeDoubleArray(row);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "SphericalCorrections{"
+                    + "Corrections=" + Arrays.toString(mCorrections)
+                    + ", CorrectionUncertainties=" + Arrays.toString(mCorrectionUncertainties)
+                    + ", DeltaTheta=" + mDeltaTheta
+                    + ", DeltaPhi=" + mDeltaPhi
+                    + '}';
+        }
+    }
+
+    private GnssAntennaInfo(
+            double carrierFrequencyMHz,
+            @NonNull PhaseCenterOffset phaseCenterOffset,
+            @Nullable SphericalCorrections phaseCenterVariationCorrections,
+            @Nullable SphericalCorrections signalGainCorrectionDbi) {
+        if (phaseCenterOffset == null) {
+            throw new IllegalArgumentException("Phase Center Offset Coordinates cannot be null.");
+        }
+        mCarrierFrequencyMHz = carrierFrequencyMHz;
+        mPhaseCenterOffset = phaseCenterOffset;
+        mPhaseCenterVariationCorrections = phaseCenterVariationCorrections;
+        mSignalGainCorrections = signalGainCorrectionDbi;
+    }
+
+    /**
+     * Builder class for GnssAntennaInfo.
+     */
+    public static class Builder {
+        private double mCarrierFrequencyMHz;
+        private PhaseCenterOffset mPhaseCenterOffset;
+        private SphericalCorrections mPhaseCenterVariationCorrections;
+        private SphericalCorrections mSignalGainCorrections;
+
+        /**
+         * Set antenna carrier frequency (MHz).
+         * @param carrierFrequencyMHz antenna carrier frequency (MHz)
+         * @return Builder builder object
+         */
+        @NonNull
+        public Builder setCarrierFrequencyMHz(@FloatRange(from = 0.0f) double carrierFrequencyMHz) {
+            mCarrierFrequencyMHz = carrierFrequencyMHz;
+            return this;
+        }
+
+        /**
+         * Set antenna phase center offset.
+         * @param phaseCenterOffset phase center offset object
+         * @return Builder builder object
+         */
+        @NonNull
+        public Builder setPhaseCenterOffset(@NonNull PhaseCenterOffset phaseCenterOffset) {
+            mPhaseCenterOffset = Objects.requireNonNull(phaseCenterOffset);
+            return this;
+        }
+
+        /**
+         * Set phase center variation corrections.
+         * @param phaseCenterVariationCorrections phase center variation corrections object
+         * @return Builder builder object
+         */
+        @NonNull
+        public Builder setPhaseCenterVariationCorrections(
+                @Nullable SphericalCorrections phaseCenterVariationCorrections) {
+            mPhaseCenterVariationCorrections = phaseCenterVariationCorrections;
+            return this;
+        }
+
+        /**
+         * Set signal gain corrections.
+         * @param signalGainCorrections signal gain corrections object
+         * @return Builder builder object
+         */
+        @NonNull
+        public Builder setSignalGainCorrections(
+                @Nullable SphericalCorrections signalGainCorrections) {
+            mSignalGainCorrections = signalGainCorrections;
+            return this;
+        }
+
+        /**
+         * Build GnssAntennaInfo object.
+         * @return instance of GnssAntennaInfo
+         */
+        @NonNull
+        public GnssAntennaInfo build() {
+            return new GnssAntennaInfo(mCarrierFrequencyMHz, mPhaseCenterOffset,
+                    mPhaseCenterVariationCorrections, mSignalGainCorrections);
+        }
+    }
+
+    @FloatRange(from = 0.0f)
+    public double getCarrierFrequencyMHz() {
+        return mCarrierFrequencyMHz;
+    }
+
+    @NonNull
+    public PhaseCenterOffset getPhaseCenterOffset() {
+        return mPhaseCenterOffset;
+    }
+
+    @Nullable
+    public SphericalCorrections getPhaseCenterVariationCorrections() {
+        return mPhaseCenterVariationCorrections;
+    }
+
+    @Nullable
+    public SphericalCorrections getSignalGainCorrections() {
+        return mSignalGainCorrections;
+    }
+
+    public static final @android.annotation.NonNull
+                    Creator<GnssAntennaInfo> CREATOR = new Creator<GnssAntennaInfo>() {
+                            @Override
+                            public GnssAntennaInfo createFromParcel(Parcel in) {
+                                double carrierFrequencyMHz = in.readDouble();
+
+                                ClassLoader classLoader = getClass().getClassLoader();
+                                PhaseCenterOffset phaseCenterOffset =
+                                        in.readParcelable(classLoader);
+                                SphericalCorrections phaseCenterVariationCorrections =
+                                        in.readParcelable(classLoader);
+                                SphericalCorrections signalGainCorrections =
+                                        in.readParcelable(classLoader);
+
+                                return new GnssAntennaInfo(
+                                            carrierFrequencyMHz,
+                                            phaseCenterOffset,
+                                            phaseCenterVariationCorrections,
+                                            signalGainCorrections);
+                            }
+
+                            @Override
+                            public GnssAntennaInfo[] newArray(int size) {
+                                return new GnssAntennaInfo[size];
+                            }
+                    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeDouble(mCarrierFrequencyMHz);
+        parcel.writeParcelable(mPhaseCenterOffset, flags);
+        parcel.writeParcelable(mPhaseCenterVariationCorrections, flags);
+        parcel.writeParcelable(mSignalGainCorrections, flags);
+    }
+
+    @Override
+    public String toString() {
+        return "GnssAntennaInfo{"
+                + "CarrierFrequencyMHz=" + mCarrierFrequencyMHz
+                + ", PhaseCenterOffset=" + mPhaseCenterOffset
+                + ", PhaseCenterVariationCorrections=" + mPhaseCenterVariationCorrections
+                + ", SignalGainCorrections=" + mSignalGainCorrections
+                + '}';
+    }
+}
diff --git a/android/location/GnssCapabilities.java b/android/location/GnssCapabilities.java
new file mode 100644
index 0000000..5734bf2
--- /dev/null
+++ b/android/location/GnssCapabilities.java
@@ -0,0 +1,207 @@
+/*
+ * 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.location;
+
+import android.annotation.SystemApi;
+
+/**
+ * A container of supported GNSS chipset capabilities.
+ */
+public final class GnssCapabilities {
+    /**
+     * Bit mask indicating GNSS chipset supports low power mode.
+     * @hide
+     */
+    public static final long LOW_POWER_MODE                                     = 1L << 0;
+
+    /**
+     * Bit mask indicating GNSS chipset supports blacklisting satellites.
+     * @hide
+     */
+    public static final long SATELLITE_BLACKLIST                                = 1L << 1;
+
+    /**
+     * Bit mask indicating GNSS chipset supports geofencing.
+     * @hide
+     */
+    public static final long GEOFENCING                                         = 1L << 2;
+
+    /**
+     * Bit mask indicating GNSS chipset supports measurements.
+     * @hide
+     */
+    public static final long MEASUREMENTS                                       = 1L << 3;
+
+    /**
+     * Bit mask indicating GNSS chipset supports navigation messages.
+     * @hide
+     */
+    public static final long NAV_MESSAGES                                       = 1L << 4;
+
+    /**
+     * Bit mask indicating GNSS chipset supports measurement corrections.
+     * @hide
+     */
+    public static final long MEASUREMENT_CORRECTIONS                            = 1L << 5;
+
+    /**
+     * Bit mask indicating GNSS chipset supports line-of-sight satellite identification
+     * measurement corrections.
+     * @hide
+     */
+    public static final long MEASUREMENT_CORRECTIONS_LOS_SATS                   = 1L << 6;
+
+    /**
+     * Bit mask indicating GNSS chipset supports per satellite excess-path-length
+     * measurement corrections.
+     * @hide
+     */
+    public static final long MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH         = 1L << 7;
+
+    /**
+     * Bit mask indicating GNSS chipset supports reflecting planes measurement corrections.
+     * @hide
+     */
+    public static final long MEASUREMENT_CORRECTIONS_REFLECTING_PLANE           = 1L << 8;
+
+    /**
+     * Bit mask indicating GNSS chipset supports GNSS antenna info.
+     * @hide
+     */
+    public static final long ANTENNA_INFO                                       = 1L << 9;
+
+    /** @hide */
+    public static final long INVALID_CAPABILITIES = -1;
+
+    /** A bitmask of supported GNSS capabilities. */
+    private final long mGnssCapabilities;
+
+    /** @hide */
+    public static GnssCapabilities of(long gnssCapabilities) {
+        return new GnssCapabilities(gnssCapabilities);
+    }
+
+    private GnssCapabilities(long gnssCapabilities) {
+        mGnssCapabilities = gnssCapabilities;
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports low power mode, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasLowPowerMode() {
+        return hasCapability(LOW_POWER_MODE);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports blacklisting satellites, {@code false}
+     * otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasSatelliteBlacklist() {
+        return hasCapability(SATELLITE_BLACKLIST);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports geofencing, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasGeofencing() {
+        return hasCapability(GEOFENCING);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports measurements, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasMeasurements() {
+        return hasCapability(MEASUREMENTS);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports navigation messages, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasNavMessages() {
+        return hasCapability(NAV_MESSAGES);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports measurement corrections, {@code false}
+     * otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasMeasurementCorrections() {
+        return hasCapability(MEASUREMENT_CORRECTIONS);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports line-of-sight satellite identification
+     * measurement corrections, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasMeasurementCorrectionsLosSats() {
+        return hasCapability(MEASUREMENT_CORRECTIONS_LOS_SATS);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports per satellite excess-path-length measurement
+     * corrections, {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasMeasurementCorrectionsExcessPathLength() {
+        return hasCapability(MEASUREMENT_CORRECTIONS_EXCESS_PATH_LENGTH);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports reflecting planes measurement corrections,
+     * {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean hasMeasurementCorrectionsReflectingPane() {
+        return hasCapability(MEASUREMENT_CORRECTIONS_REFLECTING_PLANE);
+    }
+
+    /**
+     * Returns {@code true} if GNSS chipset supports antenna info, {@code false} otherwise.
+     */
+    public boolean hasGnssAntennaInfo() {
+        return hasCapability(ANTENNA_INFO);
+    }
+
+    private boolean hasCapability(long capability) {
+        return (mGnssCapabilities & capability) == capability;
+    }
+}
diff --git a/android/location/GnssClock.java b/android/location/GnssClock.java
new file mode 100644
index 0000000..ed4bf1b
--- /dev/null
+++ b/android/location/GnssClock.java
@@ -0,0 +1,810 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class containing a GPS clock timestamp.
+ *
+ * <p>It represents a measurement of the GPS receiver's clock.
+ */
+public final class GnssClock implements Parcelable {
+    // The following enumerations must be in sync with the values declared in gps.h
+
+    private static final int HAS_NO_FLAGS = 0;
+    private static final int HAS_LEAP_SECOND = (1<<0);
+    private static final int HAS_TIME_UNCERTAINTY = (1<<1);
+    private static final int HAS_FULL_BIAS = (1<<2);
+    private static final int HAS_BIAS = (1<<3);
+    private static final int HAS_BIAS_UNCERTAINTY = (1<<4);
+    private static final int HAS_DRIFT = (1<<5);
+    private static final int HAS_DRIFT_UNCERTAINTY = (1<<6);
+    private static final int HAS_ELAPSED_REALTIME_NANOS = (1 << 7);
+    private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS = (1 << 8);
+    private static final int HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB = (1 << 9);
+    private static final int HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB = (1 << 10);
+    private static final int HAS_REFERENCE_CODE_TYPE_FOR_ISB = (1 << 11);
+
+    // End enumerations in sync with gps.h
+
+    private int mFlags;
+    private int mLeapSecond;
+    private long mTimeNanos;
+    private double mTimeUncertaintyNanos;
+    private long mFullBiasNanos;
+    private double mBiasNanos;
+    private double mBiasUncertaintyNanos;
+    private double mDriftNanosPerSecond;
+    private double mDriftUncertaintyNanosPerSecond;
+    private int mHardwareClockDiscontinuityCount;
+    private long mElapsedRealtimeNanos;
+    private double mElapsedRealtimeUncertaintyNanos;
+    private int mReferenceConstellationTypeForIsb;
+    private double mReferenceCarrierFrequencyHzForIsb;
+    private String mReferenceCodeTypeForIsb;
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public GnssClock() {
+        initialize();
+    }
+
+    /**
+     * Sets all contents to the values stored in the provided object.
+     * @hide
+     */
+    @TestApi
+    public void set(GnssClock clock) {
+        mFlags = clock.mFlags;
+        mLeapSecond = clock.mLeapSecond;
+        mTimeNanos = clock.mTimeNanos;
+        mTimeUncertaintyNanos = clock.mTimeUncertaintyNanos;
+        mFullBiasNanos = clock.mFullBiasNanos;
+        mBiasNanos = clock.mBiasNanos;
+        mBiasUncertaintyNanos = clock.mBiasUncertaintyNanos;
+        mDriftNanosPerSecond = clock.mDriftNanosPerSecond;
+        mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond;
+        mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount;
+        mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos;
+        mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos;
+        mReferenceConstellationTypeForIsb = clock.mReferenceConstellationTypeForIsb;
+        mReferenceCarrierFrequencyHzForIsb = clock.mReferenceCarrierFrequencyHzForIsb;
+        mReferenceCodeTypeForIsb = clock.mReferenceCodeTypeForIsb;
+    }
+
+    /**
+     * Resets all the contents to its original state.
+     * @hide
+     */
+    @TestApi
+    public void reset() {
+        initialize();
+    }
+
+    /**
+     * Returns {@code true} if {@link #getLeapSecond()} is available, {@code false} otherwise.
+     */
+    public boolean hasLeapSecond() {
+        return isFlagSet(HAS_LEAP_SECOND);
+    }
+
+    /**
+     * Gets the leap second associated with the clock's time.
+     *
+     * <p>The sign of the value is defined by the following equation:
+     * <pre>
+     *     UtcTimeNanos = TimeNanos - (FullBiasNanos + BiasNanos) - LeapSecond * 1,000,000,000</pre>
+     *
+     * <p>The value is only available if {@link #hasLeapSecond()} is {@code true}.
+     */
+    public int getLeapSecond() {
+        return mLeapSecond;
+    }
+
+    /**
+     * Sets the leap second associated with the clock's time.
+     * @hide
+     */
+    @TestApi
+    public void setLeapSecond(int leapSecond) {
+        setFlag(HAS_LEAP_SECOND);
+        mLeapSecond = leapSecond;
+    }
+
+    /**
+     * Resets the leap second associated with the clock's time.
+     * @hide
+     */
+    @TestApi
+    public void resetLeapSecond() {
+        resetFlag(HAS_LEAP_SECOND);
+        mLeapSecond = Integer.MIN_VALUE;
+    }
+
+    /**
+     * Gets the GNSS receiver internal hardware clock value in nanoseconds.
+     *
+     * <p>This value is expected to be monotonically increasing while the hardware clock remains
+     * powered on. For the case of a hardware clock that is not continuously on, see the
+     * {@link #getHardwareClockDiscontinuityCount} field. The GPS time can be derived by subtracting
+     * the sum of {@link #getFullBiasNanos()} and {@link #getBiasNanos()} (when they are available)
+     * from this value. Sub-nanosecond accuracy can be provided by means of {@link #getBiasNanos()}.
+     *
+     * <p>The error estimate for this value (if applicable) is {@link #getTimeUncertaintyNanos()}.
+     */
+    public long getTimeNanos() {
+        return mTimeNanos;
+    }
+
+    /**
+     * Sets the GNSS receiver internal clock in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setTimeNanos(long timeNanos) {
+        mTimeNanos = timeNanos;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getTimeUncertaintyNanos()} is available, {@code false}
+     * otherwise.
+     */
+    public boolean hasTimeUncertaintyNanos() {
+        return isFlagSet(HAS_TIME_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the clock's time Uncertainty (1-Sigma) in nanoseconds.
+     *
+     * <p>The uncertainty is represented as an absolute (single sided) value.
+     *
+     * <p>The value is only available if {@link #hasTimeUncertaintyNanos()} is {@code true}.
+     *
+     * <p>This value is often effectively zero (it is the reference clock by which all other times
+     * and time uncertainties are measured), and thus this field may often be 0, or not provided.
+     */
+    @FloatRange(from = 0.0f)
+    public double getTimeUncertaintyNanos() {
+        return mTimeUncertaintyNanos;
+    }
+
+    /**
+     * Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setTimeUncertaintyNanos(@FloatRange(from = 0.0f) double timeUncertaintyNanos) {
+        setFlag(HAS_TIME_UNCERTAINTY);
+        mTimeUncertaintyNanos = timeUncertaintyNanos;
+    }
+
+    /**
+     * Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void resetTimeUncertaintyNanos() {
+        resetFlag(HAS_TIME_UNCERTAINTY);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getFullBiasNanos()} is available, {@code false} otherwise.
+     */
+    public boolean hasFullBiasNanos() {
+        return isFlagSet(HAS_FULL_BIAS);
+    }
+
+    /**
+     * Gets the difference between hardware clock ({@link #getTimeNanos()}) inside GPS receiver and
+     * the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
+     *
+     * <p>This value is available if the receiver has estimated GPS time. If the computed time is
+     * for a non-GPS constellation, the time offset of that constellation to GPS has to be applied
+     * to fill this value. The value is only available if {@link #hasFullBiasNanos()} is
+     * {@code true}.
+     *
+     * <p>The error estimate for the sum of this field and {@link #getBiasNanos} is
+     * {@link #getBiasUncertaintyNanos()}.
+     *
+     * <p>The sign of the value is defined by the following equation:
+     *
+     * <pre>
+     *     local estimate of GPS time = TimeNanos - (FullBiasNanos + BiasNanos)</pre>
+     */
+    public long getFullBiasNanos() {
+        return mFullBiasNanos;
+    }
+
+    /**
+     * Sets the full bias in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setFullBiasNanos(long value) {
+        setFlag(HAS_FULL_BIAS);
+        mFullBiasNanos = value;
+    }
+
+    /**
+     * Resets the full bias in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void resetFullBiasNanos() {
+        resetFlag(HAS_FULL_BIAS);
+        mFullBiasNanos = Long.MIN_VALUE;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getBiasNanos()} is available, {@code false} otherwise.
+     */
+    public boolean hasBiasNanos() {
+        return isFlagSet(HAS_BIAS);
+    }
+
+    /**
+     * Gets the clock's sub-nanosecond bias.
+     *
+     * <p>See the description of how this field is part of converting from hardware clock time, to
+     * GPS time, in {@link #getFullBiasNanos()}.
+     *
+     * <p>The error estimate for the sum of this field and {@link #getFullBiasNanos} is
+     * {@link #getBiasUncertaintyNanos()}.
+     *
+     * <p>The value is only available if {@link #hasBiasNanos()} is {@code true}.
+     */
+    public double getBiasNanos() {
+        return mBiasNanos;
+    }
+
+    /**
+     * Sets the sub-nanosecond bias.
+     * @hide
+     */
+    @TestApi
+    public void setBiasNanos(double biasNanos) {
+        setFlag(HAS_BIAS);
+        mBiasNanos = biasNanos;
+    }
+
+    /**
+     * Resets the clock's Bias in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void resetBiasNanos() {
+        resetFlag(HAS_BIAS);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getBiasUncertaintyNanos()} is available, {@code false}
+     * otherwise.
+     */
+    public boolean hasBiasUncertaintyNanos() {
+        return isFlagSet(HAS_BIAS_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
+     *
+     * <p>See the description of how this field provides the error estimate in the conversion from
+     * hardware clock time, to GPS time, in {@link #getFullBiasNanos()}.
+     *
+     * <p>The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}.
+     */
+    @FloatRange(from = 0.0f)
+    public double getBiasUncertaintyNanos() {
+        return mBiasUncertaintyNanos;
+    }
+
+    /**
+     * Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setBiasUncertaintyNanos(@FloatRange(from = 0.0f) double biasUncertaintyNanos) {
+        setFlag(HAS_BIAS_UNCERTAINTY);
+        mBiasUncertaintyNanos = biasUncertaintyNanos;
+    }
+
+    /**
+     * Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void resetBiasUncertaintyNanos() {
+        resetFlag(HAS_BIAS_UNCERTAINTY);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getDriftNanosPerSecond()} is available, {@code false}
+     * otherwise.
+     */
+    public boolean hasDriftNanosPerSecond() {
+        return isFlagSet(HAS_DRIFT);
+    }
+
+    /**
+     * Gets the clock's Drift in nanoseconds per second.
+     *
+     * <p>This value is the instantaneous time-derivative of the value provided by
+     * {@link #getBiasNanos()}.
+     *
+     * <p>A positive value indicates that the frequency is higher than the nominal (e.g. GPS master
+     * clock) frequency. The error estimate for this reported drift is
+     * {@link #getDriftUncertaintyNanosPerSecond()}.
+     *
+     * <p>The value is only available if {@link #hasDriftNanosPerSecond()} is {@code true}.
+     */
+    public double getDriftNanosPerSecond() {
+        return mDriftNanosPerSecond;
+    }
+
+    /**
+     * Sets the clock's Drift in nanoseconds per second.
+     * @hide
+     */
+    @TestApi
+    public void setDriftNanosPerSecond(double driftNanosPerSecond) {
+        setFlag(HAS_DRIFT);
+        mDriftNanosPerSecond = driftNanosPerSecond;
+    }
+
+    /**
+     * Resets the clock's Drift in nanoseconds per second.
+     * @hide
+     */
+    @TestApi
+    public void resetDriftNanosPerSecond() {
+        resetFlag(HAS_DRIFT);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getDriftUncertaintyNanosPerSecond()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasDriftUncertaintyNanosPerSecond() {
+        return isFlagSet(HAS_DRIFT_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+     *
+     * <p>The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0f)
+    public double getDriftUncertaintyNanosPerSecond() {
+        return mDriftUncertaintyNanosPerSecond;
+    }
+
+    /**
+     * Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+     * @hide
+     */
+    @TestApi
+    public void setDriftUncertaintyNanosPerSecond(
+            @FloatRange(from = 0.0f) double driftUncertaintyNanosPerSecond) {
+        setFlag(HAS_DRIFT_UNCERTAINTY);
+        mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond;
+    }
+
+    /**
+     * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+     * @hide
+     */
+    @TestApi
+    public void resetDriftUncertaintyNanosPerSecond() {
+        resetFlag(HAS_DRIFT_UNCERTAINTY);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getElapsedRealtimeNanos()} is available, {@code false}
+     * otherwise.
+     */
+    public boolean hasElapsedRealtimeNanos() {
+        return isFlagSet(HAS_ELAPSED_REALTIME_NANOS);
+    }
+
+    /**
+     * Returns the elapsed real-time of this clock since system boot, in nanoseconds.
+     *
+     * <p>The value is only available if {@link #hasElapsedRealtimeNanos()} is
+     * {@code true}.
+     */
+    public long getElapsedRealtimeNanos() {
+        return mElapsedRealtimeNanos;
+    }
+
+    /**
+     * Sets the elapsed real-time of this clock since system boot, in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) {
+        setFlag(HAS_ELAPSED_REALTIME_NANOS);
+        mElapsedRealtimeNanos = elapsedRealtimeNanos;
+    }
+
+    /**
+     * Resets the elapsed real-time of this clock since system boot, in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void resetElapsedRealtimeNanos() {
+        resetFlag(HAS_ELAPSED_REALTIME_NANOS);
+        mElapsedRealtimeNanos = 0;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getElapsedRealtimeUncertaintyNanos()} is available, {@code
+     * false} otherwise.
+     */
+    public boolean hasElapsedRealtimeUncertaintyNanos() {
+        return isFlagSet(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+    }
+
+    /**
+     * Gets the estimate of the relative precision of the alignment of the
+     * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     *
+     * <p>The value is only available if {@link #hasElapsedRealtimeUncertaintyNanos()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0f)
+    public double getElapsedRealtimeUncertaintyNanos() {
+        return mElapsedRealtimeUncertaintyNanos;
+    }
+
+    /**
+     * Sets the estimate of the relative precision of the alignment of the
+     * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     * @hide
+     */
+    @TestApi
+    public void setElapsedRealtimeUncertaintyNanos(
+            @FloatRange(from = 0.0f) double elapsedRealtimeUncertaintyNanos) {
+        setFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+        mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos;
+    }
+
+    /**
+     * Resets the estimate of the relative precision of the alignment of the
+     * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     * @hide
+     */
+    @TestApi
+    public void resetElapsedRealtimeUncertaintyNanos() {
+        resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getReferenceConstellationTypeForIsb()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasReferenceConstellationTypeForIsb() {
+        return isFlagSet(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB);
+    }
+
+    /**
+     * Returns the reference constellation type for inter-signal bias.
+     *
+     * <p>The value is only available if {@link #hasReferenceConstellationTypeForIsb()} is
+     * {@code true}.
+     *
+     * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
+     * {@link GnssStatus}.
+     */
+    @GnssStatus.ConstellationType
+    public int getReferenceConstellationTypeForIsb() {
+        return mReferenceConstellationTypeForIsb;
+    }
+
+    /**
+     * Sets the reference constellation type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void setReferenceConstellationTypeForIsb(@GnssStatus.ConstellationType int value) {
+        setFlag(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB);
+        mReferenceConstellationTypeForIsb = value;
+    }
+
+    /**
+     * Resets the reference constellation type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void resetReferenceConstellationTypeForIsb() {
+        resetFlag(HAS_REFERENCE_CONSTELLATION_TYPE_FOR_ISB);
+        mReferenceConstellationTypeForIsb = GnssStatus.CONSTELLATION_UNKNOWN;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getReferenceCarrierFrequencyHzForIsb()} is available, {@code
+     * false} otherwise.
+     */
+    public boolean hasReferenceCarrierFrequencyHzForIsb() {
+        return isFlagSet(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB);
+    }
+
+    /**
+     * Returns the reference carrier frequency in Hz for inter-signal bias.
+     *
+     * <p>The value is only available if {@link #hasReferenceCarrierFrequencyHzForIsb()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0)
+    public double getReferenceCarrierFrequencyHzForIsb() {
+        return mReferenceCarrierFrequencyHzForIsb;
+    }
+
+    /**
+     * Sets the reference carrier frequency in Hz for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void setReferenceCarrierFrequencyHzForIsb(@FloatRange(from = 0.0) double value) {
+        setFlag(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB);
+        mReferenceCarrierFrequencyHzForIsb = value;
+    }
+
+    /**
+     * Resets the reference carrier frequency in Hz for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void resetReferenceCarrierFrequencyHzForIsb() {
+        resetFlag(HAS_REFERENCE_CARRIER_FREQUENCY_FOR_ISB);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getReferenceCodeTypeForIsb()} is available, {@code
+     * false} otherwise.
+     */
+    public boolean hasReferenceCodeTypeForIsb() {
+        return isFlagSet(HAS_REFERENCE_CODE_TYPE_FOR_ISB);
+    }
+
+    /**
+     * Returns the reference code type for inter-signal bias.
+     *
+     * <p>The value is only available if {@link #hasReferenceCodeTypeForIsb()} is
+     * {@code true}.
+     *
+     * <p>The return value is one of those constants defined in
+     * {@link GnssMeasurement#getCodeType()}.
+     */
+    @NonNull
+    public String getReferenceCodeTypeForIsb() {
+        return mReferenceCodeTypeForIsb;
+    }
+
+    /**
+     * Sets the reference code type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void setReferenceCodeTypeForIsb(@NonNull String codeType) {
+        setFlag(HAS_REFERENCE_CODE_TYPE_FOR_ISB);
+        mReferenceCodeTypeForIsb = codeType;
+    }
+
+    /**
+     * Resets the reference code type for inter-signal bias.
+     * @hide
+     */
+    @TestApi
+    public void resetReferenceCodeTypeForIsb() {
+        resetFlag(HAS_REFERENCE_CODE_TYPE_FOR_ISB);
+        mReferenceCodeTypeForIsb = "UNKNOWN";
+    }
+
+    /**
+     * Gets count of hardware clock discontinuities.
+     *
+     * <p>When this value stays the same, vs. a value in a previously reported {@link GnssClock}, it
+     * can be safely assumed that the {@code TimeNanos} value has been derived from a clock that has
+     * been running continuously - e.g. a single continuously powered crystal oscillator, and thus
+     * the {@code (FullBiasNanos + BiasNanos)} offset can be modelled with traditional clock bias
+     * &amp; drift models.
+     *
+     * <p>Each time this value changes, vs. the value in a previously reported {@link GnssClock},
+     * that suggests the hardware clock may have experienced a discontinuity (e.g. a power cycle or
+     * other anomaly), so that any assumptions about modelling a smoothly changing
+     * {@code (FullBiasNanos + BiasNanos)} offset, and a smoothly growing {@code (TimeNanos)}
+     * between this and the previously reported {@code GnssClock}, should be reset.
+     */
+    public int getHardwareClockDiscontinuityCount() {
+        return mHardwareClockDiscontinuityCount;
+    }
+
+    /**
+     * Sets count of last hardware clock discontinuity.
+     * @hide
+     */
+    @TestApi
+    public void setHardwareClockDiscontinuityCount(int value) {
+        mHardwareClockDiscontinuityCount = value;
+    }
+
+    public static final @android.annotation.NonNull Creator<GnssClock> CREATOR = new Creator<GnssClock>() {
+        @Override
+        public GnssClock createFromParcel(Parcel parcel) {
+            GnssClock gpsClock = new GnssClock();
+
+            gpsClock.mFlags = parcel.readInt();
+            gpsClock.mLeapSecond = parcel.readInt();
+            gpsClock.mTimeNanos = parcel.readLong();
+            gpsClock.mTimeUncertaintyNanos = parcel.readDouble();
+            gpsClock.mFullBiasNanos = parcel.readLong();
+            gpsClock.mBiasNanos = parcel.readDouble();
+            gpsClock.mBiasUncertaintyNanos = parcel.readDouble();
+            gpsClock.mDriftNanosPerSecond = parcel.readDouble();
+            gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble();
+            gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt();
+            gpsClock.mElapsedRealtimeNanos = parcel.readLong();
+            gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readDouble();
+            gpsClock.mReferenceConstellationTypeForIsb = parcel.readInt();
+            gpsClock.mReferenceCarrierFrequencyHzForIsb = parcel.readDouble();
+            gpsClock.mReferenceCodeTypeForIsb = parcel.readString();
+
+            return gpsClock;
+        }
+
+        @Override
+        public GnssClock[] newArray(int size) {
+            return new GnssClock[size];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mFlags);
+        parcel.writeInt(mLeapSecond);
+        parcel.writeLong(mTimeNanos);
+        parcel.writeDouble(mTimeUncertaintyNanos);
+        parcel.writeLong(mFullBiasNanos);
+        parcel.writeDouble(mBiasNanos);
+        parcel.writeDouble(mBiasUncertaintyNanos);
+        parcel.writeDouble(mDriftNanosPerSecond);
+        parcel.writeDouble(mDriftUncertaintyNanosPerSecond);
+        parcel.writeInt(mHardwareClockDiscontinuityCount);
+        parcel.writeLong(mElapsedRealtimeNanos);
+        parcel.writeDouble(mElapsedRealtimeUncertaintyNanos);
+        parcel.writeInt(mReferenceConstellationTypeForIsb);
+        parcel.writeDouble(mReferenceCarrierFrequencyHzForIsb);
+        parcel.writeString(mReferenceCodeTypeForIsb);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        final String format = "   %-15s = %s\n";
+        final String formatWithUncertainty = "   %-15s = %-25s   %-26s = %s\n";
+        StringBuilder builder = new StringBuilder("GnssClock:\n");
+
+        if (hasLeapSecond()) {
+            builder.append(String.format(format, "LeapSecond", mLeapSecond));
+        }
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "TimeNanos",
+                mTimeNanos,
+                "TimeUncertaintyNanos",
+                hasTimeUncertaintyNanos() ? mTimeUncertaintyNanos : null));
+
+        if (hasFullBiasNanos()) {
+            builder.append(String.format(format, "FullBiasNanos", mFullBiasNanos));
+        }
+
+        if (hasBiasNanos() || hasBiasUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "BiasNanos",
+                    hasBiasNanos() ? mBiasNanos : null,
+                    "BiasUncertaintyNanos",
+                    hasBiasUncertaintyNanos() ? mBiasUncertaintyNanos : null));
+        }
+
+        if (hasDriftNanosPerSecond() || hasDriftUncertaintyNanosPerSecond()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "DriftNanosPerSecond",
+                    hasDriftNanosPerSecond() ? mDriftNanosPerSecond : null,
+                    "DriftUncertaintyNanosPerSecond",
+                    hasDriftUncertaintyNanosPerSecond() ? mDriftUncertaintyNanosPerSecond : null));
+        }
+
+        builder.append(String.format(
+                format,
+                "HardwareClockDiscontinuityCount",
+                mHardwareClockDiscontinuityCount));
+
+        if (hasElapsedRealtimeNanos() || hasElapsedRealtimeUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "ElapsedRealtimeNanos",
+                    hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null,
+                    "ElapsedRealtimeUncertaintyNanos",
+                    hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos
+                            : null));
+        }
+
+        if (hasReferenceConstellationTypeForIsb()) {
+            builder.append(String.format(format, "ReferenceConstellationTypeForIsb",
+                    mReferenceConstellationTypeForIsb));
+        }
+
+        if (hasReferenceCarrierFrequencyHzForIsb()) {
+            builder.append(String.format(format, "ReferenceCarrierFrequencyHzForIsb",
+                    mReferenceCarrierFrequencyHzForIsb));
+        }
+
+        if (hasReferenceCodeTypeForIsb()) {
+            builder.append(
+                    String.format(format, "ReferenceCodeTypeForIsb", mReferenceCodeTypeForIsb));
+        }
+
+        return builder.toString();
+    }
+
+    private void initialize() {
+        mFlags = HAS_NO_FLAGS;
+        resetLeapSecond();
+        setTimeNanos(Long.MIN_VALUE);
+        resetTimeUncertaintyNanos();
+        resetFullBiasNanos();
+        resetBiasNanos();
+        resetBiasUncertaintyNanos();
+        resetDriftNanosPerSecond();
+        resetDriftUncertaintyNanosPerSecond();
+        setHardwareClockDiscontinuityCount(Integer.MIN_VALUE);
+        resetElapsedRealtimeNanos();
+        resetElapsedRealtimeUncertaintyNanos();
+        resetReferenceConstellationTypeForIsb();
+        resetReferenceCarrierFrequencyHzForIsb();
+        resetReferenceCodeTypeForIsb();
+    }
+
+    private void setFlag(int flag) {
+        mFlags |= flag;
+    }
+
+    private void resetFlag(int flag) {
+        mFlags &= ~flag;
+    }
+
+    private boolean isFlagSet(int flag) {
+        return (mFlags & flag) == flag;
+    }
+}
diff --git a/android/location/GnssMeasurement.java b/android/location/GnssMeasurement.java
new file mode 100644
index 0000000..cd2af1b
--- /dev/null
+++ b/android/location/GnssMeasurement.java
@@ -0,0 +1,1858 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_AUTOMATIC_GAIN_CONTROL;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_CYCLES;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_FREQUENCY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_PHASE;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_CARRIER_PHASE_UNCERTAINTY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_FULL_ISB;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_FULL_ISB_UNCERTAINTY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SATELLITE_ISB;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SATELLITE_ISB_UNCERTAINTY;
+import static android.hardware.gnss.V2_1.IGnssMeasurementCallback.GnssMeasurementFlags.HAS_SNR;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A class representing a GNSS satellite measurement, containing raw and computed information.
+ */
+public final class GnssMeasurement implements Parcelable {
+    private int mFlags;
+    private int mSvid;
+    private int mConstellationType;
+    private double mTimeOffsetNanos;
+    private int mState;
+    private long mReceivedSvTimeNanos;
+    private long mReceivedSvTimeUncertaintyNanos;
+    private double mCn0DbHz;
+    private double mBasebandCn0DbHz;
+    private double mPseudorangeRateMetersPerSecond;
+    private double mPseudorangeRateUncertaintyMetersPerSecond;
+    private int mAccumulatedDeltaRangeState;
+    private double mAccumulatedDeltaRangeMeters;
+    private double mAccumulatedDeltaRangeUncertaintyMeters;
+    private float mCarrierFrequencyHz;
+    private long mCarrierCycles;
+    private double mCarrierPhase;
+    private double mCarrierPhaseUncertainty;
+    private int mMultipathIndicator;
+    private double mSnrInDb;
+    private double mAutomaticGainControlLevelInDb;
+    @NonNull private String mCodeType;
+    private double mFullInterSignalBiasNanos;
+    private double mFullInterSignalBiasUncertaintyNanos;
+    private double mSatelliteInterSignalBiasNanos;
+    private double mSatelliteInterSignalBiasUncertaintyNanos;
+
+    // The following enumerations must be in sync with the values declared in GNSS HAL.
+
+    private static final int HAS_NO_FLAGS = 0;
+    private static final int HAS_CODE_TYPE = (1 << 14);
+    private static final int HAS_BASEBAND_CN0 = (1 << 15);
+
+    /**
+     * The status of the multipath indicator.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({MULTIPATH_INDICATOR_UNKNOWN, MULTIPATH_INDICATOR_DETECTED,
+            MULTIPATH_INDICATOR_NOT_DETECTED})
+    public @interface MultipathIndicator {}
+
+    /**
+     * The indicator is not available or the presence or absence of multipath is unknown.
+     */
+    public static final int MULTIPATH_INDICATOR_UNKNOWN = 0;
+
+    /**
+     * The measurement shows signs of multi-path.
+     */
+    public static final int MULTIPATH_INDICATOR_DETECTED = 1;
+
+    /**
+     * The measurement shows no signs of multi-path.
+     */
+    public static final int MULTIPATH_INDICATOR_NOT_DETECTED = 2;
+
+    /**
+     * GNSS measurement tracking loop state
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "STATE_" }, value = {
+            STATE_CODE_LOCK, STATE_BIT_SYNC, STATE_SUBFRAME_SYNC,
+            STATE_TOW_DECODED, STATE_MSEC_AMBIGUOUS, STATE_SYMBOL_SYNC, STATE_GLO_STRING_SYNC,
+            STATE_GLO_TOD_DECODED, STATE_BDS_D2_BIT_SYNC, STATE_BDS_D2_SUBFRAME_SYNC,
+            STATE_GAL_E1BC_CODE_LOCK, STATE_GAL_E1C_2ND_CODE_LOCK, STATE_GAL_E1B_PAGE_SYNC,
+            STATE_SBAS_SYNC, STATE_TOW_KNOWN, STATE_GLO_TOD_KNOWN, STATE_2ND_CODE_LOCK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface State {}
+
+    /** This GNSS measurement's tracking state is invalid or unknown. */
+    public static final int STATE_UNKNOWN = 0;
+    /** This GNSS measurement's tracking state has code lock. */
+    public static final int STATE_CODE_LOCK = (1<<0);
+    /** This GNSS measurement's tracking state has bit sync. */
+    public static final int STATE_BIT_SYNC = (1<<1);
+    /** This GNSS measurement's tracking state has sub-frame sync. */
+    public static final int STATE_SUBFRAME_SYNC = (1<<2);
+    /** This GNSS measurement's tracking state has time-of-week decoded. */
+    public static final int STATE_TOW_DECODED = (1<<3);
+    /** This GNSS measurement's tracking state contains millisecond ambiguity. */
+    public static final int STATE_MSEC_AMBIGUOUS = (1<<4);
+    /** This GNSS measurement's tracking state has symbol sync. */
+    public static final int STATE_SYMBOL_SYNC = (1<<5);
+    /** This Glonass measurement's tracking state has string sync. */
+    public static final int STATE_GLO_STRING_SYNC = (1<<6);
+    /** This Glonass measurement's tracking state has time-of-day decoded. */
+    public static final int STATE_GLO_TOD_DECODED = (1<<7);
+    /** This Beidou measurement's tracking state has D2 bit sync. */
+    public static final int STATE_BDS_D2_BIT_SYNC = (1<<8);
+    /** This Beidou measurement's tracking state has D2 sub-frame sync. */
+    public static final int STATE_BDS_D2_SUBFRAME_SYNC = (1<<9);
+    /** This Galileo measurement's tracking state has E1B/C code lock. */
+    public static final int STATE_GAL_E1BC_CODE_LOCK = (1<<10);
+    /** This Galileo measurement's tracking state has E1C secondary code lock. */
+    public static final int STATE_GAL_E1C_2ND_CODE_LOCK = (1<<11);
+    /** This Galileo measurement's tracking state has E1B page sync. */
+    public static final int STATE_GAL_E1B_PAGE_SYNC = (1<<12);
+    /** This SBAS measurement's tracking state has whole second level sync. */
+    public static final int STATE_SBAS_SYNC = (1<<13);
+    /**
+     * This GNSS measurement's tracking state has time-of-week known, possibly not decoded
+     * over the air but has been determined from other sources. If TOW decoded is set then TOW Known
+     * will also be set.
+     */
+    public static final int STATE_TOW_KNOWN = (1<<14);
+    /**
+     * This Glonass measurement's tracking state has time-of-day known, possibly not decoded
+     * over the air but has been determined from other sources. If TOD decoded is set then TOD Known
+     * will also be set.
+     */
+    public static final int STATE_GLO_TOD_KNOWN = (1<<15);
+
+    /** This GNSS measurement's tracking state has secondary code lock. */
+    public static final int STATE_2ND_CODE_LOCK  = (1 << 16);
+
+    /**
+     * All the GNSS receiver state flags, for bit masking purposes (not a sensible state for any
+     * individual measurement.)
+     */
+    private static final int STATE_ALL = 0x3fff;  // 2 bits + 4 bits + 4 bits + 4 bits = 14 bits
+
+    /**
+     * GNSS measurement accumulated delta range state
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "ADR_STATE_" }, value = {
+            ADR_STATE_VALID, ADR_STATE_RESET, ADR_STATE_CYCLE_SLIP, ADR_STATE_HALF_CYCLE_RESOLVED,
+            ADR_STATE_HALF_CYCLE_REPORTED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AdrState {}
+
+    /**
+     * The state of the value {@link #getAccumulatedDeltaRangeMeters()} is invalid or unknown.
+     */
+    public static final int ADR_STATE_UNKNOWN = 0;
+
+    /**
+     * The state of the {@link #getAccumulatedDeltaRangeMeters()} is valid.
+     */
+    public static final int ADR_STATE_VALID = (1<<0);
+
+    /**
+     * The state of the {@link #getAccumulatedDeltaRangeMeters()} has detected a reset.
+     */
+    public static final int ADR_STATE_RESET = (1<<1);
+
+    /**
+     * The state of the {@link #getAccumulatedDeltaRangeMeters()} has a cycle slip detected.
+     */
+    public static final int ADR_STATE_CYCLE_SLIP = (1<<2);
+
+    /**
+     * Reports whether the value {@link #getAccumulatedDeltaRangeMeters()} has resolved the half
+     * cycle ambiguity.
+     *
+     * <p> When this bit is set, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
+     * carrier phase measurement plus an accumulated integer number of carrier full cycles.
+     *
+     * <p> When this bit is unset, the {@link #getAccumulatedDeltaRangeMeters()} corresponds to the
+     * carrier phase measurement plus an accumulated integer number of carrier half cycles.
+     */
+    public static final int ADR_STATE_HALF_CYCLE_RESOLVED = (1<<3);
+
+    /**
+     * Reports whether the flag {@link #ADR_STATE_HALF_CYCLE_RESOLVED} has been reported by the
+     * GNSS hardware.
+     *
+     * <p> When this bit is set, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
+     * can be low (centimeter level) whether or not the half cycle ambiguity is resolved.
+     *
+     * <p> When this bit is unset, the value of {@link #getAccumulatedDeltaRangeUncertaintyMeters()}
+     * is larger, to cover the potential error due to half cycle ambiguity being unresolved.
+     */
+    public static final int ADR_STATE_HALF_CYCLE_REPORTED = (1<<4);
+
+    /**
+     * All the 'Accumulated Delta Range' flags.
+     * @hide
+     */
+    @TestApi
+    public static final int ADR_STATE_ALL =
+            ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP |
+            ADR_STATE_HALF_CYCLE_RESOLVED | ADR_STATE_HALF_CYCLE_REPORTED;
+
+    // End enumerations in sync with gps.h
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public GnssMeasurement() {
+        initialize();
+    }
+
+    /**
+     * Sets all contents to the values stored in the provided object.
+     * @hide
+     */
+    @TestApi
+    public void set(GnssMeasurement measurement) {
+        mFlags = measurement.mFlags;
+        mSvid = measurement.mSvid;
+        mConstellationType = measurement.mConstellationType;
+        mTimeOffsetNanos = measurement.mTimeOffsetNanos;
+        mState = measurement.mState;
+        mReceivedSvTimeNanos = measurement.mReceivedSvTimeNanos;
+        mReceivedSvTimeUncertaintyNanos = measurement.mReceivedSvTimeUncertaintyNanos;
+        mCn0DbHz = measurement.mCn0DbHz;
+        mBasebandCn0DbHz = measurement.mBasebandCn0DbHz;
+        mPseudorangeRateMetersPerSecond = measurement.mPseudorangeRateMetersPerSecond;
+        mPseudorangeRateUncertaintyMetersPerSecond =
+                measurement.mPseudorangeRateUncertaintyMetersPerSecond;
+        mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
+        mAccumulatedDeltaRangeMeters = measurement.mAccumulatedDeltaRangeMeters;
+        mAccumulatedDeltaRangeUncertaintyMeters =
+                measurement.mAccumulatedDeltaRangeUncertaintyMeters;
+        mCarrierFrequencyHz = measurement.mCarrierFrequencyHz;
+        mCarrierCycles = measurement.mCarrierCycles;
+        mCarrierPhase = measurement.mCarrierPhase;
+        mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
+        mMultipathIndicator = measurement.mMultipathIndicator;
+        mSnrInDb = measurement.mSnrInDb;
+        mAutomaticGainControlLevelInDb = measurement.mAutomaticGainControlLevelInDb;
+        mCodeType = measurement.mCodeType;
+        mFullInterSignalBiasNanos = measurement.mFullInterSignalBiasNanos;
+        mFullInterSignalBiasUncertaintyNanos =
+                measurement.mFullInterSignalBiasUncertaintyNanos;
+        mSatelliteInterSignalBiasNanos = measurement.mSatelliteInterSignalBiasNanos;
+        mSatelliteInterSignalBiasUncertaintyNanos =
+                measurement.mSatelliteInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Resets all the contents to its original state.
+     * @hide
+     */
+    @TestApi
+    public void reset() {
+        initialize();
+    }
+
+    /**
+     * Gets the satellite ID.
+     *
+     * <p>Interpretation depends on {@link #getConstellationType()}.
+     * See {@link GnssStatus#getSvid(int)}.
+     */
+    public int getSvid() {
+        return mSvid;
+    }
+
+    /**
+     * Sets the Satellite ID.
+     * @hide
+     */
+    @TestApi
+    public void setSvid(int value) {
+        mSvid = value;
+    }
+
+    /**
+     * Gets the constellation type.
+     *
+     * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in
+     * {@link GnssStatus}.
+     */
+    @GnssStatus.ConstellationType
+    public int getConstellationType() {
+        return mConstellationType;
+    }
+
+    /**
+     * Sets the constellation type.
+     * @hide
+     */
+    @TestApi
+    public void setConstellationType(@GnssStatus.ConstellationType int value) {
+        mConstellationType = value;
+    }
+
+    /**
+     * Gets the time offset at which the measurement was taken in nanoseconds.
+     *
+     * <p>The reference receiver's time from which this is offset is specified by
+     * {@link GnssClock#getTimeNanos()}.
+     *
+     * <p>The sign of this value is given by the following equation:
+     * <pre>
+     *      measurement time = TimeNanos + TimeOffsetNanos</pre>
+     *
+     * <p>The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
+     * accuracy.
+     */
+    public double getTimeOffsetNanos() {
+        return mTimeOffsetNanos;
+    }
+
+    /**
+     * Sets the time offset at which the measurement was taken in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setTimeOffsetNanos(double value) {
+        mTimeOffsetNanos = value;
+    }
+
+    /**
+     * Gets per-satellite sync state.
+     *
+     * <p>It represents the current sync state for the associated satellite.
+     *
+     * <p>This value helps interpret {@link #getReceivedSvTimeNanos()}.
+     */
+    @State
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Sets the sync state.
+     * @hide
+     */
+    @TestApi
+    public void setState(@State int value) {
+        mState = value;
+    }
+
+    /**
+     * Gets a string representation of the 'sync state'.
+     *
+     * <p>For internal and logging use only.
+     */
+    private String getStateString() {
+        if (mState == STATE_UNKNOWN) {
+            return "Unknown";
+        }
+
+        StringBuilder builder = new StringBuilder();
+        if ((mState & STATE_CODE_LOCK) != 0) {
+            builder.append("CodeLock|");
+        }
+        if ((mState & STATE_BIT_SYNC) != 0) {
+            builder.append("BitSync|");
+        }
+        if ((mState & STATE_SUBFRAME_SYNC) != 0) {
+            builder.append("SubframeSync|");
+        }
+        if ((mState & STATE_TOW_DECODED) != 0) {
+            builder.append("TowDecoded|");
+        }
+        if ((mState & STATE_TOW_KNOWN) != 0) {
+          builder.append("TowKnown|");
+        }
+        if ((mState & STATE_MSEC_AMBIGUOUS) != 0) {
+            builder.append("MsecAmbiguous|");
+        }
+        if ((mState & STATE_SYMBOL_SYNC) != 0) {
+            builder.append("SymbolSync|");
+        }
+        if ((mState & STATE_GLO_STRING_SYNC) != 0) {
+            builder.append("GloStringSync|");
+        }
+        if ((mState & STATE_GLO_TOD_DECODED) != 0) {
+            builder.append("GloTodDecoded|");
+        }
+        if ((mState & STATE_GLO_TOD_KNOWN) != 0) {
+          builder.append("GloTodKnown|");
+        }
+        if ((mState & STATE_BDS_D2_BIT_SYNC) != 0) {
+            builder.append("BdsD2BitSync|");
+        }
+        if ((mState & STATE_BDS_D2_SUBFRAME_SYNC) != 0) {
+            builder.append("BdsD2SubframeSync|");
+        }
+        if ((mState & STATE_GAL_E1BC_CODE_LOCK) != 0) {
+            builder.append("GalE1bcCodeLock|");
+        }
+        if ((mState & STATE_GAL_E1C_2ND_CODE_LOCK) != 0) {
+            builder.append("E1c2ndCodeLock|");
+        }
+        if ((mState & STATE_GAL_E1B_PAGE_SYNC) != 0) {
+            builder.append("GalE1bPageSync|");
+        }
+        if ((mState & STATE_SBAS_SYNC) != 0) {
+            builder.append("SbasSync|");
+        }
+        if ((mState & STATE_2ND_CODE_LOCK) != 0) {
+            builder.append("2ndCodeLock|");
+        }
+
+        int remainingStates = mState & ~STATE_ALL;
+        if (remainingStates > 0) {
+            builder.append("Other(");
+            builder.append(Integer.toBinaryString(remainingStates));
+            builder.append(")|");
+        }
+        builder.setLength(builder.length() - 1);
+        return builder.toString();
+    }
+
+    /**
+     * Gets the received GNSS satellite time, at the measurement time, in nanoseconds.
+     *
+     * <p>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 {@link #getState} method. The minimum value of this field is zero.
+     * The maximum value of this field is determined by looking across all of the state flags
+     * that are set, for the given constellation and code type, and finding the the maximum value
+     * in this table.
+     *
+     * <p>For example, for GPS L1 C/A, if STATE_TOW_KNOWN is set, this field can be any value from 0
+     * to 1 week (in nanoseconds), and for GAL E1B code, if only STATE_GAL_E1BC_CODE_LOCK is set,
+     * then this field can be any value from 0 to 4 milliseconds (in nanoseconds.)
+     *
+     * <table border="1">
+     *   <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 &nbsp;(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, unless the '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>
+     */
+    public long getReceivedSvTimeNanos() {
+        return mReceivedSvTimeNanos;
+    }
+
+    /**
+     * Sets the received GNSS time in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setReceivedSvTimeNanos(long value) {
+        mReceivedSvTimeNanos = value;
+    }
+
+    /**
+     * Gets the error estimate (1-sigma) for the received GNSS time, in nanoseconds.
+     */
+    public long getReceivedSvTimeUncertaintyNanos() {
+        return mReceivedSvTimeUncertaintyNanos;
+    }
+
+    /**
+     * Sets the received GNSS time uncertainty (1-Sigma) in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setReceivedSvTimeUncertaintyNanos(long value) {
+        mReceivedSvTimeUncertaintyNanos = value;
+    }
+
+    /**
+     * Gets the Carrier-to-noise density in dB-Hz.
+     *
+     * <p>Typical range: 10-50 dB-Hz. The range of possible C/N0 values is 0-63 dB-Hz to handle
+     * some edge cases.
+     *
+     * <p>The value contains the measured C/N0 for the signal at the antenna input.
+     */
+    @FloatRange(from = 0, to = 63)
+    public double getCn0DbHz() {
+        return mCn0DbHz;
+    }
+
+    /**
+     * Sets the carrier-to-noise density in dB-Hz.
+     * @hide
+     */
+    @TestApi
+    public void setCn0DbHz(double value) {
+        mCn0DbHz = value;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getBasebandCn0DbHz()} is available, {@code false} otherwise.
+     */
+    public boolean hasBasebandCn0DbHz() {
+        return isFlagSet(HAS_BASEBAND_CN0);
+    }
+
+    /**
+     * Gets the baseband carrier-to-noise density in dB-Hz.
+     *
+     * <p>Typical range: 10-50 dB-Hz. The range of possible baseband C/N0 values is 0-63 dB-Hz to
+     * handle some edge cases.
+     *
+     * <p>The value contains the measured C/N0 for the signal at the baseband. This is typically
+     * a few dB weaker than the value estimated for C/N0 at the antenna port, which is reported
+     * in {@link #getCn0DbHz()}.
+     */
+    @FloatRange(from = 0, to = 63)
+    public double getBasebandCn0DbHz() {
+        return mBasebandCn0DbHz;
+    }
+
+    /**
+     * Sets the baseband carrier-to-noise density in dB-Hz.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setBasebandCn0DbHz(double value) {
+        setFlag(HAS_BASEBAND_CN0);
+        mBasebandCn0DbHz = value;
+    }
+
+    /**
+     * Resets the baseband carrier-to-noise density in dB-Hz.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetBasebandCn0DbHz() {
+        resetFlag(HAS_BASEBAND_CN0);
+    }
+
+    /**
+     * Gets the Pseudorange rate at the timestamp in m/s.
+     *
+     * <p>The error estimate for this value is
+     * {@link #getPseudorangeRateUncertaintyMetersPerSecond()}.
+     *
+     * <p>The value is uncorrected, i.e. corrections for receiver and satellite clock frequency
+     * errors are not included.
+     *
+     * <p>A positive 'uncorrected' value indicates that the SV is moving away from the receiver. The
+     * sign of the 'uncorrected' 'pseudorange rate' and its relation to the sign of 'doppler shift'
+     * is given by the equation:
+     *
+     * <pre>
+     *      pseudorange rate = -k * doppler shift   (where k is a constant)</pre>
+     */
+    public double getPseudorangeRateMetersPerSecond() {
+        return mPseudorangeRateMetersPerSecond;
+    }
+
+    /**
+     * Sets the pseudorange rate at the timestamp in m/s.
+     * @hide
+     */
+    @TestApi
+    public void setPseudorangeRateMetersPerSecond(double value) {
+        mPseudorangeRateMetersPerSecond = value;
+    }
+
+    /**
+     * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
+     *
+     * <p>The uncertainty is represented as an absolute (single sided) value.
+     */
+    public double getPseudorangeRateUncertaintyMetersPerSecond() {
+        return mPseudorangeRateUncertaintyMetersPerSecond;
+    }
+
+    /**
+     * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
+     * @hide
+     */
+    @TestApi
+    public void setPseudorangeRateUncertaintyMetersPerSecond(double value) {
+        mPseudorangeRateUncertaintyMetersPerSecond = value;
+    }
+
+    /**
+     * Gets 'Accumulated Delta Range' state.
+     *
+     * <p>It indicates whether {@link #getAccumulatedDeltaRangeMeters()} is reset or there is a
+     * cycle slip (indicating 'loss of lock').
+     */
+    @AdrState
+    public int getAccumulatedDeltaRangeState() {
+        return mAccumulatedDeltaRangeState;
+    }
+
+    /**
+     * Sets the 'Accumulated Delta Range' state.
+     * @hide
+     */
+    @TestApi
+    public void setAccumulatedDeltaRangeState(@AdrState int value) {
+        mAccumulatedDeltaRangeState = value;
+    }
+
+    /**
+     * Gets a string representation of the 'Accumulated Delta Range state'.
+     *
+     * <p>For internal and logging use only.
+     */
+    private String getAccumulatedDeltaRangeStateString() {
+        if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
+            return "Unknown";
+        }
+        StringBuilder builder = new StringBuilder();
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
+            builder.append("Valid|");
+        }
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
+            builder.append("Reset|");
+        }
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
+            builder.append("CycleSlip|");
+        }
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_RESOLVED) ==
+                ADR_STATE_HALF_CYCLE_RESOLVED) {
+            builder.append("HalfCycleResolved|");
+        }
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_HALF_CYCLE_REPORTED)
+                == ADR_STATE_HALF_CYCLE_REPORTED) {
+            builder.append("HalfCycleReported|");
+        }
+        int remainingStates = mAccumulatedDeltaRangeState & ~ADR_STATE_ALL;
+        if (remainingStates > 0) {
+            builder.append("Other(");
+            builder.append(Integer.toBinaryString(remainingStates));
+            builder.append(")|");
+        }
+        builder.deleteCharAt(builder.length() - 1);
+        return builder.toString();
+    }
+
+    /**
+     * Gets the accumulated delta range since the last channel reset, in meters.
+     *
+     * <p>The error estimate for this value is {@link #getAccumulatedDeltaRangeUncertaintyMeters()}.
+     *
+     * <p>The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     *
+     * <p>A positive value indicates that the SV is moving away from the receiver.
+     * The sign of {@link #getAccumulatedDeltaRangeMeters()} and its relation to the sign of
+     * {@link #getCarrierPhase()} is given by the equation:
+     *
+     * <pre>
+     *          accumulated delta range = -k * carrier phase    (where k is a constant)</pre>
+     *
+     * <p>Similar to the concept of an RTCM "Phaserange", when the accumulated delta range is
+     * initially chosen, and whenever it is reset, it will retain the integer nature
+     * of the relative carrier phase offset between satellites observed by this receiver, such that
+     * the double difference of this value between receivers and satellites may be used, together
+     * with integer ambiguity resolution, to determine highly precise relative location between
+     * receivers.
+     *
+     * <p>This includes ensuring that all half-cycle ambiguities are resolved before this value is
+     * reported as {@link #ADR_STATE_VALID}.
+     *
+     * <p>The alignment of the phase measurement will not be adjusted by the receiver so the
+     * in-phase and quadrature phase components will have a 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.
+     */
+    public double getAccumulatedDeltaRangeMeters() {
+        return mAccumulatedDeltaRangeMeters;
+    }
+
+    /**
+     * Sets the accumulated delta range in meters.
+     * @hide
+     */
+    @TestApi
+    public void setAccumulatedDeltaRangeMeters(double value) {
+        mAccumulatedDeltaRangeMeters = value;
+    }
+
+    /**
+     * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
+     *
+     * <p>The uncertainty is represented as an absolute (single sided) value.
+     *
+     * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     */
+    public double getAccumulatedDeltaRangeUncertaintyMeters() {
+        return mAccumulatedDeltaRangeUncertaintyMeters;
+    }
+
+    /**
+     * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
+     *
+     * <p>The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setAccumulatedDeltaRangeUncertaintyMeters(double value) {
+        mAccumulatedDeltaRangeUncertaintyMeters = value;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getCarrierFrequencyHz()} is available, {@code false}
+     * otherwise.
+     */
+    public boolean hasCarrierFrequencyHz() {
+        return isFlagSet(HAS_CARRIER_FREQUENCY);
+    }
+
+    /**
+     * Gets the carrier frequency of the tracked signal.
+     *
+     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
+     * L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
+     * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
+     *
+     * <p> For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two raw
+     * measurement objects will be reported for this same satellite, in one of the measurement
+     * objects, all the values related to L1 will be filled, and in the other all of the values
+     * related to L5 will be filled.
+     *
+     * <p>The value is only available if {@link #hasCarrierFrequencyHz()} is {@code true}.
+     *
+     * @return the carrier frequency of the signal tracked in Hz.
+     */
+    public float getCarrierFrequencyHz() {
+        return mCarrierFrequencyHz;
+    }
+
+    /**
+     * Sets the Carrier frequency in Hz.
+     * @hide
+     */
+    @TestApi
+    public void setCarrierFrequencyHz(float carrierFrequencyHz) {
+        setFlag(HAS_CARRIER_FREQUENCY);
+        mCarrierFrequencyHz = carrierFrequencyHz;
+    }
+
+    /**
+     * Resets the Carrier frequency in Hz.
+     * @hide
+     */
+    @TestApi
+    public void resetCarrierFrequencyHz() {
+        resetFlag(HAS_CARRIER_FREQUENCY);
+        mCarrierFrequencyHz = Float.NaN;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getCarrierCycles()} is available, {@code false} otherwise.
+     * 
+     * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
+     */
+    @Deprecated
+    public boolean hasCarrierCycles() {
+        return isFlagSet(HAS_CARRIER_CYCLES);
+    }
+
+    /**
+     * The number of full carrier cycles between the satellite and the receiver.
+     *
+     * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
+     *
+     * <p>The value is only available if {@link #hasCarrierCycles()} is {@code true}.
+     *
+     * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
+     */
+    @Deprecated
+    public long getCarrierCycles() {
+        return mCarrierCycles;
+    }
+
+    /**
+     * Sets the number of full carrier cycles between the satellite and the receiver.
+     *
+     * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+     * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+     * 
+     * @hide
+     */
+    @TestApi
+    @Deprecated
+    public void setCarrierCycles(long value) {
+        setFlag(HAS_CARRIER_CYCLES);
+        mCarrierCycles = value;
+    }
+
+    /**
+     * Resets the number of full carrier cycles between the satellite and the receiver.
+     * 
+     * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+     * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+     * @hide
+     */
+    @TestApi
+    @Deprecated
+    public void resetCarrierCycles() {
+        resetFlag(HAS_CARRIER_CYCLES);
+        mCarrierCycles = Long.MIN_VALUE;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getCarrierPhase()} is available, {@code false} otherwise.
+     * 
+     * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
+     */
+    @Deprecated
+    public boolean hasCarrierPhase() {
+        return isFlagSet(HAS_CARRIER_PHASE);
+    }
+
+    /**
+     * Gets the RF phase detected by the receiver.
+     *
+     * <p>Range: [0.0, 1.0].
+     *
+     * <p>This is the fractional part of the complete carrier phase measurement.
+     *
+     * <p>The reference frequency is given by the value of {@link #getCarrierFrequencyHz()}.
+     *
+     * <p>The error estimate for this value is {@link #getCarrierPhaseUncertainty()}.
+     *
+     * <p>The value is only available if {@link #hasCarrierPhase()} is {@code true}.
+     *
+     * @deprecated use {@link #getAccumulatedDeltaRangeMeters()} instead.
+     */
+    @Deprecated
+    public double getCarrierPhase() {
+        return mCarrierPhase;
+    }
+
+    /**
+     * Sets the RF phase detected by the receiver.
+     * 
+     * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+     * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+     * 
+     * @hide
+     */
+    @TestApi
+    @Deprecated
+    public void setCarrierPhase(double value) {
+        setFlag(HAS_CARRIER_PHASE);
+        mCarrierPhase = value;
+    }
+
+    /**
+     * Resets the RF phase detected by the receiver.
+     * 
+     * @deprecated use {@link #setAccumulatedDeltaRangeMeters(double)}
+     * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+     * 
+     * @hide
+     */
+    @TestApi
+    @Deprecated
+    public void resetCarrierPhase() {
+        resetFlag(HAS_CARRIER_PHASE);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getCarrierPhaseUncertainty()} is available, {@code false}
+     * otherwise.
+     * 
+     * @deprecated use {@link #getAccumulatedDeltaRangeState()} instead.
+     */
+    @Deprecated
+    public boolean hasCarrierPhaseUncertainty() {
+        return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the carrier-phase's uncertainty (1-Sigma).
+     *
+     * <p>The uncertainty is represented as an absolute (single sided) value.
+     *
+     * <p>The value is only available if {@link #hasCarrierPhaseUncertainty()} is {@code true}.
+     *
+     * @deprecated use {@link #getAccumulatedDeltaRangeUncertaintyMeters()} instead.
+     */
+    @Deprecated
+    public double getCarrierPhaseUncertainty() {
+        return mCarrierPhaseUncertainty;
+    }
+
+    /**
+     * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
+     * 
+     * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
+     * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+     * 
+     * @hide
+     */
+    @TestApi
+    @Deprecated
+    public void setCarrierPhaseUncertainty(double value) {
+        setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
+        mCarrierPhaseUncertainty = value;
+    }
+
+    /**
+     * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
+     * 
+     * @deprecated use {@link #setAccumulatedDeltaRangeUncertaintyMeters(double)}
+     * and {@link #setAccumulatedDeltaRangeState(int)} instead.
+     * 
+     * @hide
+     */
+    @TestApi
+    @Deprecated
+    public void resetCarrierPhaseUncertainty() {
+        resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
+    }
+
+    /**
+     * Gets a value indicating the 'multipath' state of the event.
+     */
+    @MultipathIndicator
+    public int getMultipathIndicator() {
+        return mMultipathIndicator;
+    }
+
+    /**
+     * Sets the 'multi-path' indicator.
+     * @hide
+     */
+    @TestApi
+    public void setMultipathIndicator(@MultipathIndicator int value) {
+        mMultipathIndicator = value;
+    }
+
+    /**
+     * Gets a string representation of the 'multi-path indicator'.
+     *
+     * <p>For internal and logging use only.
+     */
+    private String getMultipathIndicatorString() {
+        switch (mMultipathIndicator) {
+            case MULTIPATH_INDICATOR_UNKNOWN:
+                return "Unknown";
+            case MULTIPATH_INDICATOR_DETECTED:
+                return "Detected";
+            case MULTIPATH_INDICATOR_NOT_DETECTED:
+                return "NotDetected";
+            default:
+                return "<Invalid: " + mMultipathIndicator + ">";
+        }
+    }
+
+    /**
+     * Returns {@code true} if {@link #getSnrInDb()} is available, {@code false} otherwise.
+     */
+    public boolean hasSnrInDb() {
+        return isFlagSet(HAS_SNR);
+    }
+
+    /**
+     * Gets the (post-correlation & integration) Signal-to-Noise ratio (SNR) in dB.
+     *
+     * <p>The value is only available if {@link #hasSnrInDb()} is {@code true}.
+     */
+    public double getSnrInDb() {
+        return mSnrInDb;
+    }
+
+    /**
+     * Sets the Signal-to-noise ratio (SNR) in dB.
+     * @hide
+     */
+    @TestApi
+    public void setSnrInDb(double snrInDb) {
+        setFlag(HAS_SNR);
+        mSnrInDb = snrInDb;
+    }
+
+    /**
+     * Resets the Signal-to-noise ratio (SNR) in dB.
+     * @hide
+     */
+    @TestApi
+    public void resetSnrInDb() {
+        resetFlag(HAS_SNR);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getAutomaticGainControlLevelDb()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasAutomaticGainControlLevelDb() {
+        return isFlagSet(HAS_AUTOMATIC_GAIN_CONTROL);
+    }
+
+    /**
+     * Gets the Automatic Gain Control level in dB.
+     *
+     * <p> AGC acts as a variable gain amplifier adjusting the power of the incoming signal. The AGC
+     * level may be used to indicate potential interference. When AGC is at a nominal level, this
+     * value must be set as 0. Higher gain (and/or lower input power) shall be output as a positive
+     * number. Hence in cases of strong jamming, in the band of this signal, this value will go more
+     * negative.
+     *
+     * <p> Note: Different hardware designs (e.g. antenna, pre-amplification, or other RF HW
+     * components) may also affect the typical output of of this value on any given hardware design
+     * in an open sky test - the important aspect of this output is that changes in this value are
+     * indicative of changes on input signal power in the frequency band for this measurement.
+     *
+     * <p> The value is only available if {@link #hasAutomaticGainControlLevelDb()} is {@code true}
+     */
+    public double getAutomaticGainControlLevelDb() {
+        return mAutomaticGainControlLevelInDb;
+    }
+
+    /**
+     * Sets the Automatic Gain Control level in dB.
+     * @hide
+     */
+    @TestApi
+    public void setAutomaticGainControlLevelInDb(double agcLevelDb) {
+        setFlag(HAS_AUTOMATIC_GAIN_CONTROL);
+        mAutomaticGainControlLevelInDb = agcLevelDb;
+    }
+
+    /**
+     * Resets the Automatic Gain Control level.
+     * @hide
+     */
+    @TestApi
+    public void resetAutomaticGainControlLevel() {
+        resetFlag(HAS_AUTOMATIC_GAIN_CONTROL);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getCodeType()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasCodeType() {
+        return isFlagSet(HAS_CODE_TYPE);
+    }
+
+    /**
+     * Gets the GNSS measurement's code type.
+     *
+     * <p>Similar to the Attribute field described in RINEX 3.03, e.g., in Tables 4-10, and Table
+     * A2 at the RINEX 3.03 Update 1 Document.
+     *
+     * <p>Returns "A" for GALILEO E1A, GALILEO E6A, IRNSS L5A, IRNSS SA.
+     *
+     * <p>Returns "B" for GALILEO E1B, GALILEO E6B, IRNSS L5B, IRNSS SB.
+     *
+     * <p>Returns "C" for 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.
+     *
+     * <p>Returns "D" for BDS B1C D.
+     *
+     * <p>Returns "I" for 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.
+     *
+     * <p>Returns "L" for GPS L1C (P), GPS L2C (L), QZSS L1C (P), QZSS L2C (L), LEX(6) L.
+     *
+     * <p>Returns "M" for GPS L1M, GPS L2M.
+     *
+     * <p>Returns "N" for GPS L1 codeless, GPS L2 codeless.
+     *
+     * <p>Returns "P" for GPS L1P, GPS L2P, GLONASS G1P, GLONASS G2P, BDS B1C P.
+     *
+     * <p>Returns "Q" for 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.
+     *
+     * <p>Returns "S" for GPS L1C (D), GPS L2C (M), QZSS L1C (D), QZSS L2C (M), LEX(6) S.
+     *
+     * <p>Returns "W" for GPS L1 Z-tracking, GPS L2 Z-tracking.
+     *
+     * <p>Returns "X" for GPS L1C (D+P), GPS L2C (M+L), GPS L5 (I+Q), GLONASS G3 (I+Q), GALILEO
+     * E1 (B+C), GALILEO E5a (I+Q), GALILEO E5b (I+Q), GALILEO E5a+b(I+Q), GALILEO E6 (B+C), SBAS
+     * L5 (I+Q), QZSS L1C (D+P), QZSS L2C (M+L), QZSS L5 (I+Q), LEX(6) (S+L), BDS B1 (I+Q), BDS
+     * B1C (D+P), BDS B2 (I+Q), BDS B3 (I+Q), IRNSS L5 (B+C).
+     *
+     * <p>Returns "Y" for GPS L1Y, GPS L2Y.
+     *
+     * <p>Returns "Z" for GALILEO E1 (A+B+C), GALILEO E6 (A+B+C), QZSS L1-SAIF.
+     *
+     * <p>Returns "UNKNOWN" if the GNSS Measurement's code type is unknown.
+     *
+     * <p>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 cases where the code type
+     * does not align with the above listed values. For example, if a code type "G" is added, this
+     * string shall be set to "G".
+     */
+    @NonNull
+    public String getCodeType() {
+        return mCodeType;
+    }
+
+    /**
+     * Sets the GNSS measurement's code type.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setCodeType(@NonNull String codeType) {
+        setFlag(HAS_CODE_TYPE);
+        mCodeType = codeType;
+    }
+
+    /**
+     * Resets the GNSS measurement's code type.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetCodeType() {
+        resetFlag(HAS_CODE_TYPE);
+        mCodeType = "UNKNOWN";
+    }
+
+    /**
+     * Returns {@code true} if {@link #getFullInterSignalBiasNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasFullInterSignalBiasNanos() {
+        return isFlagSet(HAS_FULL_ISB);
+    }
+
+    /**
+     * Gets the GNSS measurement's inter-signal bias in nanoseconds with sub-nanosecond accuracy.
+     *
+     * <p>This value is the sum of the estimated receiver-side and the space-segment-side
+     * inter-system bias, inter-frequency bias and inter-code bias, including:
+     *
+     * <ul>
+     * <li>Receiver inter-constellation bias (with respect to the constellation in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Receiver inter-frequency bias (with respect to the carrier frequency in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Receiver inter-code bias (with respect to the code type in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps),
+     * BDS-GLO Time Offset (BGTO))(with respect to the constellation in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Group delay (e.g., Total Group Delay (TGD))</li>
+     * <li>Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code
+     * type in {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * </ul>
+     *
+     * <p>If a component of the above is already compensated in the provided
+     * {@link GnssMeasurement#getReceivedSvTimeNanos()}, then it must not be included in the
+     * reported full ISB.
+     *
+     * <p>The value does not include the inter-frequency Ionospheric bias.
+     *
+     * <p>The value is only available if {@link #hasFullInterSignalBiasNanos()} is {@code true}.
+     */
+    public double getFullInterSignalBiasNanos() {
+        return mFullInterSignalBiasNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setFullInterSignalBiasNanos(double fullInterSignalBiasNanos) {
+        setFlag(HAS_FULL_ISB);
+        mFullInterSignalBiasNanos = fullInterSignalBiasNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetFullInterSignalBiasNanos() {
+        resetFlag(HAS_FULL_ISB);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getFullInterSignalBiasUncertaintyNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasFullInterSignalBiasUncertaintyNanos() {
+        return isFlagSet(HAS_FULL_ISB_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the GNSS measurement's inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds with sub-nanosecond accuracy.
+     *
+     * <p>The value is only available if {@link #hasFullInterSignalBiasUncertaintyNanos()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0)
+    public double getFullInterSignalBiasUncertaintyNanos() {
+        return mFullInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's inter-signal bias uncertainty (1 sigma) in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setFullInterSignalBiasUncertaintyNanos(@FloatRange(from = 0.0)
+            double fullInterSignalBiasUncertaintyNanos) {
+        setFlag(HAS_FULL_ISB_UNCERTAINTY);
+        mFullInterSignalBiasUncertaintyNanos = fullInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetFullInterSignalBiasUncertaintyNanos() {
+        resetFlag(HAS_FULL_ISB_UNCERTAINTY);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getSatelliteInterSignalBiasNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasSatelliteInterSignalBiasNanos() {
+        return isFlagSet(HAS_SATELLITE_ISB);
+    }
+
+    /**
+     * Gets the GNSS measurement's satellite inter-signal bias in nanoseconds with sub-nanosecond
+     * accuracy.
+     *
+     * <p>This value is the space-segment-side inter-system bias, inter-frequency bias and
+     * inter-code bias, including:
+     *
+     * <ul>
+     * <li>Master clock bias (e.g., GPS-GAL Time Offset (GGTO), GPS-UTC Time Offset (TauGps),
+     * BDS-GLO Time Offset (BGTO))(with respect to the constellation in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Group delay (e.g., Total Group Delay (TGD))</li>
+     * <li>Satellite inter-frequency bias (GLO only) (with respect to the carrier frequency in
+     * {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * <li>Satellite inter-code bias (e.g., Differential Code Bias (DCB)) (with respect to the code
+     * type in {@link GnssClock#getReferenceConstellationTypeForIsb())</li>
+     * </ul>
+     *
+     * <p>The value is only available if {@link #hasSatelliteInterSignalBiasNanos()} is {@code
+     * true}.
+     */
+    public double getSatelliteInterSignalBiasNanos() {
+        return mSatelliteInterSignalBiasNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's satellite inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setSatelliteInterSignalBiasNanos(double satelliteInterSignalBiasNanos) {
+        setFlag(HAS_SATELLITE_ISB);
+        mSatelliteInterSignalBiasNanos = satelliteInterSignalBiasNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's satellite inter-signal bias in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetSatelliteInterSignalBiasNanos() {
+        resetFlag(HAS_SATELLITE_ISB);
+    }
+
+    /**
+     * Returns {@code true} if {@link #getSatelliteInterSignalBiasUncertaintyNanos()} is available,
+     * {@code false} otherwise.
+     */
+    public boolean hasSatelliteInterSignalBiasUncertaintyNanos() {
+        return isFlagSet(HAS_SATELLITE_ISB_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the GNSS measurement's satellite inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds with sub-nanosecond accuracy.
+     *
+     * <p>The value is only available if {@link #hasSatelliteInterSignalBiasUncertaintyNanos()} is
+     * {@code true}.
+     */
+    @FloatRange(from = 0.0)
+    public double getSatelliteInterSignalBiasUncertaintyNanos() {
+        return mSatelliteInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Sets the GNSS measurement's satellite inter-signal bias uncertainty (1 sigma) in nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void setSatelliteInterSignalBiasUncertaintyNanos(@FloatRange(from = 0.0)
+            double satelliteInterSignalBiasUncertaintyNanos) {
+        setFlag(HAS_SATELLITE_ISB_UNCERTAINTY);
+        mSatelliteInterSignalBiasUncertaintyNanos = satelliteInterSignalBiasUncertaintyNanos;
+    }
+
+    /**
+     * Resets the GNSS measurement's satellite inter-signal bias uncertainty (1 sigma) in
+     * nanoseconds.
+     *
+     * @hide
+     */
+    @TestApi
+    public void resetSatelliteInterSignalBiasUncertaintyNanos() {
+        resetFlag(HAS_SATELLITE_ISB_UNCERTAINTY);
+    }
+
+
+    public static final @NonNull Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
+        @Override
+        public GnssMeasurement createFromParcel(Parcel parcel) {
+            GnssMeasurement gnssMeasurement = new GnssMeasurement();
+
+            gnssMeasurement.mFlags = parcel.readInt();
+            gnssMeasurement.mSvid = parcel.readInt();
+            gnssMeasurement.mConstellationType = parcel.readInt();
+            gnssMeasurement.mTimeOffsetNanos = parcel.readDouble();
+            gnssMeasurement.mState = parcel.readInt();
+            gnssMeasurement.mReceivedSvTimeNanos = parcel.readLong();
+            gnssMeasurement.mReceivedSvTimeUncertaintyNanos = parcel.readLong();
+            gnssMeasurement.mCn0DbHz = parcel.readDouble();
+            gnssMeasurement.mPseudorangeRateMetersPerSecond = parcel.readDouble();
+            gnssMeasurement.mPseudorangeRateUncertaintyMetersPerSecond = parcel.readDouble();
+            gnssMeasurement.mAccumulatedDeltaRangeState = parcel.readInt();
+            gnssMeasurement.mAccumulatedDeltaRangeMeters = parcel.readDouble();
+            gnssMeasurement.mAccumulatedDeltaRangeUncertaintyMeters = parcel.readDouble();
+            gnssMeasurement.mCarrierFrequencyHz = parcel.readFloat();
+            gnssMeasurement.mCarrierCycles = parcel.readLong();
+            gnssMeasurement.mCarrierPhase = parcel.readDouble();
+            gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
+            gnssMeasurement.mMultipathIndicator = parcel.readInt();
+            gnssMeasurement.mSnrInDb = parcel.readDouble();
+            gnssMeasurement.mAutomaticGainControlLevelInDb = parcel.readDouble();
+            gnssMeasurement.mCodeType = parcel.readString();
+            gnssMeasurement.mBasebandCn0DbHz = parcel.readDouble();
+            gnssMeasurement.mFullInterSignalBiasNanos = parcel.readDouble();
+            gnssMeasurement.mFullInterSignalBiasUncertaintyNanos = parcel.readDouble();
+            gnssMeasurement.mSatelliteInterSignalBiasNanos = parcel.readDouble();
+            gnssMeasurement.mSatelliteInterSignalBiasUncertaintyNanos = parcel.readDouble();
+
+            return gnssMeasurement;
+        }
+
+        @Override
+        public GnssMeasurement[] newArray(int i) {
+            return new GnssMeasurement[i];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mFlags);
+        parcel.writeInt(mSvid);
+        parcel.writeInt(mConstellationType);
+        parcel.writeDouble(mTimeOffsetNanos);
+        parcel.writeInt(mState);
+        parcel.writeLong(mReceivedSvTimeNanos);
+        parcel.writeLong(mReceivedSvTimeUncertaintyNanos);
+        parcel.writeDouble(mCn0DbHz);
+        parcel.writeDouble(mPseudorangeRateMetersPerSecond);
+        parcel.writeDouble(mPseudorangeRateUncertaintyMetersPerSecond);
+        parcel.writeInt(mAccumulatedDeltaRangeState);
+        parcel.writeDouble(mAccumulatedDeltaRangeMeters);
+        parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyMeters);
+        parcel.writeFloat(mCarrierFrequencyHz);
+        parcel.writeLong(mCarrierCycles);
+        parcel.writeDouble(mCarrierPhase);
+        parcel.writeDouble(mCarrierPhaseUncertainty);
+        parcel.writeInt(mMultipathIndicator);
+        parcel.writeDouble(mSnrInDb);
+        parcel.writeDouble(mAutomaticGainControlLevelInDb);
+        parcel.writeString(mCodeType);
+        parcel.writeDouble(mBasebandCn0DbHz);
+        parcel.writeDouble(mFullInterSignalBiasNanos);
+        parcel.writeDouble(mFullInterSignalBiasUncertaintyNanos);
+        parcel.writeDouble(mSatelliteInterSignalBiasNanos);
+        parcel.writeDouble(mSatelliteInterSignalBiasUncertaintyNanos);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        final String format = "   %-29s = %s\n";
+        final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
+        StringBuilder builder = new StringBuilder("GnssMeasurement:\n");
+
+        builder.append(String.format(format, "Svid", mSvid));
+        builder.append(String.format(format, "ConstellationType", mConstellationType));
+        builder.append(String.format(format, "TimeOffsetNanos", mTimeOffsetNanos));
+
+        builder.append(String.format(format, "State", getStateString()));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "ReceivedSvTimeNanos",
+                mReceivedSvTimeNanos,
+                "ReceivedSvTimeUncertaintyNanos",
+                mReceivedSvTimeUncertaintyNanos));
+
+        builder.append(String.format(format, "Cn0DbHz", mCn0DbHz));
+
+        if (hasBasebandCn0DbHz()) {
+            builder.append(String.format(format, "BasebandCn0DbHz", mBasebandCn0DbHz));
+        }
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "PseudorangeRateMetersPerSecond",
+                mPseudorangeRateMetersPerSecond,
+                "PseudorangeRateUncertaintyMetersPerSecond",
+                mPseudorangeRateUncertaintyMetersPerSecond));
+
+        builder.append(String.format(
+                format,
+                "AccumulatedDeltaRangeState",
+                getAccumulatedDeltaRangeStateString()));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "AccumulatedDeltaRangeMeters",
+                mAccumulatedDeltaRangeMeters,
+                "AccumulatedDeltaRangeUncertaintyMeters",
+                mAccumulatedDeltaRangeUncertaintyMeters));
+
+        if (hasCarrierFrequencyHz()) {
+            builder.append(String.format(format, "CarrierFrequencyHz", mCarrierFrequencyHz));
+        }
+
+        if (hasCarrierCycles()) {
+            builder.append(String.format(format, "CarrierCycles", mCarrierCycles));
+        }
+
+        if (hasCarrierPhase() || hasCarrierPhaseUncertainty()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "CarrierPhase",
+                    hasCarrierPhase() ? mCarrierPhase : null,
+                    "CarrierPhaseUncertainty",
+                    hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
+        }
+
+        builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
+
+        if (hasSnrInDb()) {
+            builder.append(String.format(format, "SnrInDb", mSnrInDb));
+        }
+
+        if (hasAutomaticGainControlLevelDb()) {
+            builder.append(String.format(format, "AgcLevelDb", mAutomaticGainControlLevelInDb));
+        }
+
+        if (hasCodeType()) {
+            builder.append(String.format(format, "CodeType", mCodeType));
+        }
+
+        if (hasFullInterSignalBiasNanos() || hasFullInterSignalBiasUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "InterSignalBiasNs",
+                    hasFullInterSignalBiasNanos() ? mFullInterSignalBiasNanos : null,
+                    "InterSignalBiasUncertaintyNs",
+                    hasFullInterSignalBiasUncertaintyNanos()
+                            ? mFullInterSignalBiasUncertaintyNanos : null));
+        }
+
+        if (hasSatelliteInterSignalBiasNanos() || hasSatelliteInterSignalBiasUncertaintyNanos()) {
+            builder.append(String.format(
+                    formatWithUncertainty,
+                    "SatelliteInterSignalBiasNs",
+                    hasSatelliteInterSignalBiasNanos() ? mSatelliteInterSignalBiasNanos : null,
+                    "SatelliteInterSignalBiasUncertaintyNs",
+                    hasSatelliteInterSignalBiasUncertaintyNanos()
+                            ? mSatelliteInterSignalBiasUncertaintyNanos
+                            : null));
+        }
+
+        return builder.toString();
+    }
+
+    private void initialize() {
+        mFlags = HAS_NO_FLAGS;
+        setSvid(0);
+        setTimeOffsetNanos(Long.MIN_VALUE);
+        setState(STATE_UNKNOWN);
+        setReceivedSvTimeNanos(Long.MIN_VALUE);
+        setReceivedSvTimeUncertaintyNanos(Long.MAX_VALUE);
+        setCn0DbHz(Double.MIN_VALUE);
+        setPseudorangeRateMetersPerSecond(Double.MIN_VALUE);
+        setPseudorangeRateUncertaintyMetersPerSecond(Double.MIN_VALUE);
+        setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
+        setAccumulatedDeltaRangeMeters(Double.MIN_VALUE);
+        setAccumulatedDeltaRangeUncertaintyMeters(Double.MIN_VALUE);
+        resetCarrierFrequencyHz();
+        resetCarrierCycles();
+        resetCarrierPhase();
+        resetCarrierPhaseUncertainty();
+        setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
+        resetSnrInDb();
+        resetAutomaticGainControlLevel();
+        resetCodeType();
+        resetBasebandCn0DbHz();
+        resetFullInterSignalBiasNanos();
+        resetFullInterSignalBiasUncertaintyNanos();
+        resetSatelliteInterSignalBiasNanos();
+        resetSatelliteInterSignalBiasUncertaintyNanos();
+    }
+
+    private void setFlag(int flag) {
+        mFlags |= flag;
+    }
+
+    private void resetFlag(int flag) {
+        mFlags &= ~flag;
+    }
+
+    private boolean isFlagSet(int flag) {
+        return (mFlags & flag) == flag;
+    }
+}
diff --git a/android/location/GnssMeasurementCorrections.java b/android/location/GnssMeasurementCorrections.java
new file mode 100644
index 0000000..ffbe11a
--- /dev/null
+++ b/android/location/GnssMeasurementCorrections.java
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2018 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.location;
+
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A class representing a GNSS measurement corrections for all used GNSS satellites at the location
+ * and time specified
+ *
+ * @hide
+ */
+@SystemApi
+public final class GnssMeasurementCorrections implements Parcelable {
+
+    /** Represents latitude in degrees at which the corrections are computed. */
+    @FloatRange(from = -90.0f, to = 90.0f)
+    private final double mLatitudeDegrees;
+    /** Represents longitude in degrees at which the corrections are computed. */
+    @FloatRange(from = -180.0f, to = 180.0f)
+    private final double mLongitudeDegrees;
+    /**
+     * Represents altitude in meters above the WGS 84 reference ellipsoid at which the corrections
+     * are computed.
+     */
+    @FloatRange(from = -1000.0, to = 10000.0f)
+    private final double mAltitudeMeters;
+    /**
+     * Represents the horizontal uncertainty (68% confidence) in meters on the device position at
+     * which the corrections are provided.
+     *
+     * <p> This value is useful for example to judge how accurate the provided corrections are.
+     */
+    @FloatRange(from = 0.0f)
+    private final double mHorizontalPositionUncertaintyMeters;
+    /**
+     * Represents the vertical uncertainty (68% confidence) in meters on the device position at
+     * which the corrections are provided.
+     *
+     * <p> This value is useful for example to judge how accurate the provided corrections are.
+     */
+    @FloatRange(from = 0.0f)
+    private final double mVerticalPositionUncertaintyMeters;
+
+    /** Time Of Applicability, GPS time of week in nanoseconds. */
+    @IntRange(from = 0)
+    private final long mToaGpsNanosecondsOfWeek;
+
+    /**
+     * A set of {@link GnssSingleSatCorrection} each containing measurement corrections for a
+     * satellite in view.
+     */
+    @NonNull
+    private final List<GnssSingleSatCorrection> mSingleSatCorrectionList;
+
+    /**
+     * Indicates whether the environment bearing is available.
+     */
+    private final boolean mHasEnvironmentBearing;
+
+    /**
+     * Environment bearing in degrees clockwise from true north, in the direction of user motion.
+     * Environment bearing is provided when it is known with high probability that velocity is
+     * aligned with an environment feature (such as edge of a building, or road).
+     */
+    @FloatRange(from = 0.0f, to = 360.0f)
+    private final float mEnvironmentBearingDegrees;
+
+    /**
+     * Environment bearing uncertainty in degrees.
+     */
+    @FloatRange(from = 0.0f, to = 180.0f)
+    private final float mEnvironmentBearingUncertaintyDegrees;
+
+    private GnssMeasurementCorrections(Builder builder) {
+        mLatitudeDegrees = builder.mLatitudeDegrees;
+        mLongitudeDegrees = builder.mLongitudeDegrees;
+        mAltitudeMeters = builder.mAltitudeMeters;
+        mHorizontalPositionUncertaintyMeters = builder.mHorizontalPositionUncertaintyMeters;
+        mVerticalPositionUncertaintyMeters = builder.mVerticalPositionUncertaintyMeters;
+        mToaGpsNanosecondsOfWeek = builder.mToaGpsNanosecondsOfWeek;
+        final List<GnssSingleSatCorrection> singleSatCorrList =  builder.mSingleSatCorrectionList;
+        Preconditions.checkArgument(singleSatCorrList != null && !singleSatCorrList.isEmpty());
+        mSingleSatCorrectionList = Collections.unmodifiableList(new ArrayList<>(singleSatCorrList));
+        mHasEnvironmentBearing = builder.mEnvironmentBearingIsSet
+                && builder.mEnvironmentBearingUncertaintyIsSet;
+        mEnvironmentBearingDegrees = builder.mEnvironmentBearingDegrees;
+        mEnvironmentBearingUncertaintyDegrees = builder.mEnvironmentBearingUncertaintyDegrees;
+    }
+
+    /** Gets the latitude in degrees at which the corrections are computed. */
+    @FloatRange(from = -90.0f, to = 90.0f)
+    public double getLatitudeDegrees() {
+        return mLatitudeDegrees;
+    }
+
+    /** Gets the longitude in degrees at which the corrections are computed. */
+    @FloatRange(from = -180.0f, to = 180.0f)
+    public double getLongitudeDegrees() {
+        return mLongitudeDegrees;
+    }
+
+    /**
+     * Gets the altitude in meters above the WGS 84 reference ellipsoid at which the corrections are
+     * computed.
+     */
+    @FloatRange(from = -1000.0f, to = 10000.0f)
+    public double getAltitudeMeters() {
+        return mAltitudeMeters;
+    }
+
+    /**
+     * Gets the horizontal uncertainty (68% confidence) in meters on the device position at
+     * which the corrections are provided.
+     */
+    @FloatRange(from = 0.0f)
+    public double getHorizontalPositionUncertaintyMeters() {
+        return mHorizontalPositionUncertaintyMeters;
+    }
+
+    /**
+     * Gets the vertical uncertainty (68% confidence) in meters on the device position at
+     * which the corrections are provided.
+     */
+    @FloatRange(from = 0.0f)
+    public double getVerticalPositionUncertaintyMeters() {
+        return mVerticalPositionUncertaintyMeters;
+    }
+
+    /** Gets the time of applicability, GPS time of week in nanoseconds. */
+    @IntRange(from = 0)
+    public long getToaGpsNanosecondsOfWeek() {
+        return mToaGpsNanosecondsOfWeek;
+    }
+
+    /**
+     * Gets a set of {@link GnssSingleSatCorrection} each containing measurement corrections for a
+     * satellite in view
+     */
+    @NonNull
+    public List<GnssSingleSatCorrection> getSingleSatelliteCorrectionList() {
+        return mSingleSatCorrectionList;
+    }
+
+    /**
+     * If true, environment bearing will be available.
+     */
+    public boolean hasEnvironmentBearing() {
+        return mHasEnvironmentBearing;
+    }
+
+    /**
+     * Gets the environment bearing in degrees clockwise from true north, in the direction of user
+     * motion. Environment bearing is provided when it is known with high probability that
+     * velocity is aligned with an environment feature (such as edge of a building, or road).
+     *
+     * {@link #hasEnvironmentBearing} should be called to check the environment bearing is available
+     * before calling this method. The value is undefined if {@link #hasEnvironmentBearing} returns
+     * false.
+     */
+    @FloatRange(from = 0.0f, to = 360.0f)
+    public float getEnvironmentBearingDegrees() {
+        return mEnvironmentBearingDegrees;
+    }
+
+    /**
+     * Gets the environment bearing uncertainty in degrees. It represents the standard deviation of
+     * the physical structure in the circle of position uncertainty. The uncertainty can take values
+     * between 0 and 180 degrees. The {@link #hasEnvironmentBearing} becomes false as the
+     * uncertainty value passes a predefined threshold depending on the physical structure around
+     * the user.
+     *
+     * {@link #hasEnvironmentBearing} should be called to check the environment bearing is available
+     * before calling this method. The value is undefined if {@link #hasEnvironmentBearing} returns
+     * false.
+     */
+    @FloatRange(from = 0.0f, to = 180.0f)
+    public float getEnvironmentBearingUncertaintyDegrees() {
+        return mEnvironmentBearingUncertaintyDegrees;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<GnssMeasurementCorrections> CREATOR =
+            new Creator<GnssMeasurementCorrections>() {
+                @Override
+                @NonNull
+                public GnssMeasurementCorrections createFromParcel(@NonNull Parcel parcel) {
+                    final GnssMeasurementCorrections.Builder gnssMeasurementCorrectons =
+                            new Builder()
+                                    .setLatitudeDegrees(parcel.readDouble())
+                                    .setLongitudeDegrees(parcel.readDouble())
+                                    .setAltitudeMeters(parcel.readDouble())
+                                    .setHorizontalPositionUncertaintyMeters(parcel.readDouble())
+                                    .setVerticalPositionUncertaintyMeters(parcel.readDouble())
+                                    .setToaGpsNanosecondsOfWeek(parcel.readLong());
+                    List<GnssSingleSatCorrection> singleSatCorrectionList = new ArrayList<>();
+                    parcel.readTypedList(singleSatCorrectionList, GnssSingleSatCorrection.CREATOR);
+                    gnssMeasurementCorrectons.setSingleSatelliteCorrectionList(
+                            singleSatCorrectionList);
+                    boolean hasEnvironmentBearing = parcel.readBoolean();
+                    if (hasEnvironmentBearing) {
+                        gnssMeasurementCorrectons.setEnvironmentBearingDegrees(parcel.readFloat());
+                        gnssMeasurementCorrectons.setEnvironmentBearingUncertaintyDegrees(
+                                parcel.readFloat());
+                    }
+                    return gnssMeasurementCorrectons.build();
+                }
+
+                @Override
+                public GnssMeasurementCorrections[] newArray(int i) {
+                    return new GnssMeasurementCorrections[i];
+                }
+            };
+
+    @NonNull
+    @Override
+    public String toString() {
+        final String format = "   %-29s = %s\n";
+        StringBuilder builder = new StringBuilder("GnssMeasurementCorrections:\n");
+        builder.append(String.format(format, "LatitudeDegrees = ", mLatitudeDegrees));
+        builder.append(String.format(format, "LongitudeDegrees = ", mLongitudeDegrees));
+        builder.append(String.format(format, "AltitudeMeters = ", mAltitudeMeters));
+        builder.append(String.format(format, "HorizontalPositionUncertaintyMeters = ",
+                mHorizontalPositionUncertaintyMeters));
+        builder.append(String.format(format, "VerticalPositionUncertaintyMeters = ",
+                mVerticalPositionUncertaintyMeters));
+        builder.append(
+                String.format(format, "ToaGpsNanosecondsOfWeek = ", mToaGpsNanosecondsOfWeek));
+        builder.append(
+                String.format(format, "mSingleSatCorrectionList = ", mSingleSatCorrectionList));
+        builder.append(
+                String.format(format, "HasEnvironmentBearing = ", mHasEnvironmentBearing));
+        builder.append(
+                String.format(format, "EnvironmentBearingDegrees = ",
+                        mEnvironmentBearingDegrees));
+        builder.append(
+                String.format(format, "EnvironmentBearingUncertaintyDegrees = ",
+                mEnvironmentBearingUncertaintyDegrees));
+        return builder.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeDouble(mLatitudeDegrees);
+        parcel.writeDouble(mLongitudeDegrees);
+        parcel.writeDouble(mAltitudeMeters);
+        parcel.writeDouble(mHorizontalPositionUncertaintyMeters);
+        parcel.writeDouble(mVerticalPositionUncertaintyMeters);
+        parcel.writeLong(mToaGpsNanosecondsOfWeek);
+        parcel.writeTypedList(mSingleSatCorrectionList);
+        parcel.writeBoolean(mHasEnvironmentBearing);
+        if (mHasEnvironmentBearing) {
+            parcel.writeFloat(mEnvironmentBearingDegrees);
+            parcel.writeFloat(mEnvironmentBearingUncertaintyDegrees);
+        }
+    }
+
+    /** Builder for {@link GnssMeasurementCorrections} */
+    public static final class Builder {
+        /**
+         * For documentation of below fields, see corresponding fields in {@link
+         * GnssMeasurementCorrections}.
+         */
+        private double mLatitudeDegrees;
+        private double mLongitudeDegrees;
+        private double mAltitudeMeters;
+        private double mHorizontalPositionUncertaintyMeters;
+        private double mVerticalPositionUncertaintyMeters;
+        private long mToaGpsNanosecondsOfWeek;
+        @Nullable private List<GnssSingleSatCorrection> mSingleSatCorrectionList;
+        private float mEnvironmentBearingDegrees;
+        private boolean mEnvironmentBearingIsSet = false;
+        private float mEnvironmentBearingUncertaintyDegrees;
+        private boolean mEnvironmentBearingUncertaintyIsSet = false;
+
+        /** Sets the latitude in degrees at which the corrections are computed. */
+        @NonNull public Builder setLatitudeDegrees(
+                @FloatRange(from = -90.0f, to = 90.0f) double latitudeDegrees) {
+            mLatitudeDegrees = latitudeDegrees;
+            return this;
+        }
+
+        /** Sets the longitude in degrees at which the corrections are computed. */
+        @NonNull public Builder setLongitudeDegrees(
+                @FloatRange(from = -180.0f, to = 180.0f) double longitudeDegrees) {
+            mLongitudeDegrees = longitudeDegrees;
+            return this;
+        }
+
+        /**
+         * Sets the altitude in meters above the WGS 84 reference ellipsoid at which the corrections
+         * are computed.
+         */
+        @NonNull public Builder setAltitudeMeters(
+                @FloatRange(from = -1000.0f, to = 10000.0f) double altitudeMeters) {
+            mAltitudeMeters = altitudeMeters;
+            return this;
+        }
+
+
+        /**
+         * Sets the horizontal uncertainty (68% confidence) in meters on the device position at
+         * which the corrections are provided.
+         */
+        @NonNull public Builder setHorizontalPositionUncertaintyMeters(
+                @FloatRange(from = 0.0f) double horizontalPositionUncertaintyMeters) {
+            mHorizontalPositionUncertaintyMeters = horizontalPositionUncertaintyMeters;
+            return this;
+        }
+
+        /**
+         * Sets the vertical uncertainty (68% confidence) in meters on the device position at which
+         * the corrections are provided.
+         */
+        @NonNull public Builder setVerticalPositionUncertaintyMeters(
+                @FloatRange(from = 0.0f) double verticalPositionUncertaintyMeters) {
+            mVerticalPositionUncertaintyMeters = verticalPositionUncertaintyMeters;
+            return this;
+        }
+
+        /** Sets the time of applicability, GPS time of week in nanoseconds. */
+        @NonNull public Builder setToaGpsNanosecondsOfWeek(
+                @IntRange(from = 0) long toaGpsNanosecondsOfWeek) {
+            mToaGpsNanosecondsOfWeek = toaGpsNanosecondsOfWeek;
+            return this;
+        }
+
+        /**
+         * Sets a the list of {@link GnssSingleSatCorrection} containing measurement corrections for
+         * a satellite in view
+         */
+        @NonNull public Builder setSingleSatelliteCorrectionList(
+                @NonNull List<GnssSingleSatCorrection> singleSatCorrectionList) {
+            mSingleSatCorrectionList = singleSatCorrectionList;
+            return this;
+        }
+
+        /**
+         * Sets the environment bearing in degrees clockwise from true north, in the direction of
+         * user motion. Environment bearing is provided when it is known with high probability
+         * that velocity is aligned with an environment feature (such as edge of a building, or
+         * road).
+         *
+         * Both the bearing and uncertainty must be set for the environment bearing to be valid.
+         */
+        @NonNull public Builder setEnvironmentBearingDegrees(
+                @FloatRange(from = 0.0f, to = 360.0f)
+                        float environmentBearingDegrees) {
+            mEnvironmentBearingDegrees = environmentBearingDegrees;
+            mEnvironmentBearingIsSet = true;
+            return this;
+        }
+
+        /**
+         * Sets the environment bearing uncertainty in degrees.
+         *
+         * Both the bearing and uncertainty must be set for the environment bearing to be valid.
+         */
+        @NonNull public Builder setEnvironmentBearingUncertaintyDegrees(
+                @FloatRange(from = 0.0f, to = 180.0f)
+                        float environmentBearingUncertaintyDegrees) {
+            mEnvironmentBearingUncertaintyDegrees = environmentBearingUncertaintyDegrees;
+            mEnvironmentBearingUncertaintyIsSet = true;
+            return this;
+        }
+
+        /** Builds a {@link GnssMeasurementCorrections} instance as specified by this builder. */
+        @NonNull public GnssMeasurementCorrections build() {
+            if (mEnvironmentBearingIsSet ^ mEnvironmentBearingUncertaintyIsSet) {
+                throw new IllegalStateException("Both environment bearing and environment bearing "
+                        + "uncertainty must be set.");
+            }
+            return new GnssMeasurementCorrections(this);
+        }
+    }
+}
diff --git a/android/location/GnssMeasurementsEvent.java b/android/location/GnssMeasurementsEvent.java
new file mode 100644
index 0000000..98ef2d4
--- /dev/null
+++ b/android/location/GnssMeasurementsEvent.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.TestApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * A class implementing a container for data associated with a measurement event.
+ * Events are delivered to registered instances of {@link Callback}.
+ */
+public final class GnssMeasurementsEvent implements Parcelable {
+    private final GnssClock mClock;
+    private final Collection<GnssMeasurement> mReadOnlyMeasurements;
+
+    /**
+     * Used for receiving GNSS satellite measurements from the GNSS engine.
+     * Each measurement contains raw and computed data identifying a satellite.
+     * You can implement this interface and call
+     * {@link LocationManager#registerGnssMeasurementsCallback}.
+     */
+    public static abstract class Callback {
+        /**
+         * The status of the GNSS measurements event.
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED, STATUS_NOT_ALLOWED})
+        public @interface GnssMeasurementsStatus {}
+
+        /**
+         * The system does not support tracking of GNSS Measurements.
+         *
+         * <p>This status will not change in the future.
+         */
+        public static final int STATUS_NOT_SUPPORTED = 0;
+
+        /**
+         * GNSS Measurements are successfully being tracked, it will receive updates once they are
+         * available.
+         */
+        public static final int STATUS_READY = 1;
+
+        /**
+         * GPS provider or Location is disabled, updates will not be received until they are
+         * enabled.
+         */
+        public static final int STATUS_LOCATION_DISABLED = 2;
+
+        /**
+         * The client is not allowed to register for GNSS Measurements in general or in the
+         * requested mode.
+         *
+         * <p>Such a status is returned when a client tries to request a functionality from the GNSS
+         * chipset while another client has an ongoing request that does not allow such
+         * functionality to be performed.
+         *
+         * <p>If such a status is received, one would try again at a later time point where no
+         * other client is having a conflicting request.
+         */
+        public static final int STATUS_NOT_ALLOWED = 3;
+
+        /**
+         * Reports the latest collected GNSS Measurements.
+         */
+        public void onGnssMeasurementsReceived(GnssMeasurementsEvent eventArgs) {}
+
+        /**
+         * Reports the latest status of the GNSS Measurements sub-system.
+         */
+        public void onStatusChanged(@GnssMeasurementsStatus int status) {}
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public GnssMeasurementsEvent(GnssClock clock, GnssMeasurement[] measurements) {
+        if (clock == null) {
+            throw new InvalidParameterException("Parameter 'clock' must not be null.");
+        }
+        if (measurements == null || measurements.length == 0) {
+            mReadOnlyMeasurements = Collections.emptyList();
+        } else {
+            Collection<GnssMeasurement> measurementCollection = Arrays.asList(measurements);
+            mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
+        }
+
+        mClock = clock;
+    }
+
+    /**
+     * Gets the GNSS receiver clock information associated with the measurements for the current
+     * event.
+     */
+    @NonNull
+    public GnssClock getClock() {
+        return mClock;
+    }
+
+    /**
+     * Gets a read-only collection of measurements associated with the current event.
+     */
+    @NonNull
+    public Collection<GnssMeasurement> getMeasurements() {
+        return mReadOnlyMeasurements;
+    }
+
+    public static final @android.annotation.NonNull Creator<GnssMeasurementsEvent> CREATOR =
+            new Creator<GnssMeasurementsEvent>() {
+        @Override
+        public GnssMeasurementsEvent createFromParcel(Parcel in) {
+            ClassLoader classLoader = getClass().getClassLoader();
+
+            GnssClock clock = in.readParcelable(classLoader);
+
+            int measurementsLength = in.readInt();
+            GnssMeasurement[] measurementsArray = new GnssMeasurement[measurementsLength];
+            in.readTypedArray(measurementsArray, GnssMeasurement.CREATOR);
+
+            return new GnssMeasurementsEvent(clock, measurementsArray);
+        }
+
+        @Override
+        public GnssMeasurementsEvent[] newArray(int size) {
+            return new GnssMeasurementsEvent[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeParcelable(mClock, flags);
+
+        int measurementsCount = mReadOnlyMeasurements.size();
+        GnssMeasurement[] measurementsArray =
+                mReadOnlyMeasurements.toArray(new GnssMeasurement[measurementsCount]);
+        parcel.writeInt(measurementsArray.length);
+        parcel.writeTypedArray(measurementsArray, flags);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("[ GnssMeasurementsEvent:\n\n");
+
+        builder.append(mClock.toString());
+        builder.append("\n");
+
+        for (GnssMeasurement measurement : mReadOnlyMeasurements) {
+            builder.append(measurement.toString());
+            builder.append("\n");
+        }
+
+        builder.append("]");
+
+        return builder.toString();
+    }
+}
diff --git a/android/location/GnssNavigationMessage.java b/android/location/GnssNavigationMessage.java
new file mode 100644
index 0000000..27d3637
--- /dev/null
+++ b/android/location/GnssNavigationMessage.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.security.InvalidParameterException;
+
+/**
+ * A class containing a GNSS satellite Navigation Message.
+ */
+public final class GnssNavigationMessage implements Parcelable {
+
+    private static final byte[] EMPTY_ARRAY = new byte[0];
+
+    /**
+     * The type of the GNSS Navigation Message
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({TYPE_UNKNOWN, TYPE_GPS_L1CA, TYPE_GPS_L2CNAV, TYPE_GPS_L5CNAV, TYPE_GPS_CNAV2,
+            TYPE_SBS, TYPE_GLO_L1CA, TYPE_QZS_L1CA, TYPE_BDS_D1, TYPE_BDS_D2, TYPE_BDS_CNAV1,
+            TYPE_BDS_CNAV2, TYPE_GAL_I, TYPE_GAL_F, TYPE_IRN_L5CA})
+    public @interface GnssNavigationMessageType {}
+
+    // The following enumerations must be in sync with the values declared in gps.h
+
+    /** Message type unknown */
+    public static final int TYPE_UNKNOWN = 0;
+    /** GPS L1 C/A message contained in the structure.  */
+    public static final int TYPE_GPS_L1CA = 0x0101;
+    /** GPS L2-CNAV message contained in the structure. */
+    public static final int TYPE_GPS_L2CNAV = 0x0102;
+    /** GPS L5-CNAV message contained in the structure. */
+    public static final int TYPE_GPS_L5CNAV = 0x0103;
+    /** GPS CNAV-2 message contained in the structure. */
+    public static final int TYPE_GPS_CNAV2 = 0x0104;
+    /** SBAS message contained in the structure. */
+    public static final int TYPE_SBS = 0x0201;
+    /** Glonass L1 CA message contained in the structure. */
+    public static final int TYPE_GLO_L1CA = 0x0301;
+    /** QZSS L1 C/A message contained in the structure. */
+    public static final int TYPE_QZS_L1CA = 0x0401;
+    /** Beidou D1 message contained in the structure. */
+    public static final int TYPE_BDS_D1 = 0x0501;
+    /** Beidou D2 message contained in the structure. */
+    public static final int TYPE_BDS_D2 = 0x0502;
+    /** Beidou CNAV1 message contained in the structure. */
+    public static final int TYPE_BDS_CNAV1 = 0x0503;
+    /** Beidou CNAV2 message contained in the structure. */
+    public static final int TYPE_BDS_CNAV2 = 0x0504;
+    /** Galileo I/NAV message contained in the structure. */
+    public static final int TYPE_GAL_I = 0x0601;
+    /** Galileo F/NAV message contained in the structure. */
+    public static final int TYPE_GAL_F = 0x0602;
+    /** IRNSS L5 C/A message contained in the structure. */
+    public static final int TYPE_IRN_L5CA = 0x0701;
+
+    /**
+     * The Navigation Message Status is 'unknown'.
+     */
+    public static final int STATUS_UNKNOWN = 0;
+
+    /**
+     * The Navigation Message was received without any parity error in its navigation words.
+     */
+    public static final int STATUS_PARITY_PASSED = (1<<0);
+
+    /**
+     * The Navigation Message was received with words that failed parity check, but the receiver was
+     * able to correct those words.
+     */
+    public static final int STATUS_PARITY_REBUILT = (1<<1);
+
+    /**
+     * Used for receiving GNSS satellite Navigation Messages from the GNSS engine.
+     *
+     * <p>You can implement this interface and call
+     * {@link LocationManager#registerGnssNavigationMessageCallback}.
+     */
+    public static abstract class Callback {
+        /**
+         * The status of GNSS Navigation Message event.
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({STATUS_NOT_SUPPORTED, STATUS_READY, STATUS_LOCATION_DISABLED})
+        public @interface GnssNavigationMessageStatus {}
+
+        /**
+         * The system does not support tracking of GNSS Navigation Messages.
+         *
+         * This status will not change in the future.
+         */
+        public static final int STATUS_NOT_SUPPORTED = 0;
+
+        /**
+         * GNSS Navigation Messages are successfully being tracked, it will receive updates once
+         * they are available.
+         */
+        public static final int STATUS_READY = 1;
+
+        /**
+         * GNSS provider or Location is disabled, updated will not be received until they are
+         * enabled.
+         */
+        public static final int STATUS_LOCATION_DISABLED = 2;
+
+        /**
+         * Returns the latest collected GNSS Navigation Message.
+         */
+        public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {}
+
+        /**
+         * Returns the latest status of the GNSS Navigation Messages sub-system.
+         */
+        public void onStatusChanged(@GnssNavigationMessageStatus int status) {}
+    }
+
+    // End enumerations in sync with gps.h
+
+    private int mType;
+    private int mSvid;
+    private int mMessageId;
+    private int mSubmessageId;
+    private byte[] mData;
+    private int mStatus;
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public GnssNavigationMessage() {
+        initialize();
+    }
+
+    /**
+     * Sets all contents to the values stored in the provided object.
+     * @hide
+     */
+    @TestApi
+    public void set(GnssNavigationMessage navigationMessage) {
+        mType = navigationMessage.mType;
+        mSvid = navigationMessage.mSvid;
+        mMessageId = navigationMessage.mMessageId;
+        mSubmessageId = navigationMessage.mSubmessageId;
+        mData = navigationMessage.mData;
+        mStatus = navigationMessage.mStatus;
+    }
+
+    /**
+     * Resets all the contents to its original state.
+     * @hide
+     */
+    @TestApi
+    public void reset() {
+        initialize();
+    }
+
+    /**
+     * Gets the type of the navigation message contained in the object.
+     */
+    @GnssNavigationMessageType
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Sets the type of the navigation message.
+     * @hide
+     */
+    @TestApi
+    public void setType(@GnssNavigationMessageType int value) {
+        mType = value;
+    }
+
+    /**
+     * Gets a string representation of the 'type'.
+     * For internal and logging use only.
+     */
+    private String getTypeString() {
+        switch (mType) {
+            case TYPE_UNKNOWN:
+                return "Unknown";
+            case TYPE_GPS_L1CA:
+                return "GPS L1 C/A";
+            case TYPE_GPS_L2CNAV:
+                return "GPS L2-CNAV";
+            case TYPE_GPS_L5CNAV:
+                return "GPS L5-CNAV";
+            case TYPE_GPS_CNAV2:
+                return "GPS CNAV2";
+            case TYPE_SBS:
+                return "SBS";
+            case TYPE_GLO_L1CA:
+                return "Glonass L1 C/A";
+            case TYPE_QZS_L1CA:
+                return "QZSS L1 C/A";
+            case TYPE_BDS_D1:
+                return "Beidou D1";
+            case TYPE_BDS_D2:
+                return "Beidou D2";
+            case TYPE_BDS_CNAV1:
+                return "Beidou CNAV1";
+            case TYPE_BDS_CNAV2:
+                return "Beidou CNAV2";
+            case TYPE_GAL_I:
+                return "Galileo I";
+            case TYPE_GAL_F:
+                return "Galileo F";
+            case TYPE_IRN_L5CA:
+                return "IRNSS L5 C/A";
+            default:
+                return "<Invalid:" + mType + ">";
+        }
+    }
+
+    /**
+     * Gets the satellite ID.
+     *
+     * <p>Range varies by constellation.  See definition at {@code GnssStatus#getSvid(int)}
+     */
+    public int getSvid() {
+        return mSvid;
+    }
+
+    /**
+     * Sets the satellite ID.
+     * @hide
+     */
+    @TestApi
+    public void setSvid(int value) {
+        mSvid = value;
+    }
+
+    /**
+     * Gets the Message identifier.
+     *
+     * <p>This provides an index to help with complete Navigation Message assembly. Similar
+     * identifiers within the data bits themselves often supplement this information, in ways even
+     * more specific to each message type; see the relevant satellite constellation ICDs for
+     * details.
+     *
+     * <ul>
+     * <li> For GPS L1 C/A subframe 4 and 5, this value corresponds to the 'frame id' of the
+     * navigation message, in the range of 1-25 (Subframe 1, 2, 3 does not contain a 'frame id' and
+     * this value can be set to -1.)</li>
+     * <li> For Glonass L1 C/A, this refers to the frame ID, in the range of 1-5.</li>
+     * <li> For BeiDou D1, this refers to the frame number in the range of 1-24</li>
+     * <li> For Beidou D2, this refers to the frame number, in the range of 1-120</li>
+     * <li> For Galileo F/NAV nominal frame structure, this refers to the subframe number, in the
+     * range of 1-12</li>
+     * <li> For Galileo I/NAV nominal frame structure, this refers to the subframe number in the
+     * range of 1-24</li>
+     * <li> For SBAS and Beidou CNAV2, this is unused and can be set to -1.</li>
+     * <li> For QZSS L1 C/A subframe 4 and 5, this value corresponds to the 'frame id' of the
+     * navigation message, in the range of 1-25 (Subframe 1, 2, 3 does not contain a 'frame id' and
+     * this value can be set to -1.)</li>
+     * <li> For Beidou CNAV1 this refers to the page type number in the range of 1-63.</li>
+     * <li> For IRNSS L5 C/A subframe 3 and 4, this value corresponds to the Message Id of the
+     * navigation message, in the range of 1-63. (Subframe 1 and 2 does not contain a message type
+     * id and this value can be set to -1.)</li>
+     * </ul>
+     */
+    public int getMessageId() {
+        return mMessageId;
+    }
+
+    /**
+     * Sets the Message Identifier.
+     * @hide
+     */
+    @TestApi
+    public void setMessageId(int value) {
+        mMessageId = value;
+    }
+
+    /**
+     * Gets the sub-message identifier, relevant to the {@link #getType()} of the message.
+     *
+     * <ul>
+     * <li> For GPS L1 C/A, BeiDou D1 &amp; BeiDou D2, the submessage id corresponds to the subframe
+     * number of the navigation message, in the range of 1-5.</li>
+     * <li>For Glonass L1 C/A, this refers to the String number, in the range from 1-15</li>
+     * <li>For Galileo F/NAV, this refers to the page type in the range 1-6</li>
+     * <li>For Galileo I/NAV, this refers to the word type in the range 1-10+</li>
+     * <li>For Galileo in particular, the type information embedded within the data bits may be even
+     * more useful in interpretation, than the nominal page and word types provided in this
+     * field.</li>
+     * <li> For SBAS, the submessage id corresponds to the message type, in the range 1-63.</li>
+     * <li> For Beidou CNAV1, the submessage id corresponds to the subframe number of the
+     * navigation message, in the range of 1-3.</li>
+     * <li> For Beidou CNAV2, the submessage id corresponds to the message type, in the range
+     * 1-63.</li>
+     * <li> For IRNSS L5 C/A, the submessage id corresponds to the subframe number of the
+     * navigation message, in the range of 1-4.</li>
+     * </ul>
+     */
+    public int getSubmessageId() {
+        return mSubmessageId;
+    }
+
+    /**
+     * Sets the Sub-message identifier.
+     * @hide
+     */
+    @TestApi
+    public void setSubmessageId(int value) {
+        mSubmessageId = value;
+    }
+
+    /**
+     * Gets the data of the reported GPS message.
+     *
+     * <p>The bytes (or words) specified using big endian format (MSB first).
+     *
+     * <ul>
+     * <li>For GPS L1 C/A, Beidou D1 &amp; Beidou D2, each subframe contains 10 30-bit words. Each
+     * word (30 bits) should be fit into the last 30 bits in a 4-byte word (skip B31 and B32), with
+     * MSB first, for a total of 40 bytes, covering a time period of 6, 6, and 0.6 seconds,
+     * respectively.</li>
+     * <li>For Glonass L1 C/A, each string contains 85 data bits, including the checksum.  These
+     * bits should be fit into 11 bytes, with MSB first (skip B86-B88), covering a time period of 2
+     * seconds.</li>
+     * <li>For Galileo F/NAV, each word consists of 238-bit (sync &amp; tail symbols excluded). Each
+     * word should be fit into 30-bytes, with MSB first (skip B239, B240), covering a time period of
+     * 10 seconds.</li>
+     * <li>For Galileo I/NAV, each page contains 2 page parts, even and odd, with a total of 2x114 =
+     * 228 bits, (sync &amp; tail excluded) that should be fit into 29 bytes, with MSB first (skip
+     * B229-B232).</li>
+     * <li>For SBAS, each block consists of 250 data bits, that should be fit into 32 bytes.  MSB
+     * first (skip B251-B256).</li>
+     * <li>For Beidou CNAV1, subframe #1 consists of 14 data bits, that should be fit into 2
+     * bytes. MSB first (skip B15-B16).  subframe #2 consists of 600 bits that should be fit into
+     * 75 bytes. subframe #3 consists of 264 data bits that should be fit into 33 bytes.</li>
+     * <li>For Beidou CNAV2, each subframe consists of 288 data bits, that should be fit into 36
+     * bytes.</li>
+     * </ul>
+     */
+    @NonNull
+    public byte[] getData() {
+        return mData;
+    }
+
+    /**
+     * Sets the data associated with the Navigation Message.
+     * @hide
+     */
+    @TestApi
+    public void setData(byte[] value) {
+        if (value == null) {
+            throw new InvalidParameterException("Data must be a non-null array");
+        }
+
+        mData = value;
+    }
+
+    /**
+     * Gets the Status of the navigation message contained in the object.
+     */
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Sets the status of the navigation message.
+     * @hide
+     */
+    @TestApi
+    public void setStatus(int value) {
+        mStatus = value;
+    }
+
+    /**
+     * Gets a string representation of the 'status'.
+     * For internal and logging use only.
+     */
+    private String getStatusString() {
+        switch (mStatus) {
+            case STATUS_UNKNOWN:
+                return "Unknown";
+            case STATUS_PARITY_PASSED:
+                return "ParityPassed";
+            case STATUS_PARITY_REBUILT:
+                return "ParityRebuilt";
+            default:
+                return "<Invalid:" + mStatus + ">";
+        }
+    }
+
+    public static final @android.annotation.NonNull Creator<GnssNavigationMessage> CREATOR =
+            new Creator<GnssNavigationMessage>() {
+        @Override
+        public GnssNavigationMessage createFromParcel(Parcel parcel) {
+            GnssNavigationMessage navigationMessage = new GnssNavigationMessage();
+
+            navigationMessage.setType(parcel.readInt());
+            navigationMessage.setSvid(parcel.readInt());
+            navigationMessage.setMessageId(parcel.readInt());
+            navigationMessage.setSubmessageId(parcel.readInt());
+            int dataLength = parcel.readInt();
+            byte[] data = new byte[dataLength];
+            parcel.readByteArray(data);
+            navigationMessage.setData(data);
+            navigationMessage.setStatus(parcel.readInt());
+
+            return navigationMessage;
+        }
+
+        @Override
+        public GnssNavigationMessage[] newArray(int size) {
+            return new GnssNavigationMessage[size];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mType);
+        parcel.writeInt(mSvid);
+        parcel.writeInt(mMessageId);
+        parcel.writeInt(mSubmessageId);
+        parcel.writeInt(mData.length);
+        parcel.writeByteArray(mData);
+        parcel.writeInt(mStatus);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        final String format = "   %-15s = %s\n";
+        StringBuilder builder = new StringBuilder("GnssNavigationMessage:\n");
+
+        builder.append(String.format(format, "Type", getTypeString()));
+        builder.append(String.format(format, "Svid", mSvid));
+        builder.append(String.format(format, "Status", getStatusString()));
+        builder.append(String.format(format, "MessageId", mMessageId));
+        builder.append(String.format(format, "SubmessageId", mSubmessageId));
+
+        builder.append(String.format(format, "Data", "{"));
+        String prefix = "        ";
+        for(byte value : mData) {
+            builder.append(prefix);
+            builder.append(value);
+            prefix = ", ";
+        }
+        builder.append(" }");
+
+        return builder.toString();
+    }
+
+    private void initialize() {
+        mType = TYPE_UNKNOWN;
+        mSvid = 0;
+        mMessageId = -1;
+        mSubmessageId = -1;
+        mData = EMPTY_ARRAY;
+        mStatus = STATUS_UNKNOWN;
+    }
+}
diff --git a/android/location/GnssReflectingPlane.java b/android/location/GnssReflectingPlane.java
new file mode 100644
index 0000000..1acdd1e
--- /dev/null
+++ b/android/location/GnssReflectingPlane.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2018 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.location;
+
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Holds the characteristics of the reflecting plane that a satellite signal has bounced from.
+ *
+ * @hide
+ */
+@SystemApi
+public final class GnssReflectingPlane implements Parcelable {
+
+    /** Represents latitude in degrees of the reflecting plane */
+    @FloatRange(from = -90.0f, to = 90.0f)
+    private final double mLatitudeDegrees;
+    /** Represents longitude in degrees of the reflecting plane. */
+    @FloatRange(from = -180.0f, to = 180.0f)
+    private final double mLongitudeDegrees;
+    /**
+     * Represents altitude in meters above the WGS 84 reference ellipsoid of the reflection point in
+     * the plane
+     */
+    @FloatRange(from = -1000.0f, to = 10000.0f)
+    private final double mAltitudeMeters;
+
+    /** Represents azimuth clockwise from north of the reflecting plane in degrees. */
+    @FloatRange(from = 0.0f, to = 360.0f)
+    private final double mAzimuthDegrees;
+
+    private GnssReflectingPlane(Builder builder) {
+        mLatitudeDegrees = builder.mLatitudeDegrees;
+        mLongitudeDegrees = builder.mLongitudeDegrees;
+        mAltitudeMeters = builder.mAltitudeMeters;
+        mAzimuthDegrees = builder.mAzimuthDegrees;
+    }
+
+    /** Gets the latitude in degrees of the reflecting plane. */
+    @FloatRange(from = -90.0f, to = 90.0f)
+    public double getLatitudeDegrees() {
+        return mLatitudeDegrees;
+    }
+
+    /** Gets the longitude in degrees of the reflecting plane. */
+    @FloatRange(from = -180.0f, to = 180.0f)
+    public double getLongitudeDegrees() {
+        return mLongitudeDegrees;
+    }
+
+    /**
+     * Gets the altitude in meters above the WGS 84 reference ellipsoid of the reflecting point
+     * within the plane
+     */
+    @FloatRange(from = -1000.0f, to = 10000.0f)
+    public double getAltitudeMeters() {
+        return mAltitudeMeters;
+    }
+
+    /** Gets the azimuth clockwise from north of the reflecting plane in degrees. */
+    @FloatRange(from = 0.0f, to = 360.0f)
+    public double getAzimuthDegrees() {
+        return mAzimuthDegrees;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<GnssReflectingPlane> CREATOR =
+            new Creator<GnssReflectingPlane>() {
+                @Override
+                @NonNull
+                public GnssReflectingPlane createFromParcel(@NonNull Parcel parcel) {
+                    GnssReflectingPlane reflectingPlane =
+                            new Builder()
+                                    .setLatitudeDegrees(parcel.readDouble())
+                                    .setLongitudeDegrees(parcel.readDouble())
+                                    .setAltitudeMeters(parcel.readDouble())
+                                    .setAzimuthDegrees(parcel.readDouble())
+                                    .build();
+                    return reflectingPlane;
+                }
+
+                @Override
+                public GnssReflectingPlane[] newArray(int i) {
+                    return new GnssReflectingPlane[i];
+                }
+            };
+
+    @NonNull
+    @Override
+    public String toString() {
+        final String format = "   %-29s = %s\n";
+        StringBuilder builder = new StringBuilder("ReflectingPlane:\n");
+        builder.append(String.format(format, "LatitudeDegrees = ", mLatitudeDegrees));
+        builder.append(String.format(format, "LongitudeDegrees = ", mLongitudeDegrees));
+        builder.append(String.format(format, "AltitudeMeters = ", mAltitudeMeters));
+        builder.append(String.format(format, "AzimuthDegrees = ", mAzimuthDegrees));
+        return builder.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeDouble(mLatitudeDegrees);
+        parcel.writeDouble(mLongitudeDegrees);
+        parcel.writeDouble(mAltitudeMeters);
+        parcel.writeDouble(mAzimuthDegrees);
+    }
+
+    /** Builder for {@link GnssReflectingPlane} */
+    public static final class Builder {
+        /** For documentation, see corresponding fields in {@link GnssReflectingPlane}. */
+        private double mLatitudeDegrees;
+        private double mLongitudeDegrees;
+        private double mAltitudeMeters;
+        private double mAzimuthDegrees;
+
+        /** Sets the latitude in degrees of the reflecting plane. */
+        @NonNull public Builder setLatitudeDegrees(
+                @FloatRange(from = -90.0f, to = 90.0f) double latitudeDegrees) {
+            mLatitudeDegrees = latitudeDegrees;
+            return this;
+        }
+
+        /** Sets the longitude in degrees of the reflecting plane. */
+        @NonNull public Builder setLongitudeDegrees(
+                @FloatRange(from = -180.0f, to = 180.0f) double longitudeDegrees) {
+            mLongitudeDegrees = longitudeDegrees;
+            return this;
+        }
+
+        /**
+         * Sets the altitude in meters above the WGS 84 reference ellipsoid of the reflecting point
+         * within the plane
+         */
+        @NonNull public Builder setAltitudeMeters(
+                @FloatRange(from = -1000.0f, to = 10000.0f) double altitudeMeters) {
+            mAltitudeMeters = altitudeMeters;
+            return this;
+        }
+
+        /** Sets the azimuth clockwise from north of the reflecting plane in degrees. */
+        @NonNull public Builder setAzimuthDegrees(
+                @FloatRange(from = 0.0f, to = 360.0f) double azimuthDegrees) {
+            mAzimuthDegrees = azimuthDegrees;
+            return this;
+        }
+
+        /** Builds a {@link GnssReflectingPlane} object as specified by this builder. */
+        @NonNull public GnssReflectingPlane build() {
+            return new GnssReflectingPlane(this);
+        }
+    }
+}
diff --git a/android/location/GnssRequest.java b/android/location/GnssRequest.java
new file mode 100644
index 0000000..2afb265
--- /dev/null
+++ b/android/location/GnssRequest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2020 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.location;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class contains extra parameters to pass to a GNSS provider implementation.
+ * @hide
+ */
+@SystemApi
+public final class GnssRequest implements Parcelable {
+    private final boolean mFullTracking;
+
+    /**
+     * Creates a {@link GnssRequest} with a full list of parameters.
+     */
+    private GnssRequest(boolean fullTracking) {
+        mFullTracking = fullTracking;
+    }
+
+    /**
+     * Represents whether to enable full GNSS tracking.
+     *
+     * <p>If true, GNSS chipset switches off duty cycling. In such a mode, no clock
+     * discontinuities are expected, and when supported, carrier phase should be continuous in
+     * good signal conditions. All non-blacklisted, healthy constellations, satellites and
+     * frequency bands that the chipset supports must be reported in this mode. The GNSS chipset
+     * is allowed to consume more power in this mode. If false, GNSS chipset optimizes power via
+     * duty cycling, constellations and frequency limits, etc.
+     */
+    public boolean isFullTracking() {
+        return mFullTracking;
+    }
+
+    @NonNull
+    public static final Creator<GnssRequest> CREATOR =
+            new Creator<GnssRequest>() {
+                @Override
+                @NonNull
+                public GnssRequest createFromParcel(@NonNull Parcel parcel) {
+                    return new GnssRequest(parcel.readBoolean());
+                }
+
+                @Override
+                public GnssRequest[] newArray(int i) {
+                    return new GnssRequest[i];
+                }
+            };
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("GnssRequest[");
+        s.append("FullTracking=").append(mFullTracking);
+        s.append(']');
+        return s.toString();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null) return false;
+        if (!(obj instanceof GnssRequest)) return false;
+
+        GnssRequest other = (GnssRequest) obj;
+        if (mFullTracking != other.mFullTracking) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return mFullTracking ? 1 : 0;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeBoolean(mFullTracking);
+    }
+
+    /** Builder for {@link GnssRequest} */
+    public static final class Builder {
+        private boolean mFullTracking;
+
+        /**
+         * Constructs a {@link Builder} instance.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Constructs a {@link Builder} instance by copying a {@link GnssRequest}.
+         */
+        public Builder(@NonNull GnssRequest request) {
+            mFullTracking = request.isFullTracking();
+        }
+
+        /**
+         * Set the value of whether to enable full GNSS tracking, which is false by default.
+         *
+         * <p>If true, GNSS chipset switches off duty cycling. In such a mode, no clock
+         * discontinuities are expected, and when supported, carrier phase should be continuous in
+         * good signal conditions. All non-blacklisted, healthy constellations, satellites and
+         * frequency bands that the chipset supports must be reported in this mode. The GNSS chipset
+         * is allowed to consume more power in this mode. If false, GNSS chipset optimizes power via
+         * duty cycling, constellations and frequency limits, etc.
+         *
+         * <p>Full tracking requests always override non-full tracking requests. If any full
+         * tracking request occurs, all listeners on the device will receive full tracking GNSS
+         * measurements.
+         */
+        @NonNull public Builder setFullTracking(boolean value) {
+            mFullTracking = value;
+            return this;
+        }
+
+        /** Builds a {@link GnssRequest} instance as specified by this builder. */
+        @NonNull
+        public GnssRequest build() {
+            return new GnssRequest(mFullTracking);
+        }
+    }
+}
diff --git a/android/location/GnssSingleSatCorrection.java b/android/location/GnssSingleSatCorrection.java
new file mode 100644
index 0000000..aeca562
--- /dev/null
+++ b/android/location/GnssSingleSatCorrection.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2018 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.location;
+
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * A container with measurement corrections for a single visible satellite
+ *
+ * @hide
+ */
+@SystemApi
+public final class GnssSingleSatCorrection implements Parcelable {
+
+    /**
+     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
+     * #mProbSatIsLos}.
+     *
+     * @hide
+     */
+    public static final int HAS_PROB_SAT_IS_LOS_MASK = 1 << 0;
+
+    /**
+     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
+     * #mExcessPathLengthMeters}.
+     *
+     * @hide
+     */
+    public static final int HAS_EXCESS_PATH_LENGTH_MASK = 1 << 1;
+
+    /**
+     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
+     * #mExcessPathLengthUncertaintyMeters}.
+     *
+     * @hide
+     */
+    public static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = 1 << 2;
+
+    /**
+     * Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
+     * #mReflectingPlane}.
+     *
+     * @hide
+     */
+    public static final int HAS_REFLECTING_PLANE_MASK = 1 << 3;
+
+    /** A bitmask of fields present in this object (see HAS_* constants defined above) */
+    private final int mSingleSatCorrectionFlags;
+
+    /** Defines the constellation of the given satellite as defined in {@link GnssStatus}. */
+    @GnssStatus.ConstellationType
+    private final int mConstellationType;
+
+    /**
+     * Satellite vehicle ID number
+     *
+     * <p>Interpretation depends on {@link GnssStatus#getSvid(int)}.
+     */
+    @IntRange(from = 0)
+    private final int mSatId;
+
+    /**
+     * Carrier frequency of the signal to be corrected, for example it can be the GPS center
+     * frequency for L1 = 1,575,420,000 Hz, varying GLO channels, etc.
+     *
+     * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction
+     * objects will be reported for this same satellite, in one of the correction objects, all the
+     * values related to L1 will be filled, and in the other all of the values related to L5 will be
+     * filled.
+     */
+    @FloatRange(from = 0.0f,  fromInclusive = false)
+    private final float mCarrierFrequencyHz;
+
+    /**
+     * The probability that the satellite is estimated to be in Line-of-Sight condition at the given
+     * location.
+     */
+    @FloatRange(from = 0.0f, to = 1.0f)
+    private final float mProbSatIsLos;
+
+    /**
+     * Excess path length to be subtracted from pseudorange before using it in calculating location.
+     */
+    @FloatRange(from = 0.0f)
+    private final float mExcessPathLengthMeters;
+
+    /** Error estimate (1-sigma) for the Excess path length estimate */
+    @FloatRange(from = 0.0f)
+    private final float mExcessPathLengthUncertaintyMeters;
+
+    /**
+     * Defines the reflecting plane location and azimuth information
+     *
+     * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
+     * signal goes through multiple reflections or if reflection plane serving is not supported.
+     */
+    @Nullable
+    private final GnssReflectingPlane mReflectingPlane;
+
+    private GnssSingleSatCorrection(Builder builder) {
+        mSingleSatCorrectionFlags = builder.mSingleSatCorrectionFlags;
+        mSatId = builder.mSatId;
+        mConstellationType = builder.mConstellationType;
+        mCarrierFrequencyHz = builder.mCarrierFrequencyHz;
+        mProbSatIsLos = builder.mProbSatIsLos;
+        mExcessPathLengthMeters = builder.mExcessPathLengthMeters;
+        mExcessPathLengthUncertaintyMeters = builder.mExcessPathLengthUncertaintyMeters;
+        mReflectingPlane = builder.mReflectingPlane;
+    }
+
+    /**
+     * Gets a bitmask of fields present in this object
+     *
+     * @hide
+     */
+    public int getSingleSatelliteCorrectionFlags() {
+        return mSingleSatCorrectionFlags;
+    }
+
+    /**
+     * Gets the constellation type.
+     *
+     * <p>The return value is one of those constants with {@code CONSTELLATION_} prefix in {@link
+     * GnssStatus}.
+     */
+    @GnssStatus.ConstellationType
+    public int getConstellationType() {
+        return mConstellationType;
+    }
+
+    /**
+     * Gets the satellite ID.
+     *
+     * <p>Interpretation depends on {@link #getConstellationType()}. See {@link
+     * GnssStatus#getSvid(int)}.
+     */
+    @IntRange(from = 0)
+    public int getSatelliteId() {
+        return mSatId;
+    }
+
+    /**
+     * Gets the carrier frequency of the tracked signal.
+     *
+     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
+     * L5 = 1176.45 MHz, varying GLO channels, etc.
+     *
+     * <p>For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two correction
+     * objects will be reported for this same satellite, in one of the correction objects, all the
+     * values related to L1 will be filled, and in the other all of the values related to L5 will be
+     * filled.
+     *
+     * @return the carrier frequency of the signal tracked in Hz.
+     */
+    @FloatRange(from = 0.0f,  fromInclusive = false)
+    public float getCarrierFrequencyHz() {
+        return mCarrierFrequencyHz;
+    }
+
+    /**
+     * Returns the probability that the satellite is in line-of-sight condition at the given
+     * location.
+     */
+    @FloatRange(from = 0.0f, to = 1.0f)
+    public float getProbabilityLineOfSight() {
+        return mProbSatIsLos;
+    }
+
+    /**
+     * Returns the Excess path length to be subtracted from pseudorange before using it in
+     * calculating location.
+     */
+    @FloatRange(from = 0.0f)
+    public float getExcessPathLengthMeters() {
+        return mExcessPathLengthMeters;
+    }
+
+    /** Returns the error estimate (1-sigma) for the Excess path length estimate */
+    @FloatRange(from = 0.0f)
+    public float getExcessPathLengthUncertaintyMeters() {
+        return mExcessPathLengthUncertaintyMeters;
+    }
+
+    /**
+     * Returns the reflecting plane characteristics at which the signal has bounced
+     *
+     * <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
+     * signal goes through multiple reflections or if reflection plane serving is not supported
+     */
+    @Nullable
+    public GnssReflectingPlane getReflectingPlane() {
+        return mReflectingPlane;
+    }
+
+    /** Returns {@code true} if {@link #getProbabilityLineOfSight()} is valid. */
+    public boolean hasValidSatelliteLineOfSight() {
+        return (mSingleSatCorrectionFlags & HAS_PROB_SAT_IS_LOS_MASK) != 0;
+    }
+
+    /** Returns {@code true} if {@link #getExcessPathLengthMeters()} is valid. */
+    public boolean hasExcessPathLength() {
+        return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_MASK) != 0;
+    }
+
+    /** Returns {@code true} if {@link #getExcessPathLengthUncertaintyMeters()} is valid. */
+    public boolean hasExcessPathLengthUncertainty() {
+        return (mSingleSatCorrectionFlags & HAS_EXCESS_PATH_LENGTH_UNC_MASK) != 0;
+    }
+
+    /** Returns {@code true} if {@link #getReflectingPlane()} is valid. */
+    public boolean hasReflectingPlane() {
+        return (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<GnssSingleSatCorrection> CREATOR =
+            new Creator<GnssSingleSatCorrection>() {
+                @Override
+                @NonNull
+                public GnssSingleSatCorrection createFromParcel(@NonNull Parcel parcel) {
+                    int mSingleSatCorrectionFlags = parcel.readInt();
+                    boolean hasReflectingPlane =
+                            (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0;
+                    final GnssSingleSatCorrection.Builder singleSatCorrectionBuilder =
+                            new Builder()
+                                    .setConstellationType(parcel.readInt())
+                                    .setSatelliteId(parcel.readInt())
+                                    .setCarrierFrequencyHz(parcel.readFloat())
+                                    .setProbabilityLineOfSight(parcel.readFloat())
+                                    .setExcessPathLengthMeters(parcel.readFloat())
+                                    .setExcessPathLengthUncertaintyMeters(parcel.readFloat());
+                    if (hasReflectingPlane) {
+                        singleSatCorrectionBuilder.setReflectingPlane(
+                                GnssReflectingPlane.CREATOR.createFromParcel(parcel));
+                    }
+                    return singleSatCorrectionBuilder.build();
+                }
+
+                @Override
+                public GnssSingleSatCorrection[] newArray(int i) {
+                    return new GnssSingleSatCorrection[i];
+                }
+            };
+
+    @NonNull
+    @Override
+    public String toString() {
+        final String format = "   %-29s = %s\n";
+        StringBuilder builder = new StringBuilder("GnssSingleSatCorrection:\n");
+        builder.append(
+                String.format(format, "SingleSatCorrectionFlags = ", mSingleSatCorrectionFlags));
+        builder.append(String.format(format, "ConstellationType = ", mConstellationType));
+        builder.append(String.format(format, "SatId = ", mSatId));
+        builder.append(String.format(format, "CarrierFrequencyHz = ", mCarrierFrequencyHz));
+        builder.append(String.format(format, "ProbSatIsLos = ", mProbSatIsLos));
+        builder.append(String.format(format, "ExcessPathLengthMeters = ", mExcessPathLengthMeters));
+        builder.append(
+                String.format(
+                        format,
+                        "ExcessPathLengthUncertaintyMeters = ",
+                        mExcessPathLengthUncertaintyMeters));
+        if (hasReflectingPlane()) {
+            builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane));
+        }
+        return builder.toString();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeInt(mSingleSatCorrectionFlags);
+        parcel.writeInt(mConstellationType);
+        parcel.writeInt(mSatId);
+        parcel.writeFloat(mCarrierFrequencyHz);
+        parcel.writeFloat(mProbSatIsLos);
+        parcel.writeFloat(mExcessPathLengthMeters);
+        parcel.writeFloat(mExcessPathLengthUncertaintyMeters);
+        if (hasReflectingPlane()) {
+            mReflectingPlane.writeToParcel(parcel, flags);
+        }
+    }
+
+    /** Builder for {@link GnssSingleSatCorrection} */
+    public static final class Builder {
+
+        /**
+         * For documentation of below fields, see corresponding fields in {@link
+         * GnssSingleSatCorrection}.
+         */
+        private int mSingleSatCorrectionFlags;
+
+        private int mConstellationType;
+        private int mSatId;
+        private float mCarrierFrequencyHz;
+        private float mProbSatIsLos;
+        private float mExcessPathLengthMeters;
+        private float mExcessPathLengthUncertaintyMeters;
+        @Nullable
+        private GnssReflectingPlane mReflectingPlane;
+
+        /** Sets the constellation type. */
+        @NonNull public Builder setConstellationType(
+                @GnssStatus.ConstellationType int constellationType) {
+            mConstellationType = constellationType;
+            return this;
+        }
+
+        /** Sets the Satellite ID defined in the ICD of the given constellation. */
+        @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) {
+            mSatId = satId;
+            return this;
+        }
+
+        /** Sets the Carrier frequency in Hz. */
+        @NonNull public Builder setCarrierFrequencyHz(
+                @FloatRange(from = 0.0f,  fromInclusive = false) float carrierFrequencyHz) {
+            mCarrierFrequencyHz = carrierFrequencyHz;
+            return this;
+        }
+
+        /**
+         * Sets the line-of-sight probability of the satellite at the given location in the range
+         * between 0 and 1.
+         */
+        @NonNull public Builder setProbabilityLineOfSight(
+                @FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) {
+            Preconditions.checkArgumentInRange(
+                    probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1.");
+            mProbSatIsLos = probSatIsLos;
+            mSingleSatCorrectionFlags =
+                    (byte) (mSingleSatCorrectionFlags | HAS_PROB_SAT_IS_LOS_MASK);
+            return this;
+        }
+
+        /**
+         * Sets the Excess path length to be subtracted from pseudorange before using it in
+         * calculating location.
+         */
+        @NonNull public Builder setExcessPathLengthMeters(
+                @FloatRange(from = 0.0f) float excessPathLengthMeters) {
+            mExcessPathLengthMeters = excessPathLengthMeters;
+            mSingleSatCorrectionFlags =
+                    (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_MASK);
+            return this;
+        }
+
+        /** Sets the error estimate (1-sigma) for the Excess path length estimate */
+        @NonNull public Builder setExcessPathLengthUncertaintyMeters(
+                @FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) {
+            mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters;
+            mSingleSatCorrectionFlags =
+                    (byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_UNC_MASK);
+            return this;
+        }
+
+        /** Sets the reflecting plane information */
+        @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) {
+            mReflectingPlane = reflectingPlane;
+            if (reflectingPlane != null) {
+                mSingleSatCorrectionFlags =
+                        (byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK);
+            } else {
+                mSingleSatCorrectionFlags =
+                        (byte) (mSingleSatCorrectionFlags & ~HAS_REFLECTING_PLANE_MASK);
+            }
+            return this;
+        }
+
+        /** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */
+        @NonNull public GnssSingleSatCorrection build() {
+            return new GnssSingleSatCorrection(this);
+        }
+    }
+}
diff --git a/android/location/GnssStatus.java b/android/location/GnssStatus.java
new file mode 100644
index 0000000..4d01cdc
--- /dev/null
+++ b/android/location/GnssStatus.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2016 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.location;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * This class represents the current state of the GNSS engine and is used in conjunction with
+ * {@link GnssStatus.Callback}.
+ *
+ * @see LocationManager#registerGnssStatusCallback
+ * @see GnssStatus.Callback
+ */
+public final class GnssStatus {
+
+    // These must match the definitions in GNSS HAL.
+    //
+    // Note: these constants are also duplicated in GnssStatusCompat.java in the androidx support
+    // library. if adding a constellation, please update that file as well.
+
+    /** Unknown constellation type. */
+    public static final int CONSTELLATION_UNKNOWN = 0;
+    /** Constellation type constant for GPS. */
+    public static final int CONSTELLATION_GPS = 1;
+    /** Constellation type constant for SBAS. */
+    public static final int CONSTELLATION_SBAS = 2;
+    /** Constellation type constant for Glonass. */
+    public static final int CONSTELLATION_GLONASS = 3;
+    /** Constellation type constant for QZSS. */
+    public static final int CONSTELLATION_QZSS = 4;
+    /** Constellation type constant for Beidou. */
+    public static final int CONSTELLATION_BEIDOU = 5;
+    /** Constellation type constant for Galileo. */
+    public static final int CONSTELLATION_GALILEO = 6;
+    /** Constellation type constant for IRNSS. */
+    public static final int CONSTELLATION_IRNSS = 7;
+    /** @hide */
+    public static final int CONSTELLATION_COUNT = 8;
+
+    private static final int SVID_FLAGS_NONE = 0;
+    private static final int SVID_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0);
+    private static final int SVID_FLAGS_HAS_ALMANAC_DATA = (1 << 1);
+    private static final int SVID_FLAGS_USED_IN_FIX = (1 << 2);
+    private static final int SVID_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3);
+    private static final int SVID_FLAGS_HAS_BASEBAND_CN0 = (1 << 4);
+
+    private static final int SVID_SHIFT_WIDTH = 12;
+    private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 8;
+    private static final int CONSTELLATION_TYPE_MASK = 0xf;
+
+    /**
+     * Used for receiving notifications when GNSS events happen.
+     *
+     * @see LocationManager#registerGnssStatusCallback
+     */
+    public static abstract class Callback {
+        /**
+         * Called when GNSS system has started.
+         */
+        public void onStarted() {
+        }
+
+        /**
+         * Called when GNSS system has stopped.
+         */
+        public void onStopped() {
+        }
+
+        /**
+         * Called when the GNSS system has received its first fix since starting.
+         *
+         * @param ttffMillis the time from start to first fix in milliseconds.
+         */
+        public void onFirstFix(int ttffMillis) {
+        }
+
+        /**
+         * Called periodically to report GNSS satellite status.
+         *
+         * @param status the current status of all satellites.
+         */
+        public void onSatelliteStatusChanged(@NonNull GnssStatus status) {
+        }
+    }
+
+    /**
+     * Constellation type.
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
+            CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO, CONSTELLATION_IRNSS})
+    public @interface ConstellationType {
+    }
+
+    /**
+     * Create a GnssStatus that wraps the given arguments without any additional overhead. Callers
+     * are responsible for guaranteeing that the arguments are never modified after calling this
+     * method.
+     *
+     * @hide
+     */
+    @NonNull
+    public static GnssStatus wrap(int svCount, int[] svidWithFlags, float[] cn0DbHzs,
+            float[] elevations, float[] azimuths, float[] carrierFrequencies,
+            float[] basebandCn0DbHzs) {
+        return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths,
+                carrierFrequencies, basebandCn0DbHzs);
+    }
+
+    private final int mSvCount;
+    private final int[] mSvidWithFlags;
+    private final float[] mCn0DbHzs;
+    private final float[] mElevations;
+    private final float[] mAzimuths;
+    private final float[] mCarrierFrequencies;
+    private final float[] mBasebandCn0DbHzs;
+
+    private GnssStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations,
+            float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs) {
+        mSvCount = svCount;
+        mSvidWithFlags = svidWithFlags;
+        mCn0DbHzs = cn0DbHzs;
+        mElevations = elevations;
+        mAzimuths = azimuths;
+        mCarrierFrequencies = carrierFrequencies;
+        mBasebandCn0DbHzs = basebandCn0DbHzs;
+    }
+
+    /**
+     * Gets the total number of satellites in satellite list.
+     */
+    @IntRange(from = 0)
+    public int getSatelliteCount() {
+        return mSvCount;
+    }
+
+    /**
+     * Retrieves the constellation type of the satellite at the specified index.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @ConstellationType
+    public int getConstellationType(@IntRange(from = 0) int satelliteIndex) {
+        return ((mSvidWithFlags[satelliteIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
+                & CONSTELLATION_TYPE_MASK);
+    }
+
+    /**
+     * Gets the identification number for the satellite at the specific index.
+     *
+     * <p>This svid is pseudo-random number for most constellations. It is FCN &amp; OSN number for
+     * Glonass.
+     *
+     * <p>The distinction is made by looking at constellation field
+     * {@link #getConstellationType(int)} Expected values are in the range of:
+     *
+     * <ul>
+     * <li>GPS: 1-32</li>
+     * <li>SBAS: 120-151, 183-192</li>
+     * <li>GLONASS: One of: OSN, or FCN+100
+     * <ul>
+     * <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li>
+     * <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100.
+     * i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li>
+     * </ul></li>
+     * <li>QZSS: 193-200</li>
+     * <li>Galileo: 1-36</li>
+     * <li>Beidou: 1-37</li>
+     * <li>IRNSS: 1-14</li>
+     * </ul>
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @IntRange(from = 1, to = 200)
+    public int getSvid(@IntRange(from = 0) int satelliteIndex) {
+        return mSvidWithFlags[satelliteIndex] >> SVID_SHIFT_WIDTH;
+    }
+
+    /**
+     * Retrieves the carrier-to-noise density at the antenna of the satellite at the specified index
+     * in dB-Hz.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @FloatRange(from = 0, to = 63)
+    public float getCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
+        return mCn0DbHzs[satelliteIndex];
+    }
+
+    /**
+     * Retrieves the elevation of the satellite at the specified index.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @FloatRange(from = -90, to = 90)
+    public float getElevationDegrees(@IntRange(from = 0) int satelliteIndex) {
+        return mElevations[satelliteIndex];
+    }
+
+    /**
+     * Retrieves the azimuth the satellite at the specified index.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @FloatRange(from = 0, to = 360)
+    public float getAzimuthDegrees(@IntRange(from = 0) int satelliteIndex) {
+        return mAzimuths[satelliteIndex];
+    }
+
+    /**
+     * Reports whether the satellite at the specified index has ephemeris data.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    public boolean hasEphemerisData(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_EPHEMERIS_DATA) != 0;
+    }
+
+    /**
+     * Reports whether the satellite at the specified index has almanac data.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    public boolean hasAlmanacData(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_ALMANAC_DATA) != 0;
+    }
+
+    /**
+     * Reports whether the satellite at the specified index was used in the calculation of the most
+     * recent position fix.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    public boolean usedInFix(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_USED_IN_FIX) != 0;
+    }
+
+    /**
+     * Reports whether a valid {@link #getCarrierFrequencyHz(int satelliteIndex)} is available.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    public boolean hasCarrierFrequencyHz(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_CARRIER_FREQUENCY) != 0;
+    }
+
+    /**
+     * Gets the carrier frequency of the signal tracked.
+     *
+     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60
+     * MHz, L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
+     * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
+     *
+     * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two measurements
+     * will be reported for this same satellite, in one all the values related to L1 will be
+     * filled, and in the other all of the values related to L5 will be filled.
+     *
+     * <p>The value is only available if {@link #hasCarrierFrequencyHz(int satelliteIndex)} is
+     * {@code true}.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @FloatRange(from = 0)
+    public float getCarrierFrequencyHz(@IntRange(from = 0) int satelliteIndex) {
+        return mCarrierFrequencies[satelliteIndex];
+    }
+
+    /**
+     * Reports whether a valid {@link #getBasebandCn0DbHz(int satelliteIndex)} is available.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    public boolean hasBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
+        return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_BASEBAND_CN0) != 0;
+    }
+
+    /**
+     * Retrieves the baseband carrier-to-noise density of the satellite at the specified index in
+     * dB-Hz.
+     *
+     * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1
+     */
+    @FloatRange(from = 0, to = 63)
+    public float getBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) {
+        return mBasebandCn0DbHzs[satelliteIndex];
+    }
+
+    /**
+     * Returns the string representation of a constellation type.
+     *
+     * @param constellationType the constellation type.
+     * @return the string representation.
+     * @hide
+     */
+    @NonNull
+    public static String constellationTypeToString(@ConstellationType int constellationType) {
+        switch (constellationType) {
+            case CONSTELLATION_UNKNOWN:
+                return "UNKNOWN";
+            case CONSTELLATION_GPS:
+                return "GPS";
+            case CONSTELLATION_SBAS:
+                return "SBAS";
+            case CONSTELLATION_GLONASS:
+                return "GLONASS";
+            case CONSTELLATION_QZSS:
+                return "QZSS";
+            case CONSTELLATION_BEIDOU:
+                return "BEIDOU";
+            case CONSTELLATION_GALILEO:
+                return "GALILEO";
+            case CONSTELLATION_IRNSS:
+                return "IRNSS";
+            default:
+                return Integer.toString(constellationType);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof GnssStatus)) {
+            return false;
+        }
+
+        GnssStatus that = (GnssStatus) o;
+        return mSvCount == that.mSvCount
+                && Arrays.equals(mSvidWithFlags, that.mSvidWithFlags)
+                && Arrays.equals(mCn0DbHzs, that.mCn0DbHzs)
+                && Arrays.equals(mElevations, that.mElevations)
+                && Arrays.equals(mAzimuths, that.mAzimuths)
+                && Arrays.equals(mCarrierFrequencies, that.mCarrierFrequencies)
+                && Arrays.equals(mBasebandCn0DbHzs, that.mBasebandCn0DbHzs);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(mSvCount);
+        result = 31 * result + Arrays.hashCode(mSvidWithFlags);
+        result = 31 * result + Arrays.hashCode(mCn0DbHzs);
+        return result;
+    }
+
+    /**
+     * Builder class to help create new GnssStatus instances.
+     */
+    public static final class Builder {
+
+        private final ArrayList<GnssSvInfo> mSatellites = new ArrayList<>();
+
+        /**
+         * Adds a new satellite to the Builder.
+         *
+         * @param constellationType one of the CONSTELLATION_* constants
+         * @param svid the space vehicle identifier
+         * @param cn0DbHz carrier-to-noise density at the antenna in dB-Hz
+         * @param elevation satellite elevation in degrees
+         * @param azimuth satellite azimuth in degrees
+         * @param hasEphemeris whether the satellite has ephemeris data
+         * @param hasAlmanac whether the satellite has almanac data
+         * @param usedInFix whether the satellite was used in the most recent location fix
+         * @param hasCarrierFrequency whether carrier frequency data is available
+         * @param carrierFrequency satellite carrier frequency in Hz
+         * @param hasBasebandCn0DbHz whether baseband carrier-to-noise density is available
+         * @param basebandCn0DbHz baseband carrier-to-noise density in dB-Hz
+         */
+        @NonNull
+        public Builder addSatellite(@ConstellationType int constellationType,
+                @IntRange(from = 1, to = 200) int svid,
+                @FloatRange(from = 0, to = 63) float cn0DbHz,
+                @FloatRange(from = -90, to = 90) float elevation,
+                @FloatRange(from = 0, to = 360) float azimuth,
+                boolean hasEphemeris,
+                boolean hasAlmanac,
+                boolean usedInFix,
+                boolean hasCarrierFrequency,
+                @FloatRange(from = 0) float carrierFrequency,
+                boolean hasBasebandCn0DbHz,
+                @FloatRange(from = 0, to = 63) float basebandCn0DbHz) {
+            mSatellites.add(new GnssSvInfo(constellationType, svid, cn0DbHz, elevation, azimuth,
+                    hasEphemeris, hasAlmanac, usedInFix, hasCarrierFrequency, carrierFrequency,
+                    hasBasebandCn0DbHz, basebandCn0DbHz));
+            return this;
+        }
+
+        /**
+         * Clears all satellites in the Builder.
+         */
+        @NonNull
+        public Builder clearSatellites() {
+            mSatellites.clear();
+            return this;
+        }
+
+        /**
+         * Builds a new GnssStatus based on the satellite information in the Builder.
+         */
+        @NonNull
+        public GnssStatus build() {
+            int svCount = mSatellites.size();
+            int[] svidWithFlags = new int[svCount];
+            float[] cn0DbHzs = new float[svCount];
+            float[] elevations = new float[svCount];
+            float[] azimuths = new float[svCount];
+            float[] carrierFrequencies = new float[svCount];
+            float[] basebandCn0DbHzs = new float[svCount];
+
+            for (int i = 0; i < svidWithFlags.length; i++) {
+                svidWithFlags[i] = mSatellites.get(i).mSvidWithFlags;
+            }
+            for (int i = 0; i < cn0DbHzs.length; i++) {
+                cn0DbHzs[i] = mSatellites.get(i).mCn0DbHz;
+            }
+            for (int i = 0; i < elevations.length; i++) {
+                elevations[i] = mSatellites.get(i).mElevation;
+            }
+            for (int i = 0; i < azimuths.length; i++) {
+                azimuths[i] = mSatellites.get(i).mAzimuth;
+            }
+            for (int i = 0; i < carrierFrequencies.length; i++) {
+                carrierFrequencies[i] = mSatellites.get(i).mCarrierFrequency;
+            }
+            for (int i = 0; i < basebandCn0DbHzs.length; i++) {
+                basebandCn0DbHzs[i] = mSatellites.get(i).mBasebandCn0DbHz;
+            }
+
+            return wrap(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths,
+                    carrierFrequencies, basebandCn0DbHzs);
+        }
+    }
+
+    private static class GnssSvInfo {
+
+        private final int mSvidWithFlags;
+        private final float mCn0DbHz;
+        private final float mElevation;
+        private final float mAzimuth;
+        private final float mCarrierFrequency;
+        private final float mBasebandCn0DbHz;
+
+        private GnssSvInfo(int constellationType, int svid, float cn0DbHz,
+                float elevation, float azimuth, boolean hasEphemeris, boolean hasAlmanac,
+                boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency,
+                boolean hasBasebandCn0DbHz, float basebandCn0DbHz) {
+            mSvidWithFlags = (svid << SVID_SHIFT_WIDTH)
+                    | ((constellationType & CONSTELLATION_TYPE_MASK)
+                    << CONSTELLATION_TYPE_SHIFT_WIDTH)
+                    | (hasEphemeris ? SVID_FLAGS_HAS_EPHEMERIS_DATA : SVID_FLAGS_NONE)
+                    | (hasAlmanac ? SVID_FLAGS_HAS_ALMANAC_DATA : SVID_FLAGS_NONE)
+                    | (usedInFix ? SVID_FLAGS_USED_IN_FIX : SVID_FLAGS_NONE)
+                    | (hasCarrierFrequency ? SVID_FLAGS_HAS_CARRIER_FREQUENCY : SVID_FLAGS_NONE)
+                    | (hasBasebandCn0DbHz ? SVID_FLAGS_HAS_BASEBAND_CN0 : SVID_FLAGS_NONE);
+            mCn0DbHz = cn0DbHz;
+            mElevation = elevation;
+            mAzimuth = azimuth;
+            mCarrierFrequency = hasCarrierFrequency ? carrierFrequency : 0;
+            mBasebandCn0DbHz = hasBasebandCn0DbHz ? basebandCn0DbHz : 0;
+        }
+    }
+}
diff --git a/android/location/GpsClock.java b/android/location/GpsClock.java
new file mode 100644
index 0000000..58af6ee
--- /dev/null
+++ b/android/location/GpsClock.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class containing a GPS clock timestamp.
+ * It represents a measurement of the GPS receiver's clock.
+ *
+ * @deprecated use {@link GnssClock} instead.
+ *
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public class GpsClock implements Parcelable {
+
+    // The following enumerations must be in sync with the values declared in gps.h
+
+    /**
+     * The type of the time stored is not available or it is unknown.
+     */
+    public static final byte TYPE_UNKNOWN = 0;
+
+    /**
+     * The source of the time value reported by this class is the 'Local Hardware Clock'.
+     */
+    public static final byte TYPE_LOCAL_HW_TIME = 1;
+
+    /**
+     * The source of the time value reported by this class is the 'GPS time' derived from
+     * satellites (epoch = Jan 6, 1980).
+     */
+    public static final byte TYPE_GPS_TIME = 2;
+
+    private static final short HAS_NO_FLAGS = 0;
+    private static final short HAS_LEAP_SECOND = (1<<0);
+    private static final short HAS_TIME_UNCERTAINTY = (1<<1);
+    private static final short HAS_FULL_BIAS = (1<<2);
+    private static final short HAS_BIAS = (1<<3);
+    private static final short HAS_BIAS_UNCERTAINTY = (1<<4);
+    private static final short HAS_DRIFT = (1<<5);
+    private static final short HAS_DRIFT_UNCERTAINTY = (1<<6);
+
+    // End enumerations in sync with gps.h
+
+    private short mFlags;
+    private short mLeapSecond;
+    private byte mType;
+    private long mTimeInNs;
+    private double mTimeUncertaintyInNs;
+    private long mFullBiasInNs;
+    private double mBiasInNs;
+    private double mBiasUncertaintyInNs;
+    private double mDriftInNsPerSec;
+    private double mDriftUncertaintyInNsPerSec;
+
+    GpsClock() {
+        initialize();
+    }
+
+    /**
+     * Sets all contents to the values stored in the provided object.
+     */
+    public void set(GpsClock clock) {
+        mFlags = clock.mFlags;
+        mLeapSecond = clock.mLeapSecond;
+        mType = clock.mType;
+        mTimeInNs = clock.mTimeInNs;
+        mTimeUncertaintyInNs = clock.mTimeUncertaintyInNs;
+        mFullBiasInNs = clock.mFullBiasInNs;
+        mBiasInNs = clock.mBiasInNs;
+        mBiasUncertaintyInNs = clock.mBiasUncertaintyInNs;
+        mDriftInNsPerSec = clock.mDriftInNsPerSec;
+        mDriftUncertaintyInNsPerSec = clock.mDriftUncertaintyInNsPerSec;
+    }
+
+    /**
+     * Resets all the contents to its original state.
+     */
+    public void reset() {
+        initialize();
+    }
+
+    /**
+     * Gets the type of time reported by {@link #getTimeInNs()}.
+     */
+    public byte getType() {
+        return mType;
+    }
+
+    /**
+     * Sets the type of time reported.
+     */
+    public void setType(byte value) {
+        mType = value;
+    }
+
+    /**
+     * Gets a string representation of the 'type'.
+     * For internal and logging use only.
+     */
+    private String getTypeString() {
+        switch (mType) {
+            case TYPE_UNKNOWN:
+                return "Unknown";
+            case TYPE_GPS_TIME:
+                return "GpsTime";
+            case TYPE_LOCAL_HW_TIME:
+                return "LocalHwClock";
+            default:
+                return "<Invalid:" + mType + ">";
+        }
+    }
+
+    /**
+     * Returns true if {@link #getLeapSecond()} is available, false otherwise.
+     */
+    public boolean hasLeapSecond() {
+        return isFlagSet(HAS_LEAP_SECOND);
+    }
+
+    /**
+     * Gets the leap second associated with the clock's time.
+     * The sign of the value is defined by the following equation:
+     *      utc_time_ns = time_ns + (full_bias_ns + bias_ns) - leap_second * 1,000,000,000
+     *
+     * The value is only available if {@link #hasLeapSecond()} is true.
+     */
+    public short getLeapSecond() {
+        return mLeapSecond;
+    }
+
+    /**
+     * Sets the leap second associated with the clock's time.
+     */
+    public void setLeapSecond(short leapSecond) {
+        setFlag(HAS_LEAP_SECOND);
+        mLeapSecond = leapSecond;
+    }
+
+    /**
+     * Resets the leap second associated with the clock's time.
+     */
+    public void resetLeapSecond() {
+        resetFlag(HAS_LEAP_SECOND);
+        mLeapSecond = Short.MIN_VALUE;
+    }
+
+    /**
+     * Gets the GPS receiver internal clock value in nanoseconds.
+     * This can be either the 'local hardware clock' value ({@link #TYPE_LOCAL_HW_TIME}), or the
+     * current GPS time derived inside GPS receiver ({@link #TYPE_GPS_TIME}).
+     * {@link #getType()} defines the time reported.
+     *
+     * For 'local hardware clock' this value is expected to be monotonically increasing during the
+     * reporting session. The real GPS time can be derived by compensating
+     * {@link #getFullBiasInNs()} (when it is available) from this value.
+     *
+     * For 'GPS time' this value is expected to be the best estimation of current GPS time that GPS
+     * receiver can achieve. {@link #getTimeUncertaintyInNs()} should be available when GPS time is
+     * specified.
+     *
+     * Sub-nanosecond accuracy can be provided by means of {@link #getBiasInNs()}.
+     * The reported time includes {@link #getTimeUncertaintyInNs()}.
+     */
+    public long getTimeInNs() {
+        return mTimeInNs;
+    }
+
+    /**
+     * Sets the GPS receiver internal clock in nanoseconds.
+     */
+    public void setTimeInNs(long timeInNs) {
+        mTimeInNs = timeInNs;
+    }
+
+    /**
+     * Returns true if {@link #getTimeUncertaintyInNs()} is available, false otherwise.
+     */
+    public boolean hasTimeUncertaintyInNs() {
+        return isFlagSet(HAS_TIME_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the clock's time Uncertainty (1-Sigma) in nanoseconds.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The value is only available if {@link #hasTimeUncertaintyInNs()} is true.
+     */
+    public double getTimeUncertaintyInNs() {
+        return mTimeUncertaintyInNs;
+    }
+
+    /**
+     * Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
+     */
+    public void setTimeUncertaintyInNs(double timeUncertaintyInNs) {
+        setFlag(HAS_TIME_UNCERTAINTY);
+        mTimeUncertaintyInNs = timeUncertaintyInNs;
+    }
+
+    /**
+     * Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds.
+     */
+    public void resetTimeUncertaintyInNs() {
+        resetFlag(HAS_TIME_UNCERTAINTY);
+        mTimeUncertaintyInNs = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link @getFullBiasInNs()} is available, false otherwise.
+     */
+    public boolean hasFullBiasInNs() {
+        return isFlagSet(HAS_FULL_BIAS);
+    }
+
+    /**
+     * Gets the difference between hardware clock ({@link #getTimeInNs()}) inside GPS receiver and
+     * the true GPS time since 0000Z, January 6, 1980, in nanoseconds.
+     *
+     * This value is available if {@link #TYPE_LOCAL_HW_TIME} is set, and GPS receiver has solved
+     * the clock for GPS time.
+     * {@link #getBiasUncertaintyInNs()} should be used for quality check.
+     *
+     * The sign of the value is defined by the following equation:
+     *      true time (GPS time) = time_ns + (full_bias_ns + bias_ns)
+     *
+     * The reported full bias includes {@link #getBiasUncertaintyInNs()}.
+     * The value is onl available if {@link #hasFullBiasInNs()} is true.
+     */
+    public long getFullBiasInNs() {
+        return mFullBiasInNs;
+    }
+
+    /**
+     * Sets the full bias in nanoseconds.
+     */
+    public void setFullBiasInNs(long value) {
+        setFlag(HAS_FULL_BIAS);
+        mFullBiasInNs = value;
+    }
+
+    /**
+     * Resets the full bias in nanoseconds.
+     */
+    public void resetFullBiasInNs() {
+        resetFlag(HAS_FULL_BIAS);
+        mFullBiasInNs = Long.MIN_VALUE;
+    }
+
+    /**
+     * Returns true if {@link #getBiasInNs()} is available, false otherwise.
+     */
+    public boolean hasBiasInNs() {
+        return isFlagSet(HAS_BIAS);
+    }
+
+    /**
+     * Gets the clock's sub-nanosecond bias.
+     * The reported bias includes {@link #getBiasUncertaintyInNs()}.
+     *
+     * The value is only available if {@link #hasBiasInNs()} is true.
+     */
+    public double getBiasInNs() {
+        return mBiasInNs;
+    }
+
+    /**
+     * Sets the sub-nanosecond bias.
+     */
+    public void setBiasInNs(double biasInNs) {
+        setFlag(HAS_BIAS);
+        mBiasInNs = biasInNs;
+    }
+
+    /**
+     * Resets the clock's Bias in nanoseconds.
+     */
+    public void resetBiasInNs() {
+        resetFlag(HAS_BIAS);
+        mBiasInNs = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getBiasUncertaintyInNs()} is available, false otherwise.
+     */
+    public boolean hasBiasUncertaintyInNs() {
+        return isFlagSet(HAS_BIAS_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
+     *
+     * The value is only available if {@link #hasBiasUncertaintyInNs()} is true.
+     */
+    public double getBiasUncertaintyInNs() {
+        return mBiasUncertaintyInNs;
+    }
+
+    /**
+     * Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
+     */
+    public void setBiasUncertaintyInNs(double biasUncertaintyInNs) {
+        setFlag(HAS_BIAS_UNCERTAINTY);
+        mBiasUncertaintyInNs = biasUncertaintyInNs;
+    }
+
+    /**
+     * Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds.
+     */
+    public void resetBiasUncertaintyInNs() {
+        resetFlag(HAS_BIAS_UNCERTAINTY);
+        mBiasUncertaintyInNs = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getDriftInNsPerSec()} is available, false otherwise.
+     */
+    public boolean hasDriftInNsPerSec() {
+        return isFlagSet(HAS_DRIFT);
+    }
+
+    /**
+     * Gets the clock's Drift in nanoseconds per second.
+     * A positive value indicates that the frequency is higher than the nominal frequency.
+     * The reported drift includes {@link #getDriftUncertaintyInNsPerSec()}.
+     *
+     * The value is only available if {@link #hasDriftInNsPerSec()} is true.
+     */
+    public double getDriftInNsPerSec() {
+        return mDriftInNsPerSec;
+    }
+
+    /**
+     * Sets the clock's Drift in nanoseconds per second.
+     */
+    public void setDriftInNsPerSec(double driftInNsPerSec) {
+        setFlag(HAS_DRIFT);
+        mDriftInNsPerSec = driftInNsPerSec;
+    }
+
+    /**
+     * Resets the clock's Drift in nanoseconds per second.
+     */
+    public void resetDriftInNsPerSec() {
+        resetFlag(HAS_DRIFT);
+        mDriftInNsPerSec = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getDriftUncertaintyInNsPerSec()} is available, false otherwise.
+     */
+    public boolean hasDriftUncertaintyInNsPerSec() {
+        return isFlagSet(HAS_DRIFT_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+     *
+     * The value is only available if {@link #hasDriftUncertaintyInNsPerSec()} is true.
+     */
+    public double getDriftUncertaintyInNsPerSec() {
+        return mDriftUncertaintyInNsPerSec;
+    }
+
+    /**
+     * Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+     */
+    public void setDriftUncertaintyInNsPerSec(double driftUncertaintyInNsPerSec) {
+        setFlag(HAS_DRIFT_UNCERTAINTY);
+        mDriftUncertaintyInNsPerSec = driftUncertaintyInNsPerSec;
+    }
+
+    /**
+     * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second.
+     */
+    public void resetDriftUncertaintyInNsPerSec() {
+        resetFlag(HAS_DRIFT_UNCERTAINTY);
+        mDriftUncertaintyInNsPerSec = Double.NaN;
+    }
+
+    public static final @android.annotation.NonNull Creator<GpsClock> CREATOR = new Creator<GpsClock>() {
+        @Override
+        public GpsClock createFromParcel(Parcel parcel) {
+            GpsClock gpsClock = new GpsClock();
+
+            gpsClock.mFlags = (short) parcel.readInt();
+            gpsClock.mLeapSecond = (short) parcel.readInt();
+            gpsClock.mType = parcel.readByte();
+            gpsClock.mTimeInNs = parcel.readLong();
+            gpsClock.mTimeUncertaintyInNs = parcel.readDouble();
+            gpsClock.mFullBiasInNs = parcel.readLong();
+            gpsClock.mBiasInNs = parcel.readDouble();
+            gpsClock.mBiasUncertaintyInNs = parcel.readDouble();
+            gpsClock.mDriftInNsPerSec = parcel.readDouble();
+            gpsClock.mDriftUncertaintyInNsPerSec = parcel.readDouble();
+
+            return gpsClock;
+        }
+
+        @Override
+        public GpsClock[] newArray(int size) {
+            return new GpsClock[size];
+        }
+    };
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mFlags);
+        parcel.writeInt(mLeapSecond);
+        parcel.writeByte(mType);
+        parcel.writeLong(mTimeInNs);
+        parcel.writeDouble(mTimeUncertaintyInNs);
+        parcel.writeLong(mFullBiasInNs);
+        parcel.writeDouble(mBiasInNs);
+        parcel.writeDouble(mBiasUncertaintyInNs);
+        parcel.writeDouble(mDriftInNsPerSec);
+        parcel.writeDouble(mDriftUncertaintyInNsPerSec);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        final String format = "   %-15s = %s\n";
+        final String formatWithUncertainty = "   %-15s = %-25s   %-26s = %s\n";
+        StringBuilder builder = new StringBuilder("GpsClock:\n");
+
+        builder.append(String.format(format, "Type", getTypeString()));
+
+        builder.append(String.format(format, "LeapSecond", hasLeapSecond() ? mLeapSecond : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "TimeInNs",
+                mTimeInNs,
+                "TimeUncertaintyInNs",
+                hasTimeUncertaintyInNs() ? mTimeUncertaintyInNs : null));
+
+        builder.append(String.format(
+                format,
+                "FullBiasInNs",
+                hasFullBiasInNs() ? mFullBiasInNs : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "BiasInNs",
+                hasBiasInNs() ? mBiasInNs : null,
+                "BiasUncertaintyInNs",
+                hasBiasUncertaintyInNs() ? mBiasUncertaintyInNs : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "DriftInNsPerSec",
+                hasDriftInNsPerSec() ? mDriftInNsPerSec : null,
+                "DriftUncertaintyInNsPerSec",
+                hasDriftUncertaintyInNsPerSec() ? mDriftUncertaintyInNsPerSec : null));
+
+        return builder.toString();
+    }
+
+    private void initialize() {
+        mFlags = HAS_NO_FLAGS;
+        resetLeapSecond();
+        setType(TYPE_UNKNOWN);
+        setTimeInNs(Long.MIN_VALUE);
+        resetTimeUncertaintyInNs();
+        resetFullBiasInNs();
+        resetBiasInNs();
+        resetBiasUncertaintyInNs();
+        resetDriftInNsPerSec();
+        resetDriftUncertaintyInNsPerSec();
+    }
+
+    private void setFlag(short flag) {
+        mFlags |= flag;
+    }
+
+    private void resetFlag(short flag) {
+        mFlags &= ~flag;
+    }
+
+    private boolean isFlagSet(short flag) {
+        return (mFlags & flag) == flag;
+    }
+}
diff --git a/android/location/GpsMeasurement.java b/android/location/GpsMeasurement.java
new file mode 100644
index 0000000..c2ab4ab
--- /dev/null
+++ b/android/location/GpsMeasurement.java
@@ -0,0 +1,1418 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class representing a GPS satellite measurement, containing raw and computed information.
+ *
+ * @deprecated use {@link GnssMeasurement} instead.
+ *
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public class GpsMeasurement implements Parcelable {
+    private int mFlags;
+    private byte mPrn;
+    private double mTimeOffsetInNs;
+    private short mState;
+    private long mReceivedGpsTowInNs;
+    private long mReceivedGpsTowUncertaintyInNs;
+    private double mCn0InDbHz;
+    private double mPseudorangeRateInMetersPerSec;
+    private double mPseudorangeRateUncertaintyInMetersPerSec;
+    private short mAccumulatedDeltaRangeState;
+    private double mAccumulatedDeltaRangeInMeters;
+    private double mAccumulatedDeltaRangeUncertaintyInMeters;
+    private double mPseudorangeInMeters;
+    private double mPseudorangeUncertaintyInMeters;
+    private double mCodePhaseInChips;
+    private double mCodePhaseUncertaintyInChips;
+    private float mCarrierFrequencyInHz;
+    private long mCarrierCycles;
+    private double mCarrierPhase;
+    private double mCarrierPhaseUncertainty;
+    private byte mLossOfLock;
+    private int mBitNumber;
+    private short mTimeFromLastBitInMs;
+    private double mDopplerShiftInHz;
+    private double mDopplerShiftUncertaintyInHz;
+    private byte mMultipathIndicator;
+    private double mSnrInDb;
+    private double mElevationInDeg;
+    private double mElevationUncertaintyInDeg;
+    private double mAzimuthInDeg;
+    private double mAzimuthUncertaintyInDeg;
+    private boolean mUsedInFix;
+
+    // The following enumerations must be in sync with the values declared in gps.h
+
+    private static final int HAS_NO_FLAGS = 0;
+    private static final int HAS_SNR = (1<<0);
+    private static final int HAS_ELEVATION = (1<<1);
+    private static final int HAS_ELEVATION_UNCERTAINTY = (1<<2);
+    private static final int HAS_AZIMUTH = (1<<3);
+    private static final int HAS_AZIMUTH_UNCERTAINTY = (1<<4);
+    private static final int HAS_PSEUDORANGE = (1<<5);
+    private static final int HAS_PSEUDORANGE_UNCERTAINTY = (1<<6);
+    private static final int HAS_CODE_PHASE = (1<<7);
+    private static final int HAS_CODE_PHASE_UNCERTAINTY = (1<<8);
+    private static final int HAS_CARRIER_FREQUENCY = (1<<9);
+    private static final int HAS_CARRIER_CYCLES = (1<<10);
+    private static final int HAS_CARRIER_PHASE = (1<<11);
+    private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
+    private static final int HAS_BIT_NUMBER = (1<<13);
+    private static final int HAS_TIME_FROM_LAST_BIT = (1<<14);
+    private static final int HAS_DOPPLER_SHIFT = (1<<15);
+    private static final int HAS_DOPPLER_SHIFT_UNCERTAINTY = (1<<16);
+    private static final int HAS_USED_IN_FIX = (1<<17);
+    private static final int GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18);
+
+    /**
+     * The indicator is not available or it is unknown.
+     */
+    public static final byte LOSS_OF_LOCK_UNKNOWN = 0;
+
+    /**
+     * The measurement does not present any indication of 'loss of lock'.
+     */
+    public static final byte LOSS_OF_LOCK_OK = 1;
+
+    /**
+     * 'Loss of lock' detected between the previous and current observation: cycle slip possible.
+     */
+    public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2;
+
+    /**
+     * The indicator is not available or it is unknown.
+     */
+    public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0;
+
+    /**
+     * The measurement has been indicated to use multi-path.
+     */
+    public static final byte MULTIPATH_INDICATOR_DETECTED = 1;
+
+    /**
+     * The measurement has been indicated not tu use multi-path.
+     */
+    public static final byte MULTIPATH_INDICATOR_NOT_USED = 2;
+
+    /**
+     * The state of GPS receiver the measurement is invalid or unknown.
+     */
+    public static final short STATE_UNKNOWN = 0;
+
+    /**
+     * The state of the GPS receiver is ranging code lock.
+     */
+    public static final short STATE_CODE_LOCK = (1<<0);
+
+    /**
+     * The state of the GPS receiver is in bit sync.
+     */
+    public static final short STATE_BIT_SYNC = (1<<1);
+
+    /**
+     *The state of the GPS receiver is in sub-frame sync.
+     */
+    public static final short STATE_SUBFRAME_SYNC = (1<<2);
+
+    /**
+     * The state of the GPS receiver has TOW decoded.
+     */
+    public static final short STATE_TOW_DECODED = (1<<3);
+
+    /**
+     * The state of the GPS receiver contains millisecond ambiguity.
+     */
+    public static final short STATE_MSEC_AMBIGUOUS = (1<<4);
+
+    /**
+     * All the GPS receiver state flags.
+     */
+    private static final short STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
+            | STATE_TOW_DECODED | STATE_MSEC_AMBIGUOUS;
+
+    /**
+     * The state of the 'Accumulated Delta Range' is invalid or unknown.
+     */
+    public static final short ADR_STATE_UNKNOWN = 0;
+
+    /**
+     * The state of the 'Accumulated Delta Range' is valid.
+     */
+    public static final short ADR_STATE_VALID = (1<<0);
+
+    /**
+     * The state of the 'Accumulated Delta Range' has detected a reset.
+     */
+    public static final short ADR_STATE_RESET = (1<<1);
+
+    /**
+     * The state of the 'Accumulated Delta Range' has a cycle slip detected.
+     */
+    public static final short ADR_STATE_CYCLE_SLIP = (1<<2);
+
+    /**
+     * All the 'Accumulated Delta Range' flags.
+     */
+    private static final short ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
+
+    // End enumerations in sync with gps.h
+
+    GpsMeasurement() {
+        initialize();
+    }
+
+    /**
+     * Sets all contents to the values stored in the provided object.
+     */
+    public void set(GpsMeasurement measurement) {
+        mFlags = measurement.mFlags;
+        mPrn = measurement.mPrn;
+        mTimeOffsetInNs = measurement.mTimeOffsetInNs;
+        mState = measurement.mState;
+        mReceivedGpsTowInNs = measurement.mReceivedGpsTowInNs;
+        mReceivedGpsTowUncertaintyInNs = measurement.mReceivedGpsTowUncertaintyInNs;
+        mCn0InDbHz = measurement.mCn0InDbHz;
+        mPseudorangeRateInMetersPerSec = measurement.mPseudorangeRateInMetersPerSec;
+        mPseudorangeRateUncertaintyInMetersPerSec =
+                measurement.mPseudorangeRateUncertaintyInMetersPerSec;
+        mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
+        mAccumulatedDeltaRangeInMeters = measurement.mAccumulatedDeltaRangeInMeters;
+        mAccumulatedDeltaRangeUncertaintyInMeters =
+                measurement.mAccumulatedDeltaRangeUncertaintyInMeters;
+        mPseudorangeInMeters = measurement.mPseudorangeInMeters;
+        mPseudorangeUncertaintyInMeters = measurement.mPseudorangeUncertaintyInMeters;
+        mCodePhaseInChips = measurement.mCodePhaseInChips;
+        mCodePhaseUncertaintyInChips = measurement.mCodePhaseUncertaintyInChips;
+        mCarrierFrequencyInHz = measurement.mCarrierFrequencyInHz;
+        mCarrierCycles = measurement.mCarrierCycles;
+        mCarrierPhase = measurement.mCarrierPhase;
+        mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
+        mLossOfLock = measurement.mLossOfLock;
+        mBitNumber = measurement.mBitNumber;
+        mTimeFromLastBitInMs = measurement.mTimeFromLastBitInMs;
+        mDopplerShiftInHz = measurement.mDopplerShiftInHz;
+        mDopplerShiftUncertaintyInHz = measurement.mDopplerShiftUncertaintyInHz;
+        mMultipathIndicator = measurement.mMultipathIndicator;
+        mSnrInDb = measurement.mSnrInDb;
+        mElevationInDeg = measurement.mElevationInDeg;
+        mElevationUncertaintyInDeg = measurement.mElevationUncertaintyInDeg;
+        mAzimuthInDeg = measurement.mAzimuthInDeg;
+        mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg;
+        mUsedInFix = measurement.mUsedInFix;
+    }
+
+    /**
+     * Resets all the contents to its original state.
+     */
+    public void reset() {
+        initialize();
+    }
+
+    /**
+     * Gets the Pseudo-random number (PRN).
+     * Range: [1, 32]
+     */
+    public byte getPrn() {
+        return mPrn;
+    }
+
+    /**
+     * Sets the Pseud-random number (PRN).
+     */
+    public void setPrn(byte value) {
+        mPrn = value;
+    }
+
+    /**
+     * Gets the time offset at which the measurement was taken in nanoseconds.
+     * The reference receiver's time is specified by {@link GpsClock#getTimeInNs()} and should be
+     * interpreted in the same way as indicated by {@link GpsClock#getType()}.
+     *
+     * The sign of this value is given by the following equation:
+     *      measurement time = time_ns + time_offset_ns
+     *
+     * The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
+     * accuracy.
+     */
+    public double getTimeOffsetInNs() {
+        return mTimeOffsetInNs;
+    }
+
+    /**
+     * Sets the time offset at which the measurement was taken in nanoseconds.
+     */
+    public void setTimeOffsetInNs(double value) {
+        mTimeOffsetInNs = value;
+    }
+
+    /**
+     * Gets per-satellite sync state.
+     * It represents the current sync state for the associated satellite.
+     *
+     * This value helps interpret {@link #getReceivedGpsTowInNs()}.
+     */
+    public short getState() {
+        return mState;
+    }
+
+    /**
+     * Sets the sync state.
+     */
+    public void setState(short value) {
+        mState = value;
+    }
+
+    /**
+     * Gets a string representation of the 'sync state'.
+     * For internal and logging use only.
+     */
+    private String getStateString() {
+        if (mState == STATE_UNKNOWN) {
+            return "Unknown";
+        }
+        StringBuilder builder = new StringBuilder();
+        if ((mState & STATE_CODE_LOCK) == STATE_CODE_LOCK) {
+            builder.append("CodeLock|");
+        }
+        if ((mState & STATE_BIT_SYNC) == STATE_BIT_SYNC) {
+            builder.append("BitSync|");
+        }
+        if ((mState & STATE_SUBFRAME_SYNC) == STATE_SUBFRAME_SYNC) {
+            builder.append("SubframeSync|");
+        }
+        if ((mState & STATE_TOW_DECODED) == STATE_TOW_DECODED) {
+            builder.append("TowDecoded|");
+        }
+        if ((mState & STATE_MSEC_AMBIGUOUS) == STATE_MSEC_AMBIGUOUS) {
+            builder.append("MsecAmbiguous");
+        }
+        int remainingStates = mState & ~STATE_ALL;
+        if (remainingStates > 0) {
+            builder.append("Other(");
+            builder.append(Integer.toBinaryString(remainingStates));
+            builder.append(")|");
+        }
+        builder.deleteCharAt(builder.length() - 1);
+        return builder.toString();
+    }
+
+    /**
+     * Gets the received GPS Time-of-Week at the measurement time, in nanoseconds.
+     * The value is relative to the beginning of the current GPS week.
+     *
+     * Given {@link #getState()} of the GPS receiver, the range of this field can be:
+     *      Searching           : [ 0           ]   : {@link #STATE_UNKNOWN} is set
+     *      Ranging code lock   : [ 0    1 ms   ]   : {@link #STATE_CODE_LOCK} is set
+     *      Bit sync            : [ 0   20 ms   ]   : {@link #STATE_BIT_SYNC} is set
+     *      Subframe sync       : [ 0    6 ms   ]   : {@link #STATE_SUBFRAME_SYNC} is set
+     *      TOW decoded         : [ 0    1 week ]   : {@link #STATE_TOW_DECODED} is set
+     */
+    public long getReceivedGpsTowInNs() {
+        return mReceivedGpsTowInNs;
+    }
+
+    /**
+     * Sets the received GPS time-of-week in nanoseconds.
+     */
+    public void setReceivedGpsTowInNs(long value) {
+        mReceivedGpsTowInNs = value;
+    }
+
+    /**
+     * Gets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
+     */
+    public long getReceivedGpsTowUncertaintyInNs() {
+        return mReceivedGpsTowUncertaintyInNs;
+    }
+
+    /**
+     * Sets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
+     */
+    public void setReceivedGpsTowUncertaintyInNs(long value) {
+        mReceivedGpsTowUncertaintyInNs = value;
+    }
+
+    /**
+     * Gets the Carrier-to-noise density in dB-Hz.
+     * Range: [0, 63].
+     *
+     * The value contains the measured C/N0 for the signal at the antenna input.
+     */
+    public double getCn0InDbHz() {
+        return mCn0InDbHz;
+    }
+
+    /**
+     * Sets the carrier-to-noise density in dB-Hz.
+     */
+    public void setCn0InDbHz(double value) {
+        mCn0InDbHz = value;
+    }
+
+    /**
+     * Gets the Pseudorange rate at the timestamp in m/s.
+     * The reported value includes {@link #getPseudorangeRateUncertaintyInMetersPerSec()}.
+     *
+     * The correction of a given Pseudorange Rate value includes corrections from receiver and
+     * satellite clock frequency errors.
+     * {@link #isPseudorangeRateCorrected()} identifies the type of value reported.
+     *
+     * A positive 'uncorrected' value indicates that the SV is moving away from the receiver.
+     * The sign of the 'uncorrected' Pseudorange Rate and its relation to the sign of
+     * {@link #getDopplerShiftInHz()} is given by the equation:
+     *      pseudorange rate = -k * doppler shift   (where k is a constant)
+     */
+    public double getPseudorangeRateInMetersPerSec() {
+        return mPseudorangeRateInMetersPerSec;
+    }
+
+    /**
+     * Sets the pseudorange rate at the timestamp in m/s.
+     */
+    public void setPseudorangeRateInMetersPerSec(double value) {
+        mPseudorangeRateInMetersPerSec = value;
+    }
+
+    /**
+     * See {@link #getPseudorangeRateInMetersPerSec()} for more details.
+     *
+     * @return {@code true} if {@link #getPseudorangeRateInMetersPerSec()} contains a corrected
+     *         value, {@code false} if it contains an uncorrected value.
+     */
+    public boolean isPseudorangeRateCorrected() {
+        return !isFlagSet(GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE);
+    }
+
+    /**
+     * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
+     * The uncertainty is represented as an absolute (single sided) value.
+     */
+    public double getPseudorangeRateUncertaintyInMetersPerSec() {
+        return mPseudorangeRateUncertaintyInMetersPerSec;
+    }
+
+    /**
+     * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
+     */
+    public void setPseudorangeRateUncertaintyInMetersPerSec(double value) {
+        mPseudorangeRateUncertaintyInMetersPerSec = value;
+    }
+
+    /**
+     * Gets 'Accumulated Delta Range' state.
+     * It indicates whether {@link #getAccumulatedDeltaRangeInMeters()} is reset or there is a
+     * cycle slip (indicating 'loss of lock').
+     */
+    public short getAccumulatedDeltaRangeState() {
+        return mAccumulatedDeltaRangeState;
+    }
+
+    /**
+     * Sets the 'Accumulated Delta Range' state.
+     */
+    public void setAccumulatedDeltaRangeState(short value) {
+        mAccumulatedDeltaRangeState = value;
+    }
+
+    /**
+     * Gets a string representation of the 'Accumulated Delta Range state'.
+     * For internal and logging use only.
+     */
+    private String getAccumulatedDeltaRangeStateString() {
+        if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
+            return "Unknown";
+        }
+        StringBuilder builder = new StringBuilder();
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
+            builder.append("Valid|");
+        }
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
+            builder.append("Reset|");
+        }
+        if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
+            builder.append("CycleSlip|");
+        }
+        int remainingStates = mAccumulatedDeltaRangeState & ~ADR_ALL;
+        if (remainingStates > 0) {
+            builder.append("Other(");
+            builder.append(Integer.toBinaryString(remainingStates));
+            builder.append(")|");
+        }
+        builder.deleteCharAt(builder.length() - 1);
+        return builder.toString();
+    }
+
+    /**
+     * Gets the accumulated delta range since the last channel reset, in meters.
+     * The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyInMeters()}.
+     *
+     * The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     *
+     * A positive value indicates that the SV is moving away from the receiver.
+     * The sign of {@link #getAccumulatedDeltaRangeInMeters()} and its relation to the sign of
+     * {@link #getCarrierPhase()} is given by the equation:
+     *          accumulated delta range = -k * carrier phase    (where k is a constant)
+     */
+    public double getAccumulatedDeltaRangeInMeters() {
+        return mAccumulatedDeltaRangeInMeters;
+    }
+
+    /**
+     * Sets the accumulated delta range in meters.
+     */
+    public void setAccumulatedDeltaRangeInMeters(double value) {
+        mAccumulatedDeltaRangeInMeters = value;
+    }
+
+    /**
+     * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     */
+    public double getAccumulatedDeltaRangeUncertaintyInMeters() {
+        return mAccumulatedDeltaRangeUncertaintyInMeters;
+    }
+
+    /**
+     * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
+     *
+     * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
+     */
+    public void setAccumulatedDeltaRangeUncertaintyInMeters(double value) {
+        mAccumulatedDeltaRangeUncertaintyInMeters = value;
+    }
+
+    /**
+     * Returns true if {@link #getPseudorangeInMeters()} is available, false otherwise.
+     */
+    public boolean hasPseudorangeInMeters() {
+        return isFlagSet(HAS_PSEUDORANGE);
+    }
+
+    /**
+     * Gets the best derived pseudorange by the chipset, in meters.
+     * The reported pseudorange includes {@link #getPseudorangeUncertaintyInMeters()}.
+     *
+     * The value is only available if {@link #hasPseudorangeInMeters()} is true.
+     */
+    public double getPseudorangeInMeters() {
+        return mPseudorangeInMeters;
+    }
+
+    /**
+     * Sets the Pseudo-range in meters.
+     */
+    public void setPseudorangeInMeters(double value) {
+        setFlag(HAS_PSEUDORANGE);
+        mPseudorangeInMeters = value;
+    }
+
+    /**
+     * Resets the Pseudo-range in meters.
+     */
+    public void resetPseudorangeInMeters() {
+        resetFlag(HAS_PSEUDORANGE);
+        mPseudorangeInMeters = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getPseudorangeUncertaintyInMeters()} is available, false otherwise.
+     */
+    public boolean hasPseudorangeUncertaintyInMeters() {
+        return isFlagSet(HAS_PSEUDORANGE_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the pseudorange's uncertainty (1-Sigma) in meters.
+     * The value contains the 'pseudorange' and 'clock' uncertainty in it.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The value is only available if {@link #hasPseudorangeUncertaintyInMeters()} is true.
+     */
+    public double getPseudorangeUncertaintyInMeters() {
+        return mPseudorangeUncertaintyInMeters;
+    }
+
+    /**
+     * Sets the pseudo-range's uncertainty (1-Sigma) in meters.
+     */
+    public void setPseudorangeUncertaintyInMeters(double value) {
+        setFlag(HAS_PSEUDORANGE_UNCERTAINTY);
+        mPseudorangeUncertaintyInMeters = value;
+    }
+
+    /**
+     * Resets the pseudo-range's uncertainty (1-Sigma) in meters.
+     */
+    public void resetPseudorangeUncertaintyInMeters() {
+        resetFlag(HAS_PSEUDORANGE_UNCERTAINTY);
+        mPseudorangeUncertaintyInMeters = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getCodePhaseInChips()} is available, false otherwise.
+     */
+    public boolean hasCodePhaseInChips() {
+        return isFlagSet(HAS_CODE_PHASE);
+    }
+
+    /**
+     * Gets the fraction of the current C/A code cycle.
+     * Range: [0, 1023]
+     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
+     * The reported code-phase includes {@link #getCodePhaseUncertaintyInChips()}.
+     *
+     * The value is only available if {@link #hasCodePhaseInChips()} is true.
+     */
+    public double getCodePhaseInChips() {
+        return mCodePhaseInChips;
+    }
+
+    /**
+     * Sets the Code-phase in chips.
+     */
+    public void setCodePhaseInChips(double value) {
+        setFlag(HAS_CODE_PHASE);
+        mCodePhaseInChips = value;
+    }
+
+    /**
+     * Resets the Code-phase in chips.
+     */
+    public void resetCodePhaseInChips() {
+        resetFlag(HAS_CODE_PHASE);
+        mCodePhaseInChips = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getCodePhaseUncertaintyInChips()} is available, false otherwise.
+     */
+    public boolean hasCodePhaseUncertaintyInChips() {
+        return isFlagSet(HAS_CODE_PHASE_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the code-phase's uncertainty (1-Sigma) as a fraction of chips.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The value is only available if {@link #hasCodePhaseUncertaintyInChips()} is true.
+     */
+    public double getCodePhaseUncertaintyInChips() {
+        return mCodePhaseUncertaintyInChips;
+    }
+
+    /**
+     * Sets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
+     */
+    public void setCodePhaseUncertaintyInChips(double value) {
+        setFlag(HAS_CODE_PHASE_UNCERTAINTY);
+        mCodePhaseUncertaintyInChips = value;
+    }
+
+    /**
+     * Resets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
+     */
+    public void resetCodePhaseUncertaintyInChips() {
+        resetFlag(HAS_CODE_PHASE_UNCERTAINTY);
+        mCodePhaseUncertaintyInChips = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getCarrierFrequencyInHz()} is available, false otherwise.
+     */
+    public boolean hasCarrierFrequencyInHz() {
+        return isFlagSet(HAS_CARRIER_FREQUENCY);
+    }
+
+    /**
+     * Gets the carrier frequency at which codes and messages are modulated, it can be L1 or L2.
+     * If the field is not set, the carrier frequency corresponds to L1.
+     *
+     * The value is only available if {@link #hasCarrierFrequencyInHz()} is true.
+     */
+    public float getCarrierFrequencyInHz() {
+        return mCarrierFrequencyInHz;
+    }
+
+    /**
+     * Sets the Carrier frequency (L1 or L2) in Hz.
+     */
+    public void setCarrierFrequencyInHz(float carrierFrequencyInHz) {
+        setFlag(HAS_CARRIER_FREQUENCY);
+        mCarrierFrequencyInHz = carrierFrequencyInHz;
+    }
+
+    /**
+     * Resets the Carrier frequency (L1 or L2) in Hz.
+     */
+    public void resetCarrierFrequencyInHz() {
+        resetFlag(HAS_CARRIER_FREQUENCY);
+        mCarrierFrequencyInHz = Float.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getCarrierCycles()} is available, false otherwise.
+     */
+    public boolean hasCarrierCycles() {
+        return isFlagSet(HAS_CARRIER_CYCLES);
+    }
+
+    /**
+     * The number of full carrier cycles between the satellite and the receiver.
+     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
+     *
+     * The value is only available if {@link #hasCarrierCycles()} is true.
+     */
+    public long getCarrierCycles() {
+        return mCarrierCycles;
+    }
+
+    /**
+     * Sets the number of full carrier cycles between the satellite and the receiver.
+     */
+    public void setCarrierCycles(long value) {
+        setFlag(HAS_CARRIER_CYCLES);
+        mCarrierCycles = value;
+    }
+
+    /**
+     * Resets the number of full carrier cycles between the satellite and the receiver.
+     */
+    public void resetCarrierCycles() {
+        resetFlag(HAS_CARRIER_CYCLES);
+        mCarrierCycles = Long.MIN_VALUE;
+    }
+
+    /**
+     * Returns true if {@link #getCarrierPhase()} is available, false otherwise.
+     */
+    public boolean hasCarrierPhase() {
+        return isFlagSet(HAS_CARRIER_PHASE);
+    }
+
+    /**
+     * Gets the RF phase detected by the receiver.
+     * Range: [0.0, 1.0].
+     * This is usually the fractional part of the complete carrier phase measurement.
+     *
+     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
+     * The reported carrier-phase includes {@link #getCarrierPhaseUncertainty()}.
+     *
+     * The value is only available if {@link #hasCarrierPhase()} is true.
+     */
+    public double getCarrierPhase() {
+        return mCarrierPhase;
+    }
+
+    /**
+     * Sets the RF phase detected by the receiver.
+     */
+    public void setCarrierPhase(double value) {
+        setFlag(HAS_CARRIER_PHASE);
+        mCarrierPhase = value;
+    }
+
+    /**
+     * Resets the RF phase detected by the receiver.
+     */
+    public void resetCarrierPhase() {
+        resetFlag(HAS_CARRIER_PHASE);
+        mCarrierPhase = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getCarrierPhaseUncertainty()} is available, false otherwise.
+     */
+    public boolean hasCarrierPhaseUncertainty() {
+        return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the carrier-phase's uncertainty (1-Sigma).
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The value is only available if {@link #hasCarrierPhaseUncertainty()} is true.
+     */
+    public double getCarrierPhaseUncertainty() {
+        return mCarrierPhaseUncertainty;
+    }
+
+    /**
+     * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
+     */
+    public void setCarrierPhaseUncertainty(double value) {
+        setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
+        mCarrierPhaseUncertainty = value;
+    }
+
+    /**
+     * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
+     */
+    public void resetCarrierPhaseUncertainty() {
+        resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
+        mCarrierPhaseUncertainty = Double.NaN;
+    }
+
+    /**
+     * Gets a value indicating the 'loss of lock' state of the event.
+     */
+    public byte getLossOfLock() {
+        return mLossOfLock;
+    }
+
+    /**
+     * Sets the 'loss of lock' status.
+     */
+    public void setLossOfLock(byte value) {
+        mLossOfLock = value;
+    }
+
+    /**
+     * Gets a string representation of the 'loss of lock'.
+     * For internal and logging use only.
+     */
+    private String getLossOfLockString() {
+        switch (mLossOfLock) {
+            case LOSS_OF_LOCK_UNKNOWN:
+                return "Unknown";
+            case LOSS_OF_LOCK_OK:
+                return "Ok";
+            case LOSS_OF_LOCK_CYCLE_SLIP:
+                return "CycleSlip";
+            default:
+                return "<Invalid:" + mLossOfLock + ">";
+        }
+    }
+
+    /**
+     * Returns true if {@link #getBitNumber()} is available, false otherwise.
+     */
+    public boolean hasBitNumber() {
+        return isFlagSet(HAS_BIT_NUMBER);
+    }
+
+    /**
+     * Gets the number of GPS bits transmitted since Sat-Sun midnight (GPS week).
+     *
+     * The value is only available if {@link #hasBitNumber()} is true.
+     */
+    public int getBitNumber() {
+        return mBitNumber;
+    }
+
+    /**
+     * Sets the bit number within the broadcast frame.
+     */
+    public void setBitNumber(int bitNumber) {
+        setFlag(HAS_BIT_NUMBER);
+        mBitNumber = bitNumber;
+    }
+
+    /**
+     * Resets the bit number within the broadcast frame.
+     */
+    public void resetBitNumber() {
+        resetFlag(HAS_BIT_NUMBER);
+        mBitNumber = Integer.MIN_VALUE;
+    }
+
+    /**
+     * Returns true if {@link #getTimeFromLastBitInMs()} is available, false otherwise.
+     */
+    public boolean hasTimeFromLastBitInMs() {
+        return isFlagSet(HAS_TIME_FROM_LAST_BIT);
+    }
+
+    /**
+     * Gets the elapsed time since the last received bit in milliseconds.
+     * Range: [0, 20].
+     *
+     * The value is only available if {@link #hasTimeFromLastBitInMs()} is true.
+     */
+    public short getTimeFromLastBitInMs() {
+        return mTimeFromLastBitInMs;
+    }
+
+    /**
+     * Sets the elapsed time since the last received bit in milliseconds.
+     */
+    public void setTimeFromLastBitInMs(short value) {
+        setFlag(HAS_TIME_FROM_LAST_BIT);
+        mTimeFromLastBitInMs = value;
+    }
+
+    /**
+     * Resets the elapsed time since the last received bit in milliseconds.
+     */
+    public void resetTimeFromLastBitInMs() {
+        resetFlag(HAS_TIME_FROM_LAST_BIT);
+        mTimeFromLastBitInMs = Short.MIN_VALUE;
+    }
+
+    /**
+     * Returns true if {@link #getDopplerShiftInHz()} is available, false otherwise.
+     */
+    public boolean hasDopplerShiftInHz() {
+        return isFlagSet(HAS_DOPPLER_SHIFT);
+    }
+
+    /**
+     * Gets the Doppler Shift in Hz.
+     * A positive value indicates that the SV is moving toward the receiver.
+     *
+     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
+     * The reported doppler shift includes {@link #getDopplerShiftUncertaintyInHz()}.
+     *
+     * The value is only available if {@link #hasDopplerShiftInHz()} is true.
+     */
+    public double getDopplerShiftInHz() {
+        return mDopplerShiftInHz;
+    }
+
+    /**
+     * Sets the Doppler shift in Hz.
+     */
+    public void setDopplerShiftInHz(double value) {
+        setFlag(HAS_DOPPLER_SHIFT);
+        mDopplerShiftInHz = value;
+    }
+
+    /**
+     * Resets the Doppler shift in Hz.
+     */
+    public void resetDopplerShiftInHz() {
+        resetFlag(HAS_DOPPLER_SHIFT);
+        mDopplerShiftInHz = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getDopplerShiftUncertaintyInHz()} is available, false otherwise.
+     */
+    public boolean hasDopplerShiftUncertaintyInHz() {
+        return isFlagSet(HAS_DOPPLER_SHIFT_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the Doppler's Shift uncertainty (1-Sigma) in Hz.
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The value is only available if {@link #hasDopplerShiftUncertaintyInHz()} is true.
+     */
+    public double getDopplerShiftUncertaintyInHz() {
+        return mDopplerShiftUncertaintyInHz;
+    }
+
+    /**
+     * Sets the Doppler's shift uncertainty (1-Sigma) in Hz.
+     */
+    public void setDopplerShiftUncertaintyInHz(double value) {
+        setFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
+        mDopplerShiftUncertaintyInHz = value;
+    }
+
+    /**
+     * Resets the Doppler's shift uncertainty (1-Sigma) in Hz.
+     */
+    public void resetDopplerShiftUncertaintyInHz() {
+        resetFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
+        mDopplerShiftUncertaintyInHz = Double.NaN;
+    }
+
+    /**
+     * Gets a value indicating the 'multipath' state of the event.
+     */
+    public byte getMultipathIndicator() {
+        return mMultipathIndicator;
+    }
+
+    /**
+     * Sets the 'multi-path' indicator.
+     */
+    public void setMultipathIndicator(byte value) {
+        mMultipathIndicator = value;
+    }
+
+    /**
+     * Gets a string representation of the 'multi-path indicator'.
+     * For internal and logging use only.
+     */
+    private String getMultipathIndicatorString() {
+        switch(mMultipathIndicator) {
+            case MULTIPATH_INDICATOR_UNKNOWN:
+                return "Unknown";
+            case MULTIPATH_INDICATOR_DETECTED:
+                return "Detected";
+            case MULTIPATH_INDICATOR_NOT_USED:
+                return "NotUsed";
+            default:
+                return "<Invalid:" + mMultipathIndicator + ">";
+        }
+    }
+
+    /**
+     * Returns true if {@link #getSnrInDb()} is available, false otherwise.
+     */
+    public boolean hasSnrInDb() {
+        return isFlagSet(HAS_SNR);
+    }
+
+    /**
+     * Gets the Signal-to-Noise ratio (SNR) in dB.
+     *
+     * The value is only available if {@link #hasSnrInDb()} is true.
+     */
+    public double getSnrInDb() {
+        return mSnrInDb;
+    }
+
+    /**
+     * Sets the Signal-to-noise ratio (SNR) in dB.
+     */
+    public void setSnrInDb(double snrInDb) {
+        setFlag(HAS_SNR);
+        mSnrInDb = snrInDb;
+    }
+
+    /**
+     * Resets the Signal-to-noise ratio (SNR) in dB.
+     */
+    public void resetSnrInDb() {
+        resetFlag(HAS_SNR);
+        mSnrInDb = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getElevationInDeg()} is available, false otherwise.
+     */
+    public boolean hasElevationInDeg() {
+        return isFlagSet(HAS_ELEVATION);
+    }
+
+    /**
+     * Gets the Elevation in degrees.
+     * Range: [-90, 90]
+     * The reported elevation includes {@link #getElevationUncertaintyInDeg()}.
+     *
+     * The value is only available if {@link #hasElevationInDeg()} is true.
+     */
+    public double getElevationInDeg() {
+        return mElevationInDeg;
+    }
+
+    /**
+     * Sets the Elevation in degrees.
+     */
+    public void setElevationInDeg(double elevationInDeg) {
+        setFlag(HAS_ELEVATION);
+        mElevationInDeg = elevationInDeg;
+    }
+
+    /**
+     * Resets the Elevation in degrees.
+     */
+    public void resetElevationInDeg() {
+        resetFlag(HAS_ELEVATION);
+        mElevationInDeg = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getElevationUncertaintyInDeg()} is available, false otherwise.
+     */
+    public boolean hasElevationUncertaintyInDeg() {
+        return isFlagSet(HAS_ELEVATION_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the elevation's uncertainty (1-Sigma) in degrees.
+     * Range: [0, 90]
+     *
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The value is only available if {@link #hasElevationUncertaintyInDeg()} is true.
+     */
+    public double getElevationUncertaintyInDeg() {
+        return mElevationUncertaintyInDeg;
+    }
+
+    /**
+     * Sets the elevation's uncertainty (1-Sigma) in degrees.
+     */
+    public void setElevationUncertaintyInDeg(double value) {
+        setFlag(HAS_ELEVATION_UNCERTAINTY);
+        mElevationUncertaintyInDeg = value;
+    }
+
+    /**
+     * Resets the elevation's uncertainty (1-Sigma) in degrees.
+     */
+    public void resetElevationUncertaintyInDeg() {
+        resetFlag(HAS_ELEVATION_UNCERTAINTY);
+        mElevationUncertaintyInDeg = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getAzimuthInDeg()} is available, false otherwise.
+     */
+    public boolean hasAzimuthInDeg() {
+        return isFlagSet(HAS_AZIMUTH);
+    }
+
+    /**
+     * Gets the azimuth in degrees.
+     * Range: [0, 360).
+     *
+     * The reported azimuth includes {@link #getAzimuthUncertaintyInDeg()}.
+     *
+     * The value is only available if {@link #hasAzimuthInDeg()} is true.
+     */
+    public double getAzimuthInDeg() {
+        return mAzimuthInDeg;
+    }
+
+    /**
+     * Sets the Azimuth in degrees.
+     */
+    public void setAzimuthInDeg(double value) {
+        setFlag(HAS_AZIMUTH);
+        mAzimuthInDeg = value;
+    }
+
+    /**
+     * Resets the Azimuth in degrees.
+     */
+    public void resetAzimuthInDeg() {
+        resetFlag(HAS_AZIMUTH);
+        mAzimuthInDeg = Double.NaN;
+    }
+
+    /**
+     * Returns true if {@link #getAzimuthUncertaintyInDeg()} is available, false otherwise.
+     */
+    public boolean hasAzimuthUncertaintyInDeg() {
+        return isFlagSet(HAS_AZIMUTH_UNCERTAINTY);
+    }
+
+    /**
+     * Gets the azimuth's uncertainty (1-Sigma) in degrees.
+     * Range: [0, 180].
+     *
+     * The uncertainty is represented as an absolute (single sided) value.
+     *
+     * The value is only available if {@link #hasAzimuthUncertaintyInDeg()} is true.
+     */
+    public double getAzimuthUncertaintyInDeg() {
+        return mAzimuthUncertaintyInDeg;
+    }
+
+    /**
+     * Sets the Azimuth's uncertainty (1-Sigma) in degrees.
+     */
+    public void setAzimuthUncertaintyInDeg(double value) {
+        setFlag(HAS_AZIMUTH_UNCERTAINTY);
+        mAzimuthUncertaintyInDeg = value;
+    }
+
+    /**
+     * Resets the Azimuth's uncertainty (1-Sigma) in degrees.
+     */
+    public void resetAzimuthUncertaintyInDeg() {
+        resetFlag(HAS_AZIMUTH_UNCERTAINTY);
+        mAzimuthUncertaintyInDeg = Double.NaN;
+    }
+
+    /**
+     * Gets a flag indicating whether the GPS represented by the measurement was used for computing
+     * the most recent fix.
+     *
+     * @return A non-null value if the data is available, null otherwise.
+     */
+    public boolean isUsedInFix() {
+        return mUsedInFix;
+    }
+
+    /**
+     * Sets the Used-in-Fix flag.
+     */
+    public void setUsedInFix(boolean value) {
+        mUsedInFix = value;
+    }
+
+    public static final @android.annotation.NonNull Creator<GpsMeasurement> CREATOR = new Creator<GpsMeasurement>() {
+        @Override
+        public GpsMeasurement createFromParcel(Parcel parcel) {
+            GpsMeasurement gpsMeasurement = new GpsMeasurement();
+
+            gpsMeasurement.mFlags = parcel.readInt();
+            gpsMeasurement.mPrn = parcel.readByte();
+            gpsMeasurement.mTimeOffsetInNs = parcel.readDouble();
+            gpsMeasurement.mState = (short) parcel.readInt();
+            gpsMeasurement.mReceivedGpsTowInNs = parcel.readLong();
+            gpsMeasurement.mReceivedGpsTowUncertaintyInNs = parcel.readLong();
+            gpsMeasurement.mCn0InDbHz = parcel.readDouble();
+            gpsMeasurement.mPseudorangeRateInMetersPerSec = parcel.readDouble();
+            gpsMeasurement.mPseudorangeRateUncertaintyInMetersPerSec = parcel.readDouble();
+            gpsMeasurement.mAccumulatedDeltaRangeState = (short) parcel.readInt();
+            gpsMeasurement.mAccumulatedDeltaRangeInMeters = parcel.readDouble();
+            gpsMeasurement.mAccumulatedDeltaRangeUncertaintyInMeters = parcel.readDouble();
+            gpsMeasurement.mPseudorangeInMeters = parcel.readDouble();
+            gpsMeasurement.mPseudorangeUncertaintyInMeters = parcel.readDouble();
+            gpsMeasurement.mCodePhaseInChips = parcel.readDouble();
+            gpsMeasurement.mCodePhaseUncertaintyInChips = parcel.readDouble();
+            gpsMeasurement.mCarrierFrequencyInHz = parcel.readFloat();
+            gpsMeasurement.mCarrierCycles = parcel.readLong();
+            gpsMeasurement.mCarrierPhase = parcel.readDouble();
+            gpsMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
+            gpsMeasurement.mLossOfLock = parcel.readByte();
+            gpsMeasurement.mBitNumber = parcel.readInt();
+            gpsMeasurement.mTimeFromLastBitInMs = (short) parcel.readInt();
+            gpsMeasurement.mDopplerShiftInHz = parcel.readDouble();
+            gpsMeasurement.mDopplerShiftUncertaintyInHz = parcel.readDouble();
+            gpsMeasurement.mMultipathIndicator = parcel.readByte();
+            gpsMeasurement.mSnrInDb = parcel.readDouble();
+            gpsMeasurement.mElevationInDeg = parcel.readDouble();
+            gpsMeasurement.mElevationUncertaintyInDeg = parcel.readDouble();
+            gpsMeasurement.mAzimuthInDeg = parcel.readDouble();
+            gpsMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble();
+            gpsMeasurement.mUsedInFix = parcel.readInt() != 0;
+
+            return gpsMeasurement;
+        }
+
+        @Override
+        public GpsMeasurement[] newArray(int i) {
+            return new GpsMeasurement[i];
+        }
+    };
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mFlags);
+        parcel.writeByte(mPrn);
+        parcel.writeDouble(mTimeOffsetInNs);
+        parcel.writeInt(mState);
+        parcel.writeLong(mReceivedGpsTowInNs);
+        parcel.writeLong(mReceivedGpsTowUncertaintyInNs);
+        parcel.writeDouble(mCn0InDbHz);
+        parcel.writeDouble(mPseudorangeRateInMetersPerSec);
+        parcel.writeDouble(mPseudorangeRateUncertaintyInMetersPerSec);
+        parcel.writeInt(mAccumulatedDeltaRangeState);
+        parcel.writeDouble(mAccumulatedDeltaRangeInMeters);
+        parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyInMeters);
+        parcel.writeDouble(mPseudorangeInMeters);
+        parcel.writeDouble(mPseudorangeUncertaintyInMeters);
+        parcel.writeDouble(mCodePhaseInChips);
+        parcel.writeDouble(mCodePhaseUncertaintyInChips);
+        parcel.writeFloat(mCarrierFrequencyInHz);
+        parcel.writeLong(mCarrierCycles);
+        parcel.writeDouble(mCarrierPhase);
+        parcel.writeDouble(mCarrierPhaseUncertainty);
+        parcel.writeByte(mLossOfLock);
+        parcel.writeInt(mBitNumber);
+        parcel.writeInt(mTimeFromLastBitInMs);
+        parcel.writeDouble(mDopplerShiftInHz);
+        parcel.writeDouble(mDopplerShiftUncertaintyInHz);
+        parcel.writeByte(mMultipathIndicator);
+        parcel.writeDouble(mSnrInDb);
+        parcel.writeDouble(mElevationInDeg);
+        parcel.writeDouble(mElevationUncertaintyInDeg);
+        parcel.writeDouble(mAzimuthInDeg);
+        parcel.writeDouble(mAzimuthUncertaintyInDeg);
+        parcel.writeInt(mUsedInFix ? 1 : 0);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        final String format = "   %-29s = %s\n";
+        final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
+        StringBuilder builder = new StringBuilder("GpsMeasurement:\n");
+
+        builder.append(String.format(format, "Prn", mPrn));
+
+        builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
+
+        builder.append(String.format(format, "State", getStateString()));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "ReceivedGpsTowInNs",
+                mReceivedGpsTowInNs,
+                "ReceivedGpsTowUncertaintyInNs",
+                mReceivedGpsTowUncertaintyInNs));
+
+        builder.append(String.format(format, "Cn0InDbHz", mCn0InDbHz));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "PseudorangeRateInMetersPerSec",
+                mPseudorangeRateInMetersPerSec,
+                "PseudorangeRateUncertaintyInMetersPerSec",
+                mPseudorangeRateUncertaintyInMetersPerSec));
+        builder.append(String.format(
+                format,
+                "PseudorangeRateIsCorrected",
+                isPseudorangeRateCorrected()));
+
+        builder.append(String.format(
+                format,
+                "AccumulatedDeltaRangeState",
+                getAccumulatedDeltaRangeStateString()));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "AccumulatedDeltaRangeInMeters",
+                mAccumulatedDeltaRangeInMeters,
+                "AccumulatedDeltaRangeUncertaintyInMeters",
+                mAccumulatedDeltaRangeUncertaintyInMeters));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "PseudorangeInMeters",
+                hasPseudorangeInMeters() ? mPseudorangeInMeters : null,
+                "PseudorangeUncertaintyInMeters",
+                hasPseudorangeUncertaintyInMeters() ? mPseudorangeUncertaintyInMeters : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "CodePhaseInChips",
+                hasCodePhaseInChips() ? mCodePhaseInChips : null,
+                "CodePhaseUncertaintyInChips",
+                hasCodePhaseUncertaintyInChips() ? mCodePhaseUncertaintyInChips : null));
+
+        builder.append(String.format(
+                format,
+                "CarrierFrequencyInHz",
+                hasCarrierFrequencyInHz() ? mCarrierFrequencyInHz : null));
+
+        builder.append(String.format(
+                format,
+                "CarrierCycles",
+                hasCarrierCycles() ? mCarrierCycles : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "CarrierPhase",
+                hasCarrierPhase() ? mCarrierPhase : null,
+                "CarrierPhaseUncertainty",
+                hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
+
+        builder.append(String.format(format, "LossOfLock", getLossOfLockString()));
+
+        builder.append(String.format(
+                format,
+                "BitNumber",
+                hasBitNumber() ? mBitNumber : null));
+
+        builder.append(String.format(
+                format,
+                "TimeFromLastBitInMs",
+                hasTimeFromLastBitInMs() ? mTimeFromLastBitInMs : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "DopplerShiftInHz",
+                hasDopplerShiftInHz() ? mDopplerShiftInHz : null,
+                "DopplerShiftUncertaintyInHz",
+                hasDopplerShiftUncertaintyInHz() ? mDopplerShiftUncertaintyInHz : null));
+
+        builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
+
+        builder.append(String.format(
+                format,
+                "SnrInDb",
+                hasSnrInDb() ? mSnrInDb : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "ElevationInDeg",
+                hasElevationInDeg() ? mElevationInDeg : null,
+                "ElevationUncertaintyInDeg",
+                hasElevationUncertaintyInDeg() ? mElevationUncertaintyInDeg : null));
+
+        builder.append(String.format(
+                formatWithUncertainty,
+                "AzimuthInDeg",
+                hasAzimuthInDeg() ? mAzimuthInDeg : null,
+                "AzimuthUncertaintyInDeg",
+                hasAzimuthUncertaintyInDeg() ? mAzimuthUncertaintyInDeg : null));
+
+        builder.append(String.format(format, "UsedInFix", mUsedInFix));
+
+        return builder.toString();
+    }
+
+    private void initialize() {
+        mFlags = HAS_NO_FLAGS;
+        setPrn(Byte.MIN_VALUE);
+        setTimeOffsetInNs(Long.MIN_VALUE);
+        setState(STATE_UNKNOWN);
+        setReceivedGpsTowInNs(Long.MIN_VALUE);
+        setReceivedGpsTowUncertaintyInNs(Long.MAX_VALUE);
+        setCn0InDbHz(Double.MIN_VALUE);
+        setPseudorangeRateInMetersPerSec(Double.MIN_VALUE);
+        setPseudorangeRateUncertaintyInMetersPerSec(Double.MIN_VALUE);
+        setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
+        setAccumulatedDeltaRangeInMeters(Double.MIN_VALUE);
+        setAccumulatedDeltaRangeUncertaintyInMeters(Double.MIN_VALUE);
+        resetPseudorangeInMeters();
+        resetPseudorangeUncertaintyInMeters();
+        resetCodePhaseInChips();
+        resetCodePhaseUncertaintyInChips();
+        resetCarrierFrequencyInHz();
+        resetCarrierCycles();
+        resetCarrierPhase();
+        resetCarrierPhaseUncertainty();
+        setLossOfLock(LOSS_OF_LOCK_UNKNOWN);
+        resetBitNumber();
+        resetTimeFromLastBitInMs();
+        resetDopplerShiftInHz();
+        resetDopplerShiftUncertaintyInHz();
+        setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
+        resetSnrInDb();
+        resetElevationInDeg();
+        resetElevationUncertaintyInDeg();
+        resetAzimuthInDeg();
+        resetAzimuthUncertaintyInDeg();
+        setUsedInFix(false);
+    }
+
+    private void setFlag(int flag) {
+        mFlags |= flag;
+    }
+
+    private void resetFlag(int flag) {
+        mFlags &= ~flag;
+    }
+
+    private boolean isFlagSet(int flag) {
+        return (mFlags & flag) == flag;
+    }
+}
diff --git a/android/location/GpsMeasurementsEvent.java b/android/location/GpsMeasurementsEvent.java
new file mode 100644
index 0000000..f3feb7a
--- /dev/null
+++ b/android/location/GpsMeasurementsEvent.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * A class implementing a container for data associated with a measurement event.
+ * Events are delivered to registered instances of {@link Listener}.
+ *
+ * @deprecated use {@link GnssMeasurementsEvent} instead.
+ *
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public class GpsMeasurementsEvent implements Parcelable {
+
+    /**
+     * The system does not support tracking of GPS Measurements. This status will not change in the
+     * future.
+     */
+    public static final int STATUS_NOT_SUPPORTED = 0;
+
+    /**
+     * GPS Measurements are successfully being tracked, it will receive updates once they are
+     * available.
+     */
+    public static final int STATUS_READY = 1;
+
+    /**
+     * GPS provider or Location is disabled, updates will not be received until they are enabled.
+     */
+    public static final int STATUS_GPS_LOCATION_DISABLED = 2;
+
+    private final GpsClock mClock;
+    private final Collection<GpsMeasurement> mReadOnlyMeasurements;
+
+    /**
+     * Used for receiving GPS satellite measurements from the GPS engine.
+     * Each measurement contains raw and computed data identifying a satellite.
+     * You can implement this interface and call {@link LocationManager#addGpsMeasurementListener}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface Listener {
+
+        /**
+         * Returns the latest collected GPS Measurements.
+         */
+        void onGpsMeasurementsReceived(GpsMeasurementsEvent eventArgs);
+
+        /**
+         * Returns the latest status of the GPS Measurements sub-system.
+         */
+        void onStatusChanged(int status);
+    }
+
+    public GpsMeasurementsEvent(GpsClock clock, GpsMeasurement[] measurements) {
+        if (clock == null) {
+            throw new InvalidParameterException("Parameter 'clock' must not be null.");
+        }
+        if (measurements == null || measurements.length == 0) {
+            throw new InvalidParameterException(
+                    "Parameter 'measurements' must not be null or empty.");
+        }
+
+        mClock = clock;
+        Collection<GpsMeasurement> measurementCollection = Arrays.asList(measurements);
+        mReadOnlyMeasurements = Collections.unmodifiableCollection(measurementCollection);
+    }
+
+    @NonNull
+    public GpsClock getClock() {
+        return mClock;
+    }
+
+    /**
+     * Gets a read-only collection of measurements associated with the current event.
+     */
+    @NonNull
+    public Collection<GpsMeasurement> getMeasurements() {
+        return mReadOnlyMeasurements;
+    }
+
+    public static final @android.annotation.NonNull Creator<GpsMeasurementsEvent> CREATOR =
+            new Creator<GpsMeasurementsEvent>() {
+        @Override
+        public GpsMeasurementsEvent createFromParcel(Parcel in) {
+            ClassLoader classLoader = getClass().getClassLoader();
+
+            GpsClock clock = in.readParcelable(classLoader);
+
+            int measurementsLength = in.readInt();
+            GpsMeasurement[] measurementsArray = new GpsMeasurement[measurementsLength];
+            in.readTypedArray(measurementsArray, GpsMeasurement.CREATOR);
+
+            return new GpsMeasurementsEvent(clock, measurementsArray);
+        }
+
+        @Override
+        public GpsMeasurementsEvent[] newArray(int size) {
+            return new GpsMeasurementsEvent[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeParcelable(mClock, flags);
+
+        int measurementsCount = mReadOnlyMeasurements.size();
+        GpsMeasurement[] measurementsArray =
+                mReadOnlyMeasurements.toArray(new GpsMeasurement[measurementsCount]);
+        parcel.writeInt(measurementsArray.length);
+        parcel.writeTypedArray(measurementsArray, flags);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("[ GpsMeasurementsEvent:\n\n");
+
+        builder.append(mClock.toString());
+        builder.append("\n");
+
+        for (GpsMeasurement measurement : mReadOnlyMeasurements) {
+            builder.append(measurement.toString());
+            builder.append("\n");
+        }
+
+        builder.append("]");
+
+        return builder.toString();
+    }
+}
diff --git a/android/location/GpsNavigationMessage.java b/android/location/GpsNavigationMessage.java
new file mode 100644
index 0000000..dc1e99f
--- /dev/null
+++ b/android/location/GpsNavigationMessage.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.security.InvalidParameterException;
+
+/**
+ * A class containing a GPS satellite Navigation Message.
+ *
+ * @deprecated use {@link GnssNavigationMessage} instead.
+ *
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public class GpsNavigationMessage implements Parcelable {
+
+    private static final byte[] EMPTY_ARRAY = new byte[0];
+
+    // The following enumerations must be in sync with the values declared in gps.h
+
+    /**
+     * The type of the navigation message is not available or unknown.
+     */
+    public static final byte TYPE_UNKNOWN = 0;
+
+    /**
+     * The Navigation Message is of type L1 C/A.
+     */
+    public static final byte TYPE_L1CA = 1;
+
+    /**
+     * The Navigation Message is of type L1-CNAV.
+     */
+    public static final byte TYPE_L2CNAV = 2;
+
+    /**
+     * The Navigation Message is of type L5-CNAV.
+     */
+    public static final byte TYPE_L5CNAV = 3;
+
+    /**
+     * The Navigation Message is of type CNAV-2.
+     */
+    public static final byte TYPE_CNAV2 = 4;
+
+    /**
+     * The Navigation Message Status is 'unknown'.
+     */
+    public static final short STATUS_UNKNOWN = 0;
+
+    /**
+     * The Navigation Message was received without any parity error in its navigation words.
+     */
+    public static final short STATUS_PARITY_PASSED = (1<<0);
+
+    /**
+     * The Navigation Message was received with words that failed parity check, but the receiver was
+     * able to correct those words.
+     */
+    public static final short STATUS_PARITY_REBUILT = (1<<1);
+
+    // End enumerations in sync with gps.h
+
+    private byte mType;
+    private byte mPrn;
+    private short mMessageId;
+    private short mSubmessageId;
+    private byte[] mData;
+    private short mStatus;
+
+    GpsNavigationMessage() {
+        initialize();
+    }
+
+    /**
+     * Sets all contents to the values stored in the provided object.
+     */
+    public void set(GpsNavigationMessage navigationMessage) {
+        mType = navigationMessage.mType;
+        mPrn = navigationMessage.mPrn;
+        mMessageId = navigationMessage.mMessageId;
+        mSubmessageId = navigationMessage.mSubmessageId;
+        mData = navigationMessage.mData;
+        mStatus = navigationMessage.mStatus;
+    }
+
+    /**
+     * Resets all the contents to its original state.
+     */
+    public void reset() {
+        initialize();
+    }
+
+    /**
+     * Gets the type of the navigation message contained in the object.
+     */
+    public byte getType() {
+        return mType;
+    }
+
+    /**
+     * Sets the type of the navigation message.
+     */
+    public void setType(byte value) {
+        mType = value;
+    }
+
+    /**
+     * Gets a string representation of the 'type'.
+     * For internal and logging use only.
+     */
+    private String getTypeString() {
+        switch (mType) {
+            case TYPE_UNKNOWN:
+                return "Unknown";
+            case TYPE_L1CA:
+                return "L1 C/A";
+            case TYPE_L2CNAV:
+                return "L2-CNAV";
+            case TYPE_L5CNAV:
+                return "L5-CNAV";
+            case TYPE_CNAV2:
+                return "CNAV-2";
+            default:
+                return "<Invalid:" + mType + ">";
+        }
+    }
+
+    /**
+     * Gets the Pseudo-random number.
+     * Range: [1, 32].
+     */
+    public byte getPrn() {
+        return mPrn;
+    }
+
+    /**
+     * Sets the Pseud-random number.
+     */
+    public void setPrn(byte value) {
+        mPrn = value;
+    }
+
+    /**
+     * Gets the Message Identifier.
+     * It provides an index so the complete Navigation Message can be assembled. i.e. for L1 C/A
+     * subframe 4 and 5, this value corresponds to the 'frame id' of the navigation message.
+     * Subframe 1, 2, 3 does not contain a 'frame id' and this might be reported as -1.
+     */
+    public short getMessageId() {
+        return mMessageId;
+    }
+
+    /**
+     * Sets the Message Identifier.
+     */
+    public void setMessageId(short value) {
+        mMessageId = value;
+    }
+
+    /**
+     * Gets the Sub-message Identifier.
+     * If required by {@link #getType()}, this value contains a sub-index within the current message
+     * (or frame) that is being transmitted. i.e. for L1 C/A the sub-message identifier corresponds
+     * to the sub-frame Id of the navigation message.
+     */
+    public short getSubmessageId() {
+        return mSubmessageId;
+    }
+
+    /**
+     * Sets the Sub-message identifier.
+     */
+    public void setSubmessageId(short value) {
+        mSubmessageId = value;
+    }
+
+    /**
+     * Gets the data associated with the Navigation Message.
+     * The bytes (or words) specified using big endian format (MSB first).
+     */
+    @NonNull
+    public byte[] getData() {
+        return mData;
+    }
+
+    /**
+     * Sets the data associated with the Navigation Message.
+     */
+    public void setData(byte[] value) {
+        if (value == null) {
+            throw new InvalidParameterException("Data must be a non-null array");
+        }
+
+        mData = value;
+    }
+
+    /**
+     * Gets the Status of the navigation message contained in the object.
+     */
+    public short getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Sets the status of the navigation message.
+     */
+    public void setStatus(short value) {
+        mStatus = value;
+    }
+
+    /**
+     * Gets a string representation of the 'status'.
+     * For internal and logging use only.
+     */
+    private String getStatusString() {
+        switch (mStatus) {
+            case STATUS_UNKNOWN:
+                return "Unknown";
+            case STATUS_PARITY_PASSED:
+                return "ParityPassed";
+            case STATUS_PARITY_REBUILT:
+                return "ParityRebuilt";
+            default:
+                return "<Invalid:" + mStatus + ">";
+        }
+    }
+
+    public static final @android.annotation.NonNull Creator<GpsNavigationMessage> CREATOR =
+            new Creator<GpsNavigationMessage>() {
+        @Override
+        public GpsNavigationMessage createFromParcel(Parcel parcel) {
+            GpsNavigationMessage navigationMessage = new GpsNavigationMessage();
+
+            navigationMessage.setType(parcel.readByte());
+            navigationMessage.setPrn(parcel.readByte());
+            navigationMessage.setMessageId((short) parcel.readInt());
+            navigationMessage.setSubmessageId((short) parcel.readInt());
+
+            int dataLength = parcel.readInt();
+            byte[] data = new byte[dataLength];
+            parcel.readByteArray(data);
+            navigationMessage.setData(data);
+
+            if (parcel.dataAvail() >= Integer.SIZE) {
+                int status = parcel.readInt();
+                navigationMessage.setStatus((short) status);
+            } else {
+                navigationMessage.setStatus(STATUS_UNKNOWN);
+            }
+
+            return navigationMessage;
+        }
+
+        @Override
+        public GpsNavigationMessage[] newArray(int size) {
+            return new GpsNavigationMessage[size];
+        }
+    };
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeByte(mType);
+        parcel.writeByte(mPrn);
+        parcel.writeInt(mMessageId);
+        parcel.writeInt(mSubmessageId);
+        parcel.writeInt(mData.length);
+        parcel.writeByteArray(mData);
+        parcel.writeInt(mStatus);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        final String format = "   %-15s = %s\n";
+        StringBuilder builder = new StringBuilder("GpsNavigationMessage:\n");
+
+        builder.append(String.format(format, "Type", getTypeString()));
+        builder.append(String.format(format, "Prn", mPrn));
+        builder.append(String.format(format, "Status", getStatusString()));
+        builder.append(String.format(format, "MessageId", mMessageId));
+        builder.append(String.format(format, "SubmessageId", mSubmessageId));
+
+        builder.append(String.format(format, "Data", "{"));
+        String prefix = "        ";
+        for(byte value : mData) {
+            builder.append(prefix);
+            builder.append(value);
+            prefix = ", ";
+        }
+        builder.append(" }");
+
+        return builder.toString();
+    }
+
+    private void initialize() {
+        mType = TYPE_UNKNOWN;
+        mPrn = 0;
+        mMessageId = -1;
+        mSubmessageId = -1;
+        mData = EMPTY_ARRAY;
+        mStatus = STATUS_UNKNOWN;
+    }
+}
diff --git a/android/location/GpsNavigationMessageEvent.java b/android/location/GpsNavigationMessageEvent.java
new file mode 100644
index 0000000..2d5d6eb
--- /dev/null
+++ b/android/location/GpsNavigationMessageEvent.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2014 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.location;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.security.InvalidParameterException;
+
+/**
+ * A class implementing a container for data associated with a navigation message event.
+ * Events are delivered to registered instances of {@link Listener}.
+ *
+ * @deprecated use {@link GnssNavigationMessage} instead.
+ *
+ * @hide
+ */
+@Deprecated
+@SystemApi
+public class GpsNavigationMessageEvent implements Parcelable {
+
+    /**
+     * The system does not support tracking of GPS Navigation Messages. This status will not change
+     * in the future.
+     */
+    public static int STATUS_NOT_SUPPORTED = 0;
+
+    /**
+     * GPS Navigation Messages are successfully being tracked, it will receive updates once they are
+     * available.
+     */
+    public static int STATUS_READY = 1;
+
+    /**
+     * GPS provider or Location is disabled, updated will not be received until they are enabled.
+     */
+    public static int STATUS_GPS_LOCATION_DISABLED = 2;
+
+    private final GpsNavigationMessage mNavigationMessage;
+
+    /**
+     * Used for receiving GPS satellite Navigation Messages from the GPS engine.
+     * You can implement this interface and call
+     * {@link LocationManager#addGpsNavigationMessageListener}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface Listener {
+
+        /**
+         * Returns the latest collected GPS Navigation Message.
+         */
+        void onGpsNavigationMessageReceived(GpsNavigationMessageEvent event);
+
+        /**
+         * Returns the latest status of the GPS Navigation Messages sub-system.
+         */
+        void onStatusChanged(int status);
+    }
+
+    public GpsNavigationMessageEvent(GpsNavigationMessage message) {
+        if (message == null) {
+            throw new InvalidParameterException("Parameter 'message' must not be null.");
+        }
+        mNavigationMessage = message;
+    }
+
+    @NonNull
+    public GpsNavigationMessage getNavigationMessage() {
+        return mNavigationMessage;
+    }
+
+    public static final @android.annotation.NonNull Creator<GpsNavigationMessageEvent> CREATOR =
+            new Creator<GpsNavigationMessageEvent>() {
+                @Override
+                public GpsNavigationMessageEvent createFromParcel(Parcel in) {
+                    ClassLoader classLoader = getClass().getClassLoader();
+                    GpsNavigationMessage navigationMessage = in.readParcelable(classLoader);
+                    return new GpsNavigationMessageEvent(navigationMessage);
+                }
+
+                @Override
+                public GpsNavigationMessageEvent[] newArray(int size) {
+                    return new GpsNavigationMessageEvent[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeParcelable(mNavigationMessage, flags);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("[ GpsNavigationMessageEvent:\n\n");
+        builder.append(mNavigationMessage.toString());
+        builder.append("\n]");
+        return builder.toString();
+    }
+}
diff --git a/android/location/GpsSatellite.java b/android/location/GpsSatellite.java
new file mode 100644
index 0000000..788d01e
--- /dev/null
+++ b/android/location/GpsSatellite.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 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.location;
+
+/**
+ * This class represents the current state of a GPS satellite.
+ *
+ * This class is used in conjunction with the {@link GpsStatus} class.
+ *
+ * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
+ */
+@Deprecated
+public final class GpsSatellite {
+    /* These package private values are modified by the GpsStatus class */
+    boolean mValid;
+    boolean mHasEphemeris;
+    boolean mHasAlmanac;
+    boolean mUsedInFix;
+    int mPrn;
+    float mSnr;
+    float mElevation;
+    float mAzimuth;
+
+    GpsSatellite(int prn) {
+        mPrn = prn;
+    }
+
+    /**
+     * Used by {@link LocationManager#getGpsStatus} to copy LocationManager's
+     * cached GpsStatus instance to the client's copy.
+     */
+    void setStatus(GpsSatellite satellite) {
+        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;
+        }
+    }
+
+    /**
+     * Returns the PRN (pseudo-random number) for the satellite.
+     *
+     * @return PRN number
+     */
+    public int getPrn() {
+        return mPrn;
+    }
+
+    /**
+     * Returns the signal to noise ratio for the satellite.
+     *
+     * @return the signal to noise ratio
+     */
+    public float getSnr() {
+        return mSnr;
+    }
+
+    /**
+     * Returns the elevation of the satellite in degrees.
+     * The elevation can vary between 0 and 90.
+     *
+     * @return the elevation in degrees
+     */
+    public float getElevation() {
+        return mElevation;
+    }
+
+    /**
+     * Returns the azimuth of the satellite in degrees.
+     * The azimuth can vary between 0 and 360.
+     *
+     * @return the azimuth in degrees
+     */
+    public float getAzimuth() {
+        return mAzimuth;
+    }
+
+    /**
+     * Returns true if the GPS engine has ephemeris data for the satellite.
+     *
+     * @return true if the satellite has ephemeris data
+     */
+    public boolean hasEphemeris() {
+        return mHasEphemeris;
+    }
+
+    /**
+     * Returns true if the GPS engine has almanac data for the satellite.
+     *
+     * @return true if the satellite has almanac data
+     */
+    public boolean hasAlmanac() {
+        return mHasAlmanac;
+    }
+
+    /**
+     * Returns true if the satellite was used by the GPS engine when
+     * calculating the most recent GPS fix.
+     *
+     * @return true if the satellite was used to compute the most recent fix.
+     */
+    public boolean usedInFix() {
+        return mUsedInFix;
+    }
+}
diff --git a/android/location/GpsStatus.java b/android/location/GpsStatus.java
new file mode 100644
index 0000000..496885c
--- /dev/null
+++ b/android/location/GpsStatus.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2008 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.location;
+
+import android.annotation.NonNull;
+import android.util.SparseArray;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+
+/**
+ * This class represents the current state of the GPS engine and is used in conjunction with {@link
+ * GpsStatus.Listener}.
+ *
+ * @deprecated Use {@link GnssStatus} instead.
+ */
+@Deprecated
+public final class GpsStatus {
+    private static final int MAX_SATELLITES = 255;
+    private static final int GLONASS_SVID_OFFSET = 64;
+    private static final int BEIDOU_SVID_OFFSET = 200;
+    private static final int SBAS_SVID_OFFSET = -87;
+
+    private int mTimeToFirstFix;
+    private final SparseArray<GpsSatellite> mSatellites = new SparseArray<>();
+
+    private final class SatelliteIterator implements Iterator<GpsSatellite> {
+        private final int mSatellitesCount;
+
+        private int mIndex = 0;
+
+        SatelliteIterator() {
+            mSatellitesCount = mSatellites.size();
+        }
+
+        @Override
+        public boolean hasNext() {
+            for (; mIndex < mSatellitesCount; ++mIndex) {
+                GpsSatellite satellite = mSatellites.valueAt(mIndex);
+                if (satellite.mValid) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public GpsSatellite next() {
+            while (mIndex < mSatellitesCount) {
+                GpsSatellite satellite = mSatellites.valueAt(mIndex);
+                ++mIndex;
+                if (satellite.mValid) {
+                    return satellite;
+                }
+            }
+            throw new NoSuchElementException();
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    private Iterable<GpsSatellite> mSatelliteList = SatelliteIterator::new;
+
+    /**
+     * Event sent when the GPS system has started.
+     */
+    public static final int GPS_EVENT_STARTED = 1;
+
+    /**
+     * Event sent when the GPS system has stopped.
+     */
+    public static final int GPS_EVENT_STOPPED = 2;
+
+    /**
+     * Event sent when the GPS system has received its first fix since starting.
+     * Call {@link #getTimeToFirstFix()} to find the time from start to first fix.
+     */
+    public static final int GPS_EVENT_FIRST_FIX = 3;
+
+    /**
+     * Event sent periodically to report GPS satellite status.
+     * Call {@link #getSatellites()} to retrieve the status for each satellite.
+     */
+    public static final int GPS_EVENT_SATELLITE_STATUS = 4;
+
+    /**
+     * Used for receiving notifications when GPS status has changed.
+     *
+     * @deprecated Use {@link GnssStatus.Callback} instead.
+     */
+    @Deprecated
+    public interface Listener {
+        /**
+         * Called to report changes in the GPS status.
+         * The event number is one of:
+         * <ul>
+         * <li> {@link GpsStatus#GPS_EVENT_STARTED}
+         * <li> {@link GpsStatus#GPS_EVENT_STOPPED}
+         * <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX}
+         * <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS}
+         * </ul>
+         *
+         * When this method is called, the client should call
+         * {@link LocationManager#getGpsStatus} to get additional
+         * status information.
+         *
+         * @param event event number for this notification
+         */
+        void onGpsStatusChanged(int event);
+    }
+
+    /**
+     * Used for receiving NMEA sentences from the GPS.
+     * NMEA 0183 is a standard for communicating with marine electronic devices
+     * and is a common method for receiving data from a GPS, typically over a serial port.
+     * See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
+     * You can implement this interface and call {@link LocationManager#addNmeaListener}
+     * to receive NMEA data from the GPS engine.
+     * @deprecated use {@link OnNmeaMessageListener} instead.
+     */
+    @Deprecated
+    public interface NmeaListener {
+        void onNmeaReceived(long timestamp, String nmea);
+    }
+
+    /**
+     * Builds a GpsStatus from the given GnssStatus.
+     */
+    @NonNull
+    public static GpsStatus create(@NonNull GnssStatus gnssStatus, int timeToFirstFix) {
+        GpsStatus status = new GpsStatus();
+        status.setStatus(gnssStatus, timeToFirstFix);
+        return status;
+    }
+
+    private GpsStatus() {
+    }
+
+    /**
+     * @hide
+     */
+    void setStatus(GnssStatus status, int timeToFirstFix) {
+        for (int i = 0; i < mSatellites.size(); i++) {
+            mSatellites.valueAt(i).mValid = false;
+        }
+
+        mTimeToFirstFix = timeToFirstFix;
+        for (int i = 0; i < status.getSatelliteCount(); i++) {
+            int constellationType = status.getConstellationType(i);
+            int prn = status.getSvid(i);
+            // Other satellites passed through these APIs before GnssSvStatus was availble.
+            // GPS, SBAS & QZSS can pass through at their nominally
+            // assigned prn number (as long as it fits in the valid 0-255 range below.)
+            // Glonass, and Beidou are passed through with the defacto standard offsets
+            // Other future constellation reporting (e.g. Galileo) needs to use
+            // GnssSvStatus on (N level) HAL & Java layers.
+            if (constellationType == GnssStatus.CONSTELLATION_GLONASS) {
+                prn += GLONASS_SVID_OFFSET;
+            } else if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) {
+                prn += BEIDOU_SVID_OFFSET;
+            } else if (constellationType == GnssStatus.CONSTELLATION_SBAS) {
+                prn += SBAS_SVID_OFFSET;
+            } else if ((constellationType != GnssStatus.CONSTELLATION_GPS) &&
+                    (constellationType != GnssStatus.CONSTELLATION_QZSS)) {
+                continue;
+            }
+            if (prn <= 0 || prn > MAX_SATELLITES) {
+                continue;
+            }
+
+            GpsSatellite satellite = mSatellites.get(prn);
+            if (satellite == null) {
+                satellite = new GpsSatellite(prn);
+                mSatellites.put(prn, satellite);
+            }
+
+            satellite.mValid = true;
+            satellite.mSnr = status.getCn0DbHz(i);
+            satellite.mElevation = status.getElevationDegrees(i);
+            satellite.mAzimuth = status.getAzimuthDegrees(i);
+            satellite.mHasEphemeris = status.hasEphemerisData(i);
+            satellite.mHasAlmanac = status.hasAlmanacData(i);
+            satellite.mUsedInFix = status.usedInFix(i);
+        }
+    }
+
+    /**
+     * 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
+     */
+    public int getTimeToFirstFix() {
+        return mTimeToFirstFix;
+    }
+
+    /**
+     * Returns an array of {@link GpsSatellite} objects, which represent the
+     * current state of the GPS engine.
+     *
+     * @return the list of satellites
+     */
+    public Iterable<GpsSatellite> getSatellites() {
+        return mSatelliteList;
+    }
+
+    /**
+     * Returns the maximum number of satellites that can be in the satellite
+     * list that can be returned by {@link #getSatellites()}.
+     *
+     * @return the maximum number of satellites
+     */
+    public int getMaxSatellites() {
+        return mSatellites.size();
+    }
+
+}
diff --git a/android/location/Location.java b/android/location/Location.java
new file mode 100644
index 0000000..9aa0c87
--- /dev/null
+++ b/android/location/Location.java
@@ -0,0 +1,1257 @@
+/*
+ * Copyright (C) 2007 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.location;
+
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.util.Printer;
+import android.util.TimeUtils;
+
+import java.text.DecimalFormat;
+import java.util.StringTokenizer;
+
+/**
+ * A data class representing a geographic location.
+ *
+ * <p>A location can consist of a latitude, longitude, timestamp,
+ * and other information such as bearing, altitude and velocity.
+ *
+ * <p>All locations generated by the {@link LocationManager} are
+ * guaranteed to have a valid latitude, longitude, and timestamp
+ * (both UTC time and elapsed real-time since boot), all other
+ * parameters are optional.
+ */
+public class Location implements Parcelable {
+    /**
+     * Constant used to specify formatting of a latitude or longitude
+     * in the form "[+-]DDD.DDDDD where D indicates degrees.
+     */
+    public static final int FORMAT_DEGREES = 0;
+
+    /**
+     * Constant used to specify formatting of a latitude or longitude
+     * in the form "[+-]DDD:MM.MMMMM" where D indicates degrees and
+     * M indicates minutes of arc (1 minute = 1/60th of a degree).
+     */
+    public static final int FORMAT_MINUTES = 1;
+
+    /**
+     * Constant used to specify formatting of a latitude or longitude
+     * in the form "DDD:MM:SS.SSSSS" where D indicates degrees, M
+     * indicates minutes of arc, and S indicates seconds of arc (1
+     * minute = 1/60th of a degree, 1 second = 1/3600th of a degree).
+     */
+    public static final int FORMAT_SECONDS = 2;
+
+    /**
+     * Bundle key for a version of the location containing no GPS data.
+     * Allows location providers to flag locations as being safe to
+     * feed to LocationFudger.
+     *
+     * @hide
+     * @deprecated As of Android R, this extra is longer in use, since it is not necessary to keep
+     * gps locations separate from other locations for coarsening. Providers that do not need to
+     * support platforms below Android R should not use this constant.
+     */
+    @TestApi
+    @SystemApi
+    @Deprecated
+    public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
+
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mAltitude.
+     */
+    private static final int HAS_ALTITUDE_MASK = 1;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mSpeed.
+     */
+    private static final int HAS_SPEED_MASK = 2;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mBearing.
+     */
+    private static final int HAS_BEARING_MASK = 4;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mHorizontalAccuracy.
+     */
+    private static final int HAS_HORIZONTAL_ACCURACY_MASK = 8;
+    /**
+     * Bit mask for mFieldsMask indicating location is from a mock provider.
+     */
+    private static final int HAS_MOCK_PROVIDER_MASK = 16;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mVerticalAccuracy.
+     */
+    private static final int HAS_VERTICAL_ACCURACY_MASK = 32;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mSpeedAccuracy.
+     */
+    private static final int HAS_SPEED_ACCURACY_MASK = 64;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mBearingAccuracy.
+     */
+    private static final int HAS_BEARING_ACCURACY_MASK = 128;
+    /**
+     * Bit mask for mFieldsMask indicating the presence of mElapsedRealtimeUncertaintyNanos.
+     */
+    private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK = 256;
+
+    // Cached data to make bearing/distance computations more efficient for the case
+    // where distanceTo and bearingTo are called in sequence.  Assume this typically happens
+    // on the same thread for caching purposes.
+    private static ThreadLocal<BearingDistanceCache> sBearingDistanceCache
+            = new ThreadLocal<BearingDistanceCache>() {
+        @Override
+        protected BearingDistanceCache initialValue() {
+            return new BearingDistanceCache();
+        }
+    };
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private String mProvider;
+    private long mTime = 0;
+    @UnsupportedAppUsage
+    private long mElapsedRealtimeNanos = 0;
+    // Estimate of the relative precision of the alignment of this SystemClock
+    // timestamp, with the reported measurements in nanoseconds (68% confidence).
+    private double mElapsedRealtimeUncertaintyNanos = 0.0f;
+    private double mLatitude = 0.0;
+    private double mLongitude = 0.0;
+    private double mAltitude = 0.0f;
+    private float mSpeed = 0.0f;
+    private float mBearing = 0.0f;
+    private float mHorizontalAccuracyMeters = 0.0f;
+    private float mVerticalAccuracyMeters = 0.0f;
+    private float mSpeedAccuracyMetersPerSecond = 0.0f;
+    private float mBearingAccuracyDegrees = 0.0f;
+
+    private Bundle mExtras = null;
+
+    // A bitmask of fields present in this object (see HAS_* constants defined above).
+    private int mFieldsMask = 0;
+
+    /**
+     * Construct a new Location with a named provider.
+     *
+     * <p>By default time, latitude and longitude are 0, and the location
+     * has no bearing, altitude, speed, accuracy or extras.
+     *
+     * @param provider the source that provides the location. It can be of type
+     * {@link LocationManager#GPS_PROVIDER}, {@link LocationManager#NETWORK_PROVIDER},
+     * or {@link LocationManager#PASSIVE_PROVIDER}. You can also define your own
+     * provider string, in which case an empty string is a valid provider.
+     */
+    public Location(String provider) {
+        mProvider = provider;
+    }
+
+    /**
+     * Construct a new Location object that is copied from an existing one.
+     */
+    public Location(Location l) {
+        set(l);
+    }
+
+    /**
+     * Sets the contents of the location to the values from the given location.
+     */
+    public void set(Location l) {
+        mProvider = l.mProvider;
+        mTime = l.mTime;
+        mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
+        mElapsedRealtimeUncertaintyNanos = l.mElapsedRealtimeUncertaintyNanos;
+        mFieldsMask = l.mFieldsMask;
+        mLatitude = l.mLatitude;
+        mLongitude = l.mLongitude;
+        mAltitude = l.mAltitude;
+        mSpeed = l.mSpeed;
+        mBearing = l.mBearing;
+        mHorizontalAccuracyMeters = l.mHorizontalAccuracyMeters;
+        mVerticalAccuracyMeters = l.mVerticalAccuracyMeters;
+        mSpeedAccuracyMetersPerSecond = l.mSpeedAccuracyMetersPerSecond;
+        mBearingAccuracyDegrees = l.mBearingAccuracyDegrees;
+        mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras);
+    }
+
+    /**
+     * Clears the contents of the location.
+     */
+    public void reset() {
+        mProvider = null;
+        mTime = 0;
+        mElapsedRealtimeNanos = 0;
+        mElapsedRealtimeUncertaintyNanos = 0.0;
+        mFieldsMask = 0;
+        mLatitude = 0;
+        mLongitude = 0;
+        mAltitude = 0;
+        mSpeed = 0;
+        mBearing = 0;
+        mHorizontalAccuracyMeters = 0;
+        mVerticalAccuracyMeters = 0;
+        mSpeedAccuracyMetersPerSecond = 0;
+        mBearingAccuracyDegrees = 0;
+        mExtras = null;
+    }
+
+    /**
+     * Converts a coordinate to a String representation. The outputType
+     * may be one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
+     * The coordinate must be a valid double between -180.0 and 180.0.
+     * This conversion is performed in a method that is dependent on the
+     * default locale, and so is not guaranteed to round-trip with
+     * {@link #convert(String)}.
+     *
+     * @throws IllegalArgumentException if coordinate is less than
+     * -180.0, greater than 180.0, or is not a number.
+     * @throws IllegalArgumentException if outputType is not one of
+     * FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
+     */
+    public static String convert(double coordinate, int outputType) {
+        if (coordinate < -180.0 || coordinate > 180.0 ||
+            Double.isNaN(coordinate)) {
+            throw new IllegalArgumentException("coordinate=" + coordinate);
+        }
+        if ((outputType != FORMAT_DEGREES) &&
+            (outputType != FORMAT_MINUTES) &&
+            (outputType != FORMAT_SECONDS)) {
+            throw new IllegalArgumentException("outputType=" + outputType);
+        }
+
+        StringBuilder sb = new StringBuilder();
+
+        // Handle negative values
+        if (coordinate < 0) {
+            sb.append('-');
+            coordinate = -coordinate;
+        }
+
+        DecimalFormat df = new DecimalFormat("###.#####");
+        if (outputType == FORMAT_MINUTES || outputType == FORMAT_SECONDS) {
+            int degrees = (int) Math.floor(coordinate);
+            sb.append(degrees);
+            sb.append(':');
+            coordinate -= degrees;
+            coordinate *= 60.0;
+            if (outputType == FORMAT_SECONDS) {
+                int minutes = (int) Math.floor(coordinate);
+                sb.append(minutes);
+                sb.append(':');
+                coordinate -= minutes;
+                coordinate *= 60.0;
+            }
+        }
+        sb.append(df.format(coordinate));
+        return sb.toString();
+    }
+
+    /**
+     * Converts a String in one of the formats described by
+     * FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS into a
+     * double. This conversion is performed in a locale agnostic
+     * method, and so is not guaranteed to round-trip with
+     * {@link #convert(double, int)}.
+     *
+     * @throws NullPointerException if coordinate is null
+     * @throws IllegalArgumentException if the coordinate is not
+     * in one of the valid formats.
+     */
+    public static double convert(String coordinate) {
+        // IllegalArgumentException if bad syntax
+        if (coordinate == null) {
+            throw new NullPointerException("coordinate");
+        }
+
+        boolean negative = false;
+        if (coordinate.charAt(0) == '-') {
+            coordinate = coordinate.substring(1);
+            negative = true;
+        }
+
+        StringTokenizer st = new StringTokenizer(coordinate, ":");
+        int tokens = st.countTokens();
+        if (tokens < 1) {
+            throw new IllegalArgumentException("coordinate=" + coordinate);
+        }
+        try {
+            String degrees = st.nextToken();
+            double val;
+            if (tokens == 1) {
+                val = Double.parseDouble(degrees);
+                return negative ? -val : val;
+            }
+
+            String minutes = st.nextToken();
+            int deg = Integer.parseInt(degrees);
+            double min;
+            double sec = 0.0;
+            boolean secPresent = false;
+
+            if (st.hasMoreTokens()) {
+                min = Integer.parseInt(minutes);
+                String seconds = st.nextToken();
+                sec = Double.parseDouble(seconds);
+                secPresent = true;
+            } else {
+                min = Double.parseDouble(minutes);
+            }
+
+            boolean isNegative180 = negative && (deg == 180) &&
+                (min == 0) && (sec == 0);
+
+            // deg must be in [0, 179] except for the case of -180 degrees
+            if ((deg < 0.0) || (deg > 179 && !isNegative180)) {
+                throw new IllegalArgumentException("coordinate=" + coordinate);
+            }
+
+            // min must be in [0, 59] if seconds are present, otherwise [0.0, 60.0)
+            if (min < 0 || min >= 60 || (secPresent && (min > 59))) {
+                throw new IllegalArgumentException("coordinate=" +
+                        coordinate);
+            }
+
+            // sec must be in [0.0, 60.0)
+            if (sec < 0 || sec >= 60) {
+                throw new IllegalArgumentException("coordinate=" +
+                        coordinate);
+            }
+
+            val = deg*3600.0 + min*60.0 + sec;
+            val /= 3600.0;
+            return negative ? -val : val;
+        } catch (NumberFormatException nfe) {
+            throw new IllegalArgumentException("coordinate=" + coordinate);
+        }
+    }
+
+    private static void computeDistanceAndBearing(double lat1, double lon1,
+        double lat2, double lon2, BearingDistanceCache results) {
+        // Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+        // using the "Inverse Formula" (section 4)
+
+        int MAXITERS = 20;
+        // Convert lat/long to radians
+        lat1 *= Math.PI / 180.0;
+        lat2 *= Math.PI / 180.0;
+        lon1 *= Math.PI / 180.0;
+        lon2 *= Math.PI / 180.0;
+
+        double a = 6378137.0; // WGS84 major axis
+        double b = 6356752.3142; // WGS84 semi-major axis
+        double f = (a - b) / a;
+        double aSqMinusBSqOverBSq = (a * a - b * b) / (b * b);
+
+        double L = lon2 - lon1;
+        double A = 0.0;
+        double U1 = Math.atan((1.0 - f) * Math.tan(lat1));
+        double U2 = Math.atan((1.0 - f) * Math.tan(lat2));
+
+        double cosU1 = Math.cos(U1);
+        double cosU2 = Math.cos(U2);
+        double sinU1 = Math.sin(U1);
+        double sinU2 = Math.sin(U2);
+        double cosU1cosU2 = cosU1 * cosU2;
+        double sinU1sinU2 = sinU1 * sinU2;
+
+        double sigma = 0.0;
+        double deltaSigma = 0.0;
+        double cosSqAlpha = 0.0;
+        double cos2SM = 0.0;
+        double cosSigma = 0.0;
+        double sinSigma = 0.0;
+        double cosLambda = 0.0;
+        double sinLambda = 0.0;
+
+        double lambda = L; // initial guess
+        for (int iter = 0; iter < MAXITERS; iter++) {
+            double lambdaOrig = lambda;
+            cosLambda = Math.cos(lambda);
+            sinLambda = Math.sin(lambda);
+            double t1 = cosU2 * sinLambda;
+            double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;
+            double sinSqSigma = t1 * t1 + t2 * t2; // (14)
+            sinSigma = Math.sqrt(sinSqSigma);
+            cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15)
+            sigma = Math.atan2(sinSigma, cosSigma); // (16)
+            double sinAlpha = (sinSigma == 0) ? 0.0 :
+                cosU1cosU2 * sinLambda / sinSigma; // (17)
+            cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
+            cos2SM = (cosSqAlpha == 0) ? 0.0 :
+                cosSigma - 2.0 * sinU1sinU2 / cosSqAlpha; // (18)
+
+            double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defn
+            A = 1 + (uSquared / 16384.0) * // (3)
+                (4096.0 + uSquared *
+                 (-768 + uSquared * (320.0 - 175.0 * uSquared)));
+            double B = (uSquared / 1024.0) * // (4)
+                (256.0 + uSquared *
+                 (-128.0 + uSquared * (74.0 - 47.0 * uSquared)));
+            double C = (f / 16.0) *
+                cosSqAlpha *
+                (4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10)
+            double cos2SMSq = cos2SM * cos2SM;
+            deltaSigma = B * sinSigma * // (6)
+                (cos2SM + (B / 4.0) *
+                 (cosSigma * (-1.0 + 2.0 * cos2SMSq) -
+                  (B / 6.0) * cos2SM *
+                  (-3.0 + 4.0 * sinSigma * sinSigma) *
+                  (-3.0 + 4.0 * cos2SMSq)));
+
+            lambda = L +
+                (1.0 - C) * f * sinAlpha *
+                (sigma + C * sinSigma *
+                 (cos2SM + C * cosSigma *
+                  (-1.0 + 2.0 * cos2SM * cos2SM))); // (11)
+
+            double delta = (lambda - lambdaOrig) / lambda;
+            if (Math.abs(delta) < 1.0e-12) {
+                break;
+            }
+        }
+
+        float distance = (float) (b * A * (sigma - deltaSigma));
+        results.mDistance = distance;
+        float initialBearing = (float) Math.atan2(cosU2 * sinLambda,
+            cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
+        initialBearing *= 180.0 / Math.PI;
+        results.mInitialBearing = initialBearing;
+        float finalBearing = (float) Math.atan2(cosU1 * sinLambda,
+                -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);
+        finalBearing *= 180.0 / Math.PI;
+        results.mFinalBearing = finalBearing;
+        results.mLat1 = lat1;
+        results.mLat2 = lat2;
+        results.mLon1 = lon1;
+        results.mLon2 = lon2;
+    }
+
+    /**
+     * Computes the approximate distance in meters between two
+     * locations, and optionally the initial and final bearings of the
+     * shortest path between them.  Distance and bearing are defined using the
+     * WGS84 ellipsoid.
+     *
+     * <p> The computed distance is stored in results[0].  If results has length
+     * 2 or greater, the initial bearing is stored in results[1]. If results has
+     * length 3 or greater, the final bearing is stored in results[2].
+     *
+     * @param startLatitude the starting latitude
+     * @param startLongitude the starting longitude
+     * @param endLatitude the ending latitude
+     * @param endLongitude the ending longitude
+     * @param results an array of floats to hold the results
+     *
+     * @throws IllegalArgumentException if results is null or has length < 1
+     */
+    public static void distanceBetween(double startLatitude, double startLongitude,
+        double endLatitude, double endLongitude, float[] results) {
+        if (results == null || results.length < 1) {
+            throw new IllegalArgumentException("results is null or has length < 1");
+        }
+        BearingDistanceCache cache = sBearingDistanceCache.get();
+        computeDistanceAndBearing(startLatitude, startLongitude,
+                endLatitude, endLongitude, cache);
+        results[0] = cache.mDistance;
+        if (results.length > 1) {
+            results[1] = cache.mInitialBearing;
+            if (results.length > 2) {
+                results[2] = cache.mFinalBearing;
+            }
+        }
+    }
+
+    /**
+     * Returns the approximate distance in meters between this
+     * location and the given location.  Distance is defined using
+     * the WGS84 ellipsoid.
+     *
+     * @param dest the destination location
+     * @return the approximate distance in meters
+     */
+    public float distanceTo(Location dest) {
+        BearingDistanceCache cache = sBearingDistanceCache.get();
+        // See if we already have the result
+        if (mLatitude != cache.mLat1 || mLongitude != cache.mLon1 ||
+            dest.mLatitude != cache.mLat2 || dest.mLongitude != cache.mLon2) {
+            computeDistanceAndBearing(mLatitude, mLongitude,
+                dest.mLatitude, dest.mLongitude, cache);
+        }
+        return cache.mDistance;
+    }
+
+    /**
+     * Returns the approximate initial bearing in degrees East of true
+     * North when traveling along the shortest path between this
+     * location and the given location.  The shortest path is defined
+     * using the WGS84 ellipsoid.  Locations that are (nearly)
+     * antipodal may produce meaningless results.
+     *
+     * @param dest the destination location
+     * @return the initial bearing in degrees
+     */
+    public float bearingTo(Location dest) {
+        BearingDistanceCache cache = sBearingDistanceCache.get();
+        // See if we already have the result
+        if (mLatitude != cache.mLat1 || mLongitude != cache.mLon1 ||
+                        dest.mLatitude != cache.mLat2 || dest.mLongitude != cache.mLon2) {
+            computeDistanceAndBearing(mLatitude, mLongitude,
+                dest.mLatitude, dest.mLongitude, cache);
+        }
+        return cache.mInitialBearing;
+    }
+
+    /**
+     * Returns the name of the provider that generated this fix.
+     *
+     * @return the provider, or null if it has not been set
+     */
+    public String getProvider() {
+        return mProvider;
+    }
+
+    /**
+     * Sets the name of the provider that generated this fix.
+     */
+    public void setProvider(String provider) {
+        mProvider = provider;
+    }
+
+    /**
+     * Return the UTC time of this fix, in milliseconds since January 1, 1970.
+     *
+     * <p>Note that the UTC time on a device is not monotonic: it
+     * can jump forwards or backwards unpredictably. So always use
+     * {@link #getElapsedRealtimeNanos} when calculating time deltas.
+     *
+     * <p>On the other hand, {@link #getTime} is useful for presenting
+     * a human readable time to the user, or for carefully comparing
+     * location fixes across reboot or across devices.
+     *
+     * <p>All locations generated by the {@link LocationManager}
+     * are guaranteed to have a valid UTC time, however remember that
+     * the system time may have changed since the location was generated.
+     *
+     * @return time of fix, in milliseconds since January 1, 1970.
+     */
+    public long getTime() {
+        return mTime;
+    }
+
+    /**
+     * Set the UTC time of this fix, in milliseconds since January 1,
+     * 1970.
+     *
+     * @param time UTC time of this fix, in milliseconds since January 1, 1970
+     */
+    public void setTime(long time) {
+        mTime = time;
+    }
+
+    /**
+     * Return the time of this fix, in elapsed real-time since system boot.
+     *
+     * <p>This value can be reliably compared to
+     * {@link android.os.SystemClock#elapsedRealtimeNanos},
+     * to calculate the age of a fix and to compare Location fixes. This
+     * is reliable because elapsed real-time is guaranteed monotonic for
+     * each system boot and continues to increment even when the system
+     * is in deep sleep (unlike {@link #getTime}.
+     *
+     * <p>All locations generated by the {@link LocationManager}
+     * are guaranteed to have a valid elapsed real-time.
+     *
+     * @return elapsed real-time of fix, in nanoseconds since system boot.
+     */
+    public long getElapsedRealtimeNanos() {
+        return mElapsedRealtimeNanos;
+    }
+
+    /** @hide */
+    public long getElapsedRealtimeAgeNanos(long referenceRealtimeNs) {
+        return referenceRealtimeNs - mElapsedRealtimeNanos;
+    }
+
+    /** @hide */
+    public long getElapsedRealtimeAgeNanos() {
+        return getElapsedRealtimeAgeNanos(SystemClock.elapsedRealtimeNanos());
+    }
+
+    /**
+     * Set the time of this fix, in elapsed real-time since system boot.
+     *
+     * @param time elapsed real-time of fix, in nanoseconds since system boot.
+     */
+    public void setElapsedRealtimeNanos(long time) {
+        mElapsedRealtimeNanos = time;
+    }
+
+    /**
+     * Get estimate of the relative precision of the alignment of the
+     * ElapsedRealtimeNanos timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     *
+     * This means that we have 68% confidence that the true timestamp of the
+     * event is within ElapsedReatimeNanos +/- uncertainty.
+     *
+     * Example :
+     *   - getElapsedRealtimeNanos() returns 10000000
+     *   - getElapsedRealtimeUncertaintyNanos() returns 1000000 (equivalent to 1millisecond)
+     *   This means that the event most likely happened between 9000000 and 11000000.
+     *
+     * @return uncertainty of elapsed real-time of fix, in nanoseconds.
+     */
+    public double getElapsedRealtimeUncertaintyNanos() {
+        return mElapsedRealtimeUncertaintyNanos;
+    }
+
+    /**
+     * Set estimate of the relative precision of the alignment of the
+     * ElapsedRealtimeNanos timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     *
+     * @param time uncertainty of the elapsed real-time of fix, in nanoseconds.
+     */
+    public void setElapsedRealtimeUncertaintyNanos(double time) {
+        mElapsedRealtimeUncertaintyNanos = time;
+        mFieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
+    }
+
+    /**
+     * True if this location has a elapsed realtime accuracy.
+     */
+    public boolean hasElapsedRealtimeUncertaintyNanos() {
+        return (mFieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0;
+    }
+
+
+    /**
+     * Get the latitude, in degrees.
+     *
+     * <p>All locations generated by the {@link LocationManager}
+     * will have a valid latitude.
+     */
+    public double getLatitude() {
+        return mLatitude;
+    }
+
+    /**
+     * Set the latitude, in degrees.
+     */
+    public void setLatitude(double latitude) {
+        mLatitude = latitude;
+    }
+
+    /**
+     * Get the longitude, in degrees.
+     *
+     * <p>All locations generated by the {@link LocationManager}
+     * will have a valid longitude.
+     */
+    public double getLongitude() {
+        return mLongitude;
+    }
+
+    /**
+     * Set the longitude, in degrees.
+     */
+    public void setLongitude(double longitude) {
+        mLongitude = longitude;
+    }
+
+    /**
+     * True if this location has an altitude.
+     */
+    public boolean hasAltitude() {
+        return (mFieldsMask & HAS_ALTITUDE_MASK) != 0;
+    }
+
+    /**
+     * Get the altitude if available, in meters above the WGS 84 reference
+     * ellipsoid.
+     *
+     * <p>If this location does not have an altitude then 0.0 is returned.
+     */
+    public double getAltitude() {
+        return mAltitude;
+    }
+
+    /**
+     * Set the altitude, in meters above the WGS 84 reference ellipsoid.
+     *
+     * <p>Following this call {@link #hasAltitude} will return true.
+     */
+    public void setAltitude(double altitude) {
+        mAltitude = altitude;
+        mFieldsMask |= HAS_ALTITUDE_MASK;
+    }
+
+    /**
+     * Remove the altitude from this location.
+     *
+     * <p>Following this call {@link #hasAltitude} will return false,
+     * and {@link #getAltitude} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     */
+    @Deprecated
+    public void removeAltitude() {
+        mAltitude = 0.0f;
+        mFieldsMask &= ~HAS_ALTITUDE_MASK;
+    }
+
+    /**
+     * True if this location has a speed.
+     */
+    public boolean hasSpeed() {
+        return (mFieldsMask & HAS_SPEED_MASK) != 0;
+    }
+
+    /**
+     * Get the speed if it is available, in meters/second over ground.
+     *
+     * <p>If this location does not have a speed then 0.0 is returned.
+     */
+    public float getSpeed() {
+        return mSpeed;
+    }
+
+    /**
+     * Set the speed, in meters/second over ground.
+     *
+     * <p>Following this call {@link #hasSpeed} will return true.
+     */
+    public void setSpeed(float speed) {
+        mSpeed = speed;
+        mFieldsMask |= HAS_SPEED_MASK;
+    }
+
+    /**
+     * Remove the speed from this location.
+     *
+     * <p>Following this call {@link #hasSpeed} will return false,
+     * and {@link #getSpeed} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     */
+    @Deprecated
+    public void removeSpeed() {
+        mSpeed = 0.0f;
+        mFieldsMask &= ~HAS_SPEED_MASK;
+    }
+
+    /**
+     * True if this location has a bearing.
+     */
+    public boolean hasBearing() {
+        return (mFieldsMask & HAS_BEARING_MASK) != 0;
+    }
+
+    /**
+     * Get the bearing, in degrees.
+     *
+     * <p>Bearing is the horizontal direction of travel of this device,
+     * and is not related to the device orientation. It is guaranteed to
+     * be in the range (0.0, 360.0] if the device has a bearing.
+     *
+     * <p>If this location does not have a bearing then 0.0 is returned.
+     */
+    public float getBearing() {
+        return mBearing;
+    }
+
+    /**
+     * Set the bearing, in degrees.
+     *
+     * <p>Bearing is the horizontal direction of travel of this device,
+     * and is not related to the device orientation.
+     *
+     * <p>The input will be wrapped into the range (0.0, 360.0].
+     */
+    public void setBearing(float bearing) {
+        while (bearing < 0.0f) {
+            bearing += 360.0f;
+        }
+        while (bearing >= 360.0f) {
+            bearing -= 360.0f;
+        }
+        mBearing = bearing;
+        mFieldsMask |= HAS_BEARING_MASK;
+    }
+
+    /**
+     * Remove the bearing from this location.
+     *
+     * <p>Following this call {@link #hasBearing} will return false,
+     * and {@link #getBearing} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     */
+    @Deprecated
+    public void removeBearing() {
+        mBearing = 0.0f;
+        mFieldsMask &= ~HAS_BEARING_MASK;
+    }
+
+    /**
+     * True if this location has a horizontal accuracy.
+     *
+     * <p>All locations generated by the {@link LocationManager} have an horizontal accuracy.
+     */
+    public boolean hasAccuracy() {
+        return (mFieldsMask & HAS_HORIZONTAL_ACCURACY_MASK) != 0;
+    }
+
+    /**
+     * Get the estimated horizontal accuracy of this location, radial, in meters.
+     *
+     * <p>We define horizontal accuracy as the radius of 68% confidence. In other
+     * words, if you draw a circle centered at this location's
+     * latitude and longitude, and with a radius equal to the accuracy,
+     * then there is a 68% probability that the true location is inside
+     * the circle.
+     *
+     * <p>This accuracy estimation is only concerned with horizontal
+     * accuracy, and does not indicate the accuracy of bearing,
+     * velocity or altitude if those are included in this Location.
+     *
+     * <p>If this location does not have a horizontal accuracy, then 0.0 is returned.
+     * All locations generated by the {@link LocationManager} include horizontal accuracy.
+     */
+    public float getAccuracy() {
+        return mHorizontalAccuracyMeters;
+    }
+
+    /**
+     * Set the estimated horizontal accuracy of this location, meters.
+     *
+     * <p>See {@link #getAccuracy} for the definition of horizontal accuracy.
+     *
+     * <p>Following this call {@link #hasAccuracy} will return true.
+     */
+    public void setAccuracy(float horizontalAccuracy) {
+        mHorizontalAccuracyMeters = horizontalAccuracy;
+        mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
+    }
+
+    /**
+     * Remove the horizontal accuracy from this location.
+     *
+     * <p>Following this call {@link #hasAccuracy} will return false, and
+     * {@link #getAccuracy} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     */
+    @Deprecated
+    public void removeAccuracy() {
+        mHorizontalAccuracyMeters = 0.0f;
+        mFieldsMask &= ~HAS_HORIZONTAL_ACCURACY_MASK;
+    }
+
+    /**
+     * True if this location has a vertical accuracy.
+     */
+    public boolean hasVerticalAccuracy() {
+        return (mFieldsMask & HAS_VERTICAL_ACCURACY_MASK) != 0;
+    }
+
+    /**
+     * Get the estimated vertical accuracy of this location, in meters.
+     *
+     * <p>We define vertical accuracy at 68% confidence.  Specifically, as 1-side of the
+     * 2-sided range above and below the estimated altitude reported by {@link #getAltitude()},
+     * within which there is a 68% probability of finding the true altitude.
+     *
+     * <p>In the case where the underlying distribution is assumed Gaussian normal, this would be
+     * considered 1 standard deviation.
+     *
+     * <p>For example, if {@link #getAltitude()} returns 150, and
+     * {@link #getVerticalAccuracyMeters()} returns 20 then there is a 68% probability
+     * of the true altitude being between 130 and 170 meters.
+     *
+     * <p>If this location does not have a vertical accuracy, then 0.0 is returned.
+     */
+    public float getVerticalAccuracyMeters() {
+        return mVerticalAccuracyMeters;
+    }
+
+    /**
+     * Set the estimated vertical accuracy of this location, meters.
+     *
+     * <p>See {@link #getVerticalAccuracyMeters} for the definition of vertical accuracy.
+     *
+     * <p>Following this call {@link #hasVerticalAccuracy} will return true.
+     */
+    public void setVerticalAccuracyMeters(float verticalAccuracyMeters) {
+        mVerticalAccuracyMeters = verticalAccuracyMeters;
+        mFieldsMask |= HAS_VERTICAL_ACCURACY_MASK;
+    }
+
+    /**
+     * Remove the vertical accuracy from this location.
+     *
+     * <p>Following this call {@link #hasVerticalAccuracy} will return false, and
+     * {@link #getVerticalAccuracyMeters} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     * @removed
+     */
+    @Deprecated
+    public void removeVerticalAccuracy() {
+        mVerticalAccuracyMeters = 0.0f;
+        mFieldsMask &= ~HAS_VERTICAL_ACCURACY_MASK;
+    }
+
+    /**
+     * True if this location has a speed accuracy.
+     */
+    public boolean hasSpeedAccuracy() {
+        return (mFieldsMask & HAS_SPEED_ACCURACY_MASK) != 0;
+    }
+
+    /**
+     * Get the estimated speed accuracy of this location, in meters per second.
+     *
+     * <p>We define speed accuracy at 68% confidence.  Specifically, as 1-side of the
+     * 2-sided range above and below the estimated speed reported by {@link #getSpeed()},
+     * within which there is a 68% probability of finding the true speed.
+     *
+     * <p>In the case where the underlying
+     * distribution is assumed Gaussian normal, this would be considered 1 standard deviation.
+     *
+     * <p>For example, if {@link #getSpeed()} returns 5, and
+     * {@link #getSpeedAccuracyMetersPerSecond()} returns 1, then there is a 68% probability of
+     * the true speed being between 4 and 6 meters per second.
+     *
+     * <p>Note that the speed and speed accuracy is often better than would be obtained simply from
+     * differencing sequential positions, such as when the Doppler measurements from GNSS satellites
+     * are used.
+     *
+     * <p>If this location does not have a speed accuracy, then 0.0 is returned.
+     */
+    public float getSpeedAccuracyMetersPerSecond() {
+        return mSpeedAccuracyMetersPerSecond;
+    }
+
+    /**
+     * Set the estimated speed accuracy of this location, meters per second.
+     *
+     * <p>See {@link #getSpeedAccuracyMetersPerSecond} for the definition of speed accuracy.
+     *
+     * <p>Following this call {@link #hasSpeedAccuracy} will return true.
+     */
+    public void setSpeedAccuracyMetersPerSecond(float speedAccuracyMeterPerSecond) {
+        mSpeedAccuracyMetersPerSecond = speedAccuracyMeterPerSecond;
+        mFieldsMask |= HAS_SPEED_ACCURACY_MASK;
+    }
+
+    /**
+     * Remove the speed accuracy from this location.
+     *
+     * <p>Following this call {@link #hasSpeedAccuracy} will return false, and
+     * {@link #getSpeedAccuracyMetersPerSecond} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     * @removed
+     */
+    @Deprecated
+    public void removeSpeedAccuracy() {
+        mSpeedAccuracyMetersPerSecond = 0.0f;
+        mFieldsMask &= ~HAS_SPEED_ACCURACY_MASK;
+    }
+
+    /**
+     * True if this location has a bearing accuracy.
+     */
+    public boolean hasBearingAccuracy() {
+        return (mFieldsMask & HAS_BEARING_ACCURACY_MASK) != 0;
+    }
+
+    /**
+     * Get the estimated bearing accuracy of this location, in degrees.
+     *
+     * <p>We define bearing accuracy at 68% confidence.  Specifically, as 1-side of the
+     * 2-sided range on each side of the estimated bearing reported by {@link #getBearing()},
+     * within which there is a 68% probability of finding the true bearing.
+     *
+     * <p>In the case where the underlying distribution is assumed Gaussian normal, this would be
+     * considered 1 standard deviation.
+     *
+     * <p>For example, if {@link #getBearing()} returns 60, and
+     * {@link #getBearingAccuracyDegrees()} returns 10, then there is a 68% probability of the
+     * true bearing being between 50 and 70 degrees.
+     *
+     * <p>If this location does not have a bearing accuracy, then 0.0 is returned.
+     */
+    public float getBearingAccuracyDegrees() {
+        return mBearingAccuracyDegrees;
+    }
+
+    /**
+     * Set the estimated bearing accuracy of this location, degrees.
+     *
+     * <p>See {@link #getBearingAccuracyDegrees} for the definition of bearing accuracy.
+     *
+     * <p>Following this call {@link #hasBearingAccuracy} will return true.
+     */
+    public void setBearingAccuracyDegrees(float bearingAccuracyDegrees) {
+        mBearingAccuracyDegrees = bearingAccuracyDegrees;
+        mFieldsMask |= HAS_BEARING_ACCURACY_MASK;
+    }
+
+    /**
+     * Remove the bearing accuracy from this location.
+     *
+     * <p>Following this call {@link #hasBearingAccuracy} will return false, and
+     * {@link #getBearingAccuracyDegrees} will return 0.0.
+     *
+     * @deprecated use a new Location object for location updates.
+     * @removed
+     */
+    @Deprecated
+    public void removeBearingAccuracy() {
+        mBearingAccuracyDegrees = 0.0f;
+        mFieldsMask &= ~HAS_BEARING_ACCURACY_MASK;
+    }
+
+    /**
+     * Return true if this Location object is complete.
+     *
+     * <p>A location object is currently considered complete if it has
+     * a valid provider, accuracy, wall-clock time and elapsed real-time.
+     *
+     * <p>All locations supplied by the {@link LocationManager} to
+     * applications must be complete.
+     *
+     * @see #makeComplete
+     * @hide
+     */
+    @SystemApi
+    public boolean isComplete() {
+        if (mProvider == null) return false;
+        if (!hasAccuracy()) return false;
+        if (mTime == 0) return false;
+        if (mElapsedRealtimeNanos == 0) return false;
+        return true;
+    }
+
+    /**
+     * Helper to fill incomplete fields.
+     *
+     * <p>Used to assist in backwards compatibility with
+     * Location objects received from applications.
+     *
+     * @see #isComplete
+     * @hide
+     */
+    @TestApi
+    @SystemApi
+    public void makeComplete() {
+        if (mProvider == null) mProvider = "?";
+        if (!hasAccuracy()) {
+            mFieldsMask |= HAS_HORIZONTAL_ACCURACY_MASK;
+            mHorizontalAccuracyMeters = 100.0f;
+        }
+        if (mTime == 0) mTime = System.currentTimeMillis();
+        if (mElapsedRealtimeNanos == 0) mElapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos();
+    }
+
+    /**
+     * Returns additional provider-specific information about the
+     * location fix as a Bundle.  The keys and values are determined
+     * by the provider.  If no additional information is available,
+     * null is returned.
+     *
+     * <p> A number of common key/value pairs are listed
+     * below. Providers that use any of the keys on this list must
+     * provide the corresponding value as described below.
+     *
+     * <ul>
+     * <li> satellites - the number of satellites used to derive the fix
+     * </ul>
+     */
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Sets the extra information associated with this fix to the
+     * given Bundle.
+     *
+     * <p>Note this stores a copy of the given extras, so any changes to extras after calling this
+     * method won't be reflected in the location bundle.
+     */
+    public void setExtras(Bundle extras) {
+        mExtras = (extras == null) ? null : new Bundle(extras);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("Location[");
+        s.append(mProvider);
+        s.append(String.format(" %.6f,%.6f", mLatitude, mLongitude));
+        if (hasAccuracy()) s.append(String.format(" hAcc=%.0f", mHorizontalAccuracyMeters));
+        else s.append(" hAcc=???");
+        if (mTime == 0) {
+            s.append(" t=?!?");
+        }
+        if (mElapsedRealtimeNanos == 0) {
+            s.append(" et=?!?");
+        } else {
+            s.append(" et=");
+            TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
+        }
+        if (hasElapsedRealtimeUncertaintyNanos()) {
+            s.append(" etAcc=");
+            TimeUtils.formatDuration((long) (mElapsedRealtimeUncertaintyNanos / 1000000), s);
+        }
+        if (hasAltitude()) s.append(" alt=").append(mAltitude);
+        if (hasSpeed()) s.append(" vel=").append(mSpeed);
+        if (hasBearing()) s.append(" bear=").append(mBearing);
+        if (hasVerticalAccuracy()) s.append(String.format(" vAcc=%.0f", mVerticalAccuracyMeters));
+        else s.append(" vAcc=???");
+        if (hasSpeedAccuracy()) s.append(String.format(" sAcc=%.0f", mSpeedAccuracyMetersPerSecond));
+        else s.append(" sAcc=???");
+        if (hasBearingAccuracy()) s.append(String.format(" bAcc=%.0f", mBearingAccuracyDegrees));
+        else s.append(" bAcc=???");
+        if (isFromMockProvider()) s.append(" mock");
+
+        if (mExtras != null) {
+            s.append(" {").append(mExtras).append('}');
+        }
+        s.append(']');
+        return s.toString();
+    }
+
+    public void dump(Printer pw, String prefix) {
+        pw.println(prefix + toString());
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Location> CREATOR =
+        new Parcelable.Creator<Location>() {
+        @Override
+        public Location createFromParcel(Parcel in) {
+            String provider = in.readString();
+            Location l = new Location(provider);
+            l.mTime = in.readLong();
+            l.mElapsedRealtimeNanos = in.readLong();
+            l.mElapsedRealtimeUncertaintyNanos = in.readDouble();
+            l.mFieldsMask = in.readInt();
+            l.mLatitude = in.readDouble();
+            l.mLongitude = in.readDouble();
+            l.mAltitude = in.readDouble();
+            l.mSpeed = in.readFloat();
+            l.mBearing = in.readFloat();
+            l.mHorizontalAccuracyMeters = in.readFloat();
+            l.mVerticalAccuracyMeters = in.readFloat();
+            l.mSpeedAccuracyMetersPerSecond = in.readFloat();
+            l.mBearingAccuracyDegrees = in.readFloat();
+            l.mExtras = Bundle.setDefusable(in.readBundle(), true);
+            return l;
+        }
+
+        @Override
+        public Location[] newArray(int size) {
+            return new Location[size];
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mProvider);
+        parcel.writeLong(mTime);
+        parcel.writeLong(mElapsedRealtimeNanos);
+        parcel.writeDouble(mElapsedRealtimeUncertaintyNanos);
+        parcel.writeInt(mFieldsMask);
+        parcel.writeDouble(mLatitude);
+        parcel.writeDouble(mLongitude);
+        parcel.writeDouble(mAltitude);
+        parcel.writeFloat(mSpeed);
+        parcel.writeFloat(mBearing);
+        parcel.writeFloat(mHorizontalAccuracyMeters);
+        parcel.writeFloat(mVerticalAccuracyMeters);
+        parcel.writeFloat(mSpeedAccuracyMetersPerSecond);
+        parcel.writeFloat(mBearingAccuracyDegrees);
+        parcel.writeBundle(mExtras);
+    }
+
+    /**
+     * Returns one of the optional extra {@link Location}s that can be attached
+     * to this Location.
+     *
+     * @param key the key associated with the desired extra Location
+     * @return the extra Location, or null if unavailable
+     * @hide
+     */
+    public Location getExtraLocation(String key) {
+        if (mExtras != null) {
+            Parcelable value = mExtras.getParcelable(key);
+            if (value instanceof Location) {
+                return (Location) value;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns true if the Location came from a mock provider.
+     *
+     * @return true if this Location came from a mock provider, false otherwise
+     */
+    public boolean isFromMockProvider() {
+        return (mFieldsMask & HAS_MOCK_PROVIDER_MASK) != 0;
+    }
+
+    /**
+     * Flag this Location as having come from a mock provider or not.
+     *
+     * @param isFromMockProvider true if this Location came from a mock provider, false otherwise
+     * @hide
+     */
+    @SystemApi
+    public void setIsFromMockProvider(boolean isFromMockProvider) {
+        if (isFromMockProvider) {
+            mFieldsMask |= HAS_MOCK_PROVIDER_MASK;
+        } else {
+            mFieldsMask &= ~HAS_MOCK_PROVIDER_MASK;
+        }
+    }
+
+    /**
+     * Caches data used to compute distance and bearing (so successive calls to {@link #distanceTo}
+     * and {@link #bearingTo} don't duplicate work.
+     */
+    private static class BearingDistanceCache {
+        private double mLat1 = 0.0;
+        private double mLon1 = 0.0;
+        private double mLat2 = 0.0;
+        private double mLon2 = 0.0;
+        private float mDistance = 0.0f;
+        private float mInitialBearing = 0.0f;
+        private float mFinalBearing = 0.0f;
+    }
+}
diff --git a/android/location/LocationListener.java b/android/location/LocationListener.java
new file mode 100644
index 0000000..8df0834
--- /dev/null
+++ b/android/location/LocationListener.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 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.location;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+
+/**
+ * Used for receiving notifications from the LocationManager when
+ * the location has changed. These methods are called if the
+ * LocationListener has been registered with the location manager service
+ * using the {@link LocationManager#requestLocationUpdates(String, long, float, LocationListener)}
+ * method.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about identifying user location, read the
+ * <a href="{@docRoot}guide/topics/location/obtaining-user-location.html">Obtaining User
+ * Location</a> developer guide.</p>
+ * </div>
+ */
+public interface LocationListener {
+
+    /**
+     * Called when the location has changed.
+     *
+     * @param location the updated location
+     */
+    void onLocationChanged(@NonNull Location location);
+
+    /**
+     * This callback will never be invoked on Android Q and above, and providers can be considered
+     * as always in the {@link LocationProvider#AVAILABLE} state.
+     *
+     * @deprecated This callback will never be invoked on Android Q and above.
+     */
+    @Deprecated
+    default void onStatusChanged(String provider, int status, Bundle extras) {}
+
+    /**
+     * Called when the provider is enabled by the user.
+     *
+     * @param provider the name of the location provider that has become enabled
+     */
+    default void onProviderEnabled(@NonNull String provider) {}
+
+    /**
+     * Called when the provider is disabled by the user. If requestLocationUpdates
+     * is called on an already disabled provider, this method is called
+     * immediately.
+     *
+     * @param provider the name of the location provider that has become disabled
+     */
+    default void onProviderDisabled(@NonNull String provider) {}
+}
diff --git a/android/location/LocationManager.java b/android/location/LocationManager.java
new file mode 100644
index 0000000..412b43e
--- /dev/null
+++ b/android/location/LocationManager.java
@@ -0,0 +1,3190 @@
+/*
+ * Copyright (C) 2007 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.location;
+
+import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
+import static android.Manifest.permission.ACCESS_FINE_LOCATION;
+import static android.Manifest.permission.LOCATION_HARDWARE;
+import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
+import static android.app.AlarmManager.ELAPSED_REALTIME;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainRunnable;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.app.AlarmManager;
+import android.app.AppOpsManager;
+import android.app.PendingIntent;
+import android.app.PropertyInvalidatedCache;
+import android.compat.Compatibility;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.ICancellationSignal;
+import android.os.Looper;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.location.ProviderProperties;
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledRunnable;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.function.Consumer;
+
+/**
+ * This class provides access to the system location services. These services allow applications to
+ * obtain periodic updates of the device's geographical location, or to be notified when the device
+ * enters the proximity of a given geographical location.
+ *
+ * <p class="note">Unless noted, all Location API methods require the {@link
+ * android.Manifest.permission#ACCESS_COARSE_LOCATION} or {@link
+ * android.Manifest.permission#ACCESS_FINE_LOCATION} permissions. If your application only has the
+ * coarse permission then it will not have access to fine location providers. Other providers will
+ * still return location results, but the exact location will be obfuscated to a coarse level of
+ * accuracy.
+ */
+@SuppressWarnings({"deprecation"})
+@SystemService(Context.LOCATION_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_LOCATION)
+public class LocationManager {
+
+    @GuardedBy("mLock")
+    private PropertyInvalidatedCache<Integer, Boolean> mLocationEnabledCache =
+            new PropertyInvalidatedCache<Integer, Boolean>(
+                4,
+                CACHE_KEY_LOCATION_ENABLED_PROPERTY) {
+                @Override
+                protected Boolean recompute(Integer userHandle) {
+                    try {
+                        return mService.isLocationEnabledForUser(userHandle);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            };
+
+    private final Object mLock = new Object();
+
+    /**
+     * For apps targeting Android R and above, {@link #getProvider(String)} will no longer throw any
+     * security exceptions.
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+    private static final long GET_PROVIDER_SECURITY_EXCEPTIONS = 150935354L;
+
+    /**
+     * For apps targeting Android K and above, supplied {@link PendingIntent}s must be targeted to a
+     * specific package.
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
+    private static final long TARGETED_PENDING_INTENT = 148963590L;
+
+    /**
+     * For apps targeting Android K and above, incomplete locations may not be passed to
+     * {@link #setTestProviderLocation}.
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
+    private static final long INCOMPLETE_LOCATION = 148964793L;
+
+    /**
+     * For apps targeting Android S and above, all {@link GpsStatus} API usage must be replaced with
+     * {@link GnssStatus} APIs.
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
+    private static final long GPS_STATUS_USAGE = 144027538L;
+
+    /**
+     * Name of the network location provider.
+     *
+     * <p>This provider determines location based on nearby of cell tower and WiFi access points.
+     * Results are retrieved by means of a network lookup.
+     */
+    public static final String NETWORK_PROVIDER = "network";
+
+    /**
+     * Name of the GNSS location provider.
+     *
+     * <p>This provider determines location using GNSS satellites. Depending on conditions, this
+     * provider may take a while to return a location fix. Requires the
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission.
+     *
+     * <p>The extras Bundle for the GPS location provider can contain the following key/value pairs:
+     * <ul>
+     * <li> satellites - the number of satellites used to derive the fix
+     * </ul>
+     */
+    public static final String GPS_PROVIDER = "gps";
+
+    /**
+     * A special location provider for receiving locations without actually initiating a location
+     * fix.
+     *
+     * <p>This provider can be used to passively receive location updates when other applications or
+     * services request them without actually requesting the locations yourself. This provider will
+     * only return locations generated by other providers.  You can query the
+     * {@link Location#getProvider()} method to determine the actual provider that supplied the
+     * location update. Requires the {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission, although there is no guarantee of fine locations.
+     */
+    public static final String PASSIVE_PROVIDER = "passive";
+
+    /**
+     * The fused location provider.
+     *
+     * <p>This provider combines may combine inputs from several location sources to provide the
+     * best possible location fix. It is implicitly used for all API's that involve the
+     * {@link LocationRequest} object.
+     *
+     * @hide
+     */
+    @TestApi
+    public static final String FUSED_PROVIDER = "fused";
+
+    /**
+     * Key used for the Bundle extra holding a boolean indicating whether
+     * a proximity alert is entering (true) or exiting (false)..
+     */
+    public static final String KEY_PROXIMITY_ENTERING = "entering";
+
+    /**
+     * This key is no longer in use.
+     *
+     * <p>Key used for a Bundle extra holding an Integer status value when a status change is
+     * broadcast using a PendingIntent.
+     *
+     * @deprecated Status changes are deprecated and no longer broadcast from Android Q onwards.
+     */
+    @Deprecated
+    public static final String KEY_STATUS_CHANGED = "status";
+
+    /**
+     * Key used for an extra holding a boolean enabled/disabled status value when a provider
+     * enabled/disabled event is broadcast using a PendingIntent.
+     *
+     * @see #requestLocationUpdates(String, long, float, PendingIntent)
+     */
+    public static final String KEY_PROVIDER_ENABLED = "providerEnabled";
+
+    /**
+     * Key used for an extra holding a {@link Location} value when a location change is broadcast
+     * using a PendingIntent.
+     *
+     * @see #requestLocationUpdates(String, long, float, PendingIntent)
+     */
+    public static final String KEY_LOCATION_CHANGED = "location";
+
+    /**
+     * Broadcast intent action when the set of enabled location providers changes. To check the
+     * status of a provider, use {@link #isProviderEnabled(String)}. From Android Q and above, will
+     * include a string intent extra, {@link #EXTRA_PROVIDER_NAME}, with the name of the provider
+     * whose state has changed. From Android R and above, will include a boolean intent extra,
+     * {@link #EXTRA_PROVIDER_ENABLED}, with the enabled state of the provider.
+     *
+     * @see #EXTRA_PROVIDER_NAME
+     * @see #EXTRA_PROVIDER_ENABLED
+     * @see #isProviderEnabled(String)
+     */
+    public static final String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
+
+    /**
+     * Intent extra included with {@link #PROVIDERS_CHANGED_ACTION} broadcasts, containing the name
+     * of the location provider that has changed.
+     *
+     * @see #PROVIDERS_CHANGED_ACTION
+     * @see #EXTRA_PROVIDER_ENABLED
+     */
+    public static final String EXTRA_PROVIDER_NAME = "android.location.extra.PROVIDER_NAME";
+
+    /**
+     * Intent extra included with {@link #PROVIDERS_CHANGED_ACTION} broadcasts, containing the
+     * boolean enabled state of the location provider that has changed.
+     *
+     * @see #PROVIDERS_CHANGED_ACTION
+     * @see #EXTRA_PROVIDER_NAME
+     */
+    public static final String EXTRA_PROVIDER_ENABLED = "android.location.extra.PROVIDER_ENABLED";
+
+    /**
+     * Broadcast intent action when the device location enabled state changes. From Android R and
+     * above, will include a boolean intent extra, {@link #EXTRA_LOCATION_ENABLED}, with the enabled
+     * state of location.
+     *
+     * @see #EXTRA_LOCATION_ENABLED
+     * @see #isLocationEnabled()
+     */
+    public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
+
+    /**
+     * Intent extra included with {@link #MODE_CHANGED_ACTION} broadcasts, containing the boolean
+     * enabled state of location.
+     *
+     * @see #MODE_CHANGED_ACTION
+     */
+    public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED";
+
+    /**
+     * Broadcast intent action indicating that a high power location requests
+     * has either started or stopped being active.  The current state of
+     * active location requests should be read from AppOpsManager using
+     * {@code OP_MONITOR_HIGH_POWER_LOCATION}.
+     *
+     * @hide
+     */
+    public static final String HIGH_POWER_REQUEST_CHANGE_ACTION =
+            "android.location.HIGH_POWER_REQUEST_CHANGE";
+
+    /**
+     * Broadcast intent action for Settings app to inject a footer at the bottom of location
+     * settings. This is for use only by apps that are included in the system image.
+     *
+     * <p>To inject a footer to location settings, you must declare a broadcast receiver for
+     * this action in the manifest:
+     * <pre>
+     *     &lt;receiver android:name="com.example.android.footer.MyFooterInjector"&gt;
+     *         &lt;intent-filter&gt;
+     *             &lt;action android:name="com.android.settings.location.INJECT_FOOTER" /&gt;
+     *         &lt;/intent-filter&gt;
+     *         &lt;meta-data
+     *             android:name="com.android.settings.location.FOOTER_STRING"
+     *             android:resource="@string/my_injected_footer_string" /&gt;
+     *     &lt;/receiver&gt;
+     * </pre>
+     *
+     * <p>This broadcast receiver will never actually be invoked. See also
+     * {#METADATA_SETTINGS_FOOTER_STRING}.
+     *
+     * @hide
+     */
+    public static final String SETTINGS_FOOTER_DISPLAYED_ACTION =
+            "com.android.settings.location.DISPLAYED_FOOTER";
+
+    /**
+     * Metadata name for {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast
+     * receivers to specify a string resource id as location settings footer text. This is for use
+     * only by apps that are included in the system image.
+     *
+     * <p>See {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} for more detail on how to use.
+     *
+     * @hide
+     */
+    public static final String METADATA_SETTINGS_FOOTER_STRING =
+            "com.android.settings.location.FOOTER_STRING";
+
+    private static final long GET_CURRENT_LOCATION_MAX_TIMEOUT_MS = 30 * 1000;
+
+    private final Context mContext;
+
+    @UnsupportedAppUsage
+    private final ILocationManager mService;
+
+    @GuardedBy("mListeners")
+    private final ArrayMap<LocationListener, LocationListenerTransport> mListeners =
+            new ArrayMap<>();
+
+    @GuardedBy("mBatchedLocationCallbackManager")
+    private final BatchedLocationCallbackManager mBatchedLocationCallbackManager =
+            new BatchedLocationCallbackManager();
+    private final GnssStatusListenerManager
+            mGnssStatusListenerManager = new GnssStatusListenerManager();
+    private final GnssMeasurementsListenerManager mGnssMeasurementsListenerManager =
+            new GnssMeasurementsListenerManager();
+    private final GnssNavigationMessageListenerManager mGnssNavigationMessageListenerTransport =
+            new GnssNavigationMessageListenerManager();
+    private final GnssAntennaInfoListenerManager mGnssAntennaInfoListenerManager =
+            new GnssAntennaInfoListenerManager();
+
+    /**
+     * @hide
+     */
+    public LocationManager(@NonNull Context context, @NonNull ILocationManager service) {
+        mService = service;
+        mContext = context;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public @NonNull String[] getBackgroundThrottlingWhitelist() {
+        try {
+            return mService.getBackgroundThrottlingWhitelist();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public @NonNull String[] getIgnoreSettingsWhitelist() {
+        try {
+            return mService.getIgnoreSettingsWhitelist();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the extra location controller package on the device.
+     *
+     * @hide
+     */
+    @SystemApi
+    public @Nullable String getExtraLocationControllerPackage() {
+        try {
+            return mService.getExtraLocationControllerPackage();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+            return null;
+        }
+    }
+
+    /**
+     * Set the extra location controller package for location services on the device.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public void setExtraLocationControllerPackage(@Nullable String packageName) {
+        try {
+            mService.setExtraLocationControllerPackage(packageName);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set whether the extra location controller package is currently enabled on the device.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public void setExtraLocationControllerPackageEnabled(boolean enabled) {
+        try {
+            mService.setExtraLocationControllerPackageEnabled(enabled);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether extra location controller package is currently enabled on the device.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isExtraLocationControllerPackageEnabled() {
+        try {
+            return mService.isExtraLocationControllerPackageEnabled();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+            return false;
+        }
+    }
+
+    /**
+     * Set the extra location controller package for location services on the device.
+     *
+     * @removed
+     * @deprecated Use {@link #setExtraLocationControllerPackage} instead.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public void setLocationControllerExtraPackage(String packageName) {
+        try {
+            mService.setExtraLocationControllerPackage(packageName);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set whether the extra location controller package is currently enabled on the device.
+     *
+     * @removed
+     * @deprecated Use {@link #setExtraLocationControllerPackageEnabled} instead.
+     * @hide
+     */
+    @SystemApi
+    @Deprecated
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public void setLocationControllerExtraPackageEnabled(boolean enabled) {
+        try {
+            mService.setExtraLocationControllerPackageEnabled(enabled);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current enabled/disabled state of location. To listen for changes, see
+     * {@link #MODE_CHANGED_ACTION}.
+     *
+     * @return true if location is enabled and false if location is disabled.
+     */
+    public boolean isLocationEnabled() {
+        return isLocationEnabledForUser(Process.myUserHandle());
+    }
+
+    /**
+     * Returns the current enabled/disabled state of location for the given user.
+     *
+     * @param userHandle the user to query
+     * @return true if location is enabled and false if location is disabled.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isLocationEnabledForUser(@NonNull UserHandle userHandle) {
+        synchronized (mLock) {
+            if (mLocationEnabledCache != null) {
+                return mLocationEnabledCache.query(userHandle.getIdentifier());
+            }
+        }
+
+        // fallback if cache is disabled
+        try {
+            return mService.isLocationEnabledForUser(userHandle.getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Enables or disables location for the given user.
+     *
+     * @param enabled true to enable location and false to disable location.
+     * @param userHandle the user to set
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(WRITE_SECURE_SETTINGS)
+    public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) {
+        try {
+            mService.setLocationEnabledForUser(enabled, userHandle.getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current enabled/disabled status of the given provider. To listen for changes, see
+     * {@link #PROVIDERS_CHANGED_ACTION}.
+     *
+     * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw
+     * {@link SecurityException} if the location permissions were not sufficient to use the
+     * specified provider.
+     *
+     * @param provider a provider listed by {@link #getAllProviders()}
+     * @return true if the provider exists and is enabled
+     *
+     * @throws IllegalArgumentException if provider is null
+     */
+    public boolean isProviderEnabled(@NonNull String provider) {
+        return isProviderEnabledForUser(provider, Process.myUserHandle());
+    }
+
+    /**
+     * Returns the current enabled/disabled status of the given provider and user. Callers should
+     * prefer {@link #isLocationEnabledForUser(UserHandle)} unless they depend on provider-specific
+     * APIs.
+     *
+     * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw
+     * {@link SecurityException} if the location permissions were not sufficient to use the
+     * specified provider.
+     *
+     * @param provider a provider listed by {@link #getAllProviders()}
+     * @param userHandle the user to query
+     * @return true if the provider exists and is enabled
+     *
+     * @throws IllegalArgumentException if provider is null
+     * @hide
+     */
+    @SystemApi
+    public boolean isProviderEnabledForUser(
+            @NonNull String provider, @NonNull UserHandle userHandle) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        try {
+            return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Method for enabling or disabling a single location provider. This method is deprecated and
+     * functions as a best effort. It should not be relied on in any meaningful sense as providers
+     * may no longer be enabled or disabled by clients.
+     *
+     * @param provider a provider listed by {@link #getAllProviders()}
+     * @param enabled whether to enable or disable the provider
+     * @param userHandle the user to set
+     * @return true if the value was set, false otherwise
+     *
+     * @throws IllegalArgumentException if provider is null
+     * @deprecated Do not manipulate providers individually, use
+     * {@link #setLocationEnabledForUser(boolean, UserHandle)} instead.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    @RequiresPermission(WRITE_SECURE_SETTINGS)
+    public boolean setProviderEnabledForUser(
+            @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        return Settings.Secure.putStringForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
+                (enabled ? "+" : "-") + provider,
+                userHandle.getIdentifier());
+    }
+
+    /**
+     * Gets the last known location from the fused provider, or null if there is no last known
+     * location. The returned location may be quite old in some circumstances, so the age of the
+     * location should always be checked.
+     *
+     * @return the last known location, or null if not available
+     * @throws SecurityException if no suitable location permission is present
+     *
+     * @hide
+     */
+    @Nullable
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public Location getLastLocation() {
+        try {
+            return mService.getLastLocation(null, mContext.getPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets the last known location from the given provider, or null if there is no last known
+     * location. The returned location may be quite old in some circumstances, so the age of the
+     * location should always be checked.
+     *
+     * <p>This will never activate sensors to compute a new location, and will only ever return a
+     * cached location.
+     *
+     * <p>See also {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} which
+     * will always attempt to return a current location, but will potentially use additional power
+     * in the course of the attempt as compared to this method.
+     *
+     * @param provider a provider listed by {@link #getAllProviders()}
+     * @return the last known location for the given provider, or null if not available
+     * @throws SecurityException if no suitable permission is present
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    @Nullable
+    public Location getLastKnownLocation(@NonNull String provider) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                provider, 0, 0, true);
+
+        try {
+            return mService.getLastLocation(request, mContext.getPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Asynchronously returns a single current location fix. This may activate sensors in order to
+     * compute a new location, unlike {@link #getLastKnownLocation(String)}, which will only return
+     * a cached fix if available. The given callback will be invoked once and only once, either with
+     * a valid location fix or with a null location fix if the provider was unable to generate a
+     * valid location.
+     *
+     * <p>A client may supply an optional {@link CancellationSignal}. If this is used to cancel the
+     * operation, no callback should be expected after the cancellation.
+     *
+     * <p>This method may return locations from the very recent past (on the order of several
+     * seconds), but will never return older locations (for example, several minutes old or older).
+     * Clients may rely upon the guarantee that if this method returns a location, it will represent
+     * the best estimation of the location of the device in the present moment.
+     *
+     * <p>Clients calling this method from the background may notice that the method fails to
+     * determine a valid location fix more often than while in the foreground. Background
+     * applications may be throttled in their location accesses to some degree.
+     *
+     * @param provider           a provider listed by {@link #getAllProviders()}
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor           the callback will take place on this {@link Executor}
+     * @param consumer           the callback invoked with either a {@link Location} or null
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if consumer is null
+     * @throws SecurityException        if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void getCurrentLocation(@NonNull String provider,
+            @Nullable CancellationSignal cancellationSignal,
+            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) {
+        getCurrentLocation(LocationRequest.createFromDeprecatedProvider(provider, 0, 0, true),
+                cancellationSignal, executor, consumer);
+    }
+
+    /**
+     * Asynchronously returns a single current location fix based on the given
+     * {@link LocationRequest}.
+     *
+     * <p>See {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} for more
+     * information.
+     *
+     * @param locationRequest    the location request containing location parameters
+     * @param cancellationSignal an optional signal that allows for cancelling this call
+     * @param executor           the callback will take place on this {@link Executor}
+     * @param consumer           the callback invoked with either a {@link Location} or null
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if consumer is null
+     * @throws SecurityException        if no suitable permission is present
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void getCurrentLocation(@NonNull LocationRequest locationRequest,
+            @Nullable CancellationSignal cancellationSignal,
+            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) {
+        LocationRequest currentLocationRequest = new LocationRequest(locationRequest)
+                .setNumUpdates(1);
+        if (currentLocationRequest.getExpireIn() > GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) {
+            currentLocationRequest.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
+        }
+
+        GetCurrentLocationTransport transport = new GetCurrentLocationTransport(executor,
+                consumer);
+
+        if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
+        }
+
+        ICancellationSignal remoteCancellationSignal = CancellationSignal.createTransport();
+
+        try {
+            if (mService.getCurrentLocation(currentLocationRequest, remoteCancellationSignal,
+                    transport, mContext.getPackageName(), mContext.getAttributionTag(),
+                    transport.getListenerId())) {
+                transport.register(mContext.getSystemService(AlarmManager.class),
+                        remoteCancellationSignal);
+                if (cancellationSignal != null) {
+                    cancellationSignal.setOnCancelListener(transport::cancel);
+                }
+            } else {
+                transport.fail();
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Register for a single location update using the named provider and a callback.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} for
+     * more detail on how to use this method.
+     *
+     * @param provider a provider listed by {@link #getAllProviders()}
+     * @param listener the listener to receive location updates
+     * @param looper   the looper handling listener callbacks, or null to use the looper of the
+     *                 calling thread
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException        if no suitable permission is present
+     * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)}
+     * instead as it does not carry a risk of extreme battery drain.
+     */
+    @Deprecated
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestSingleUpdate(
+            @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+        Preconditions.checkArgument(listener != null, "invalid null listener");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                provider, 0, 0, true);
+        request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
+        requestLocationUpdates(request, listener, looper);
+    }
+
+    /**
+     * Register for a single location update using a Criteria and a callback.
+     *
+     * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail
+     * on how to use this method.
+     *
+     * @param criteria contains parameters to choose the appropriate provider for location updates
+     * @param listener the listener to receive location updates
+     * @param looper   the looper handling listener callbacks, or null to use the looper of the
+     *                 calling thread
+     *
+     * @throws IllegalArgumentException if criteria is null
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException        if no suitable permission is present
+     * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)}
+     * instead as it does not carry a risk of extreme battery drain.
+     */
+    @Deprecated
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestSingleUpdate(
+            @NonNull Criteria criteria,
+            @NonNull LocationListener listener,
+            @Nullable Looper looper) {
+        Preconditions.checkArgument(criteria != null, "invalid null criteria");
+        Preconditions.checkArgument(listener != null, "invalid null listener");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+                criteria, 0, 0, true);
+        request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
+        requestLocationUpdates(request, listener, looper);
+    }
+
+    /**
+     * Register for a single location update using a named provider and pending intent.
+     *
+     * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail
+     * on how to use this method.
+     *
+     * @param provider      a provider listed by {@link #getAllProviders()}
+     * @param pendingIntent the pending intent to send location updates
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if intent is null
+     * @throws SecurityException        if no suitable permission is present
+     * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)}
+     * instead as it does not carry a risk of extreme battery drain.
+     */
+    @Deprecated
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestSingleUpdate(@NonNull String provider,
+            @NonNull PendingIntent pendingIntent) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                provider, 0, 0, true);
+        request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
+        requestLocationUpdates(request, pendingIntent);
+    }
+
+    /**
+     * Register for a single location update using a Criteria and pending intent.
+     *
+     * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail
+     * on how to use this method.
+     *
+     * @param criteria      contains parameters to choose the appropriate provider for location
+     *                      updates
+     * @param pendingIntent the pending intent to send location updates
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if intent is null
+     * @throws SecurityException        if no suitable permission is present
+     * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)}
+     * instead as it does not carry a risk of extreme battery drain.
+     */
+    @Deprecated
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestSingleUpdate(@NonNull Criteria criteria,
+            @NonNull PendingIntent pendingIntent) {
+        Preconditions.checkArgument(criteria != null, "invalid null criteria");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+                criteria, 0, 0, true);
+        request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
+        requestLocationUpdates(request, pendingIntent);
+    }
+
+    /**
+     * Register for location updates from the given provider with the given arguments. {@link
+     * LocationListener} callbacks will take place on the given {@link Looper} or {@link Executor}.
+     * If a null {@link Looper} is supplied, the Looper of the calling thread will be used instead.
+     * Only one request can be registered for each unique listener, so any subsequent requests with
+     * the same listener will overwrite all associated arguments.
+     *
+     * <p> It may take a while to receive the first location update. If an immediate location is
+     * required, applications may use the {@link #getLastKnownLocation(String)} method.
+     *
+     * <p> The location update interval can be controlled using the minimum time parameter. The
+     * elapsed time between location updates will never be less than this parameter, although it may
+     * be more depending on location availability and other factors. Choosing a sensible value for
+     * the minimum time parameter is important to conserve battery life. Every location update
+     * requires power from a variety of sensors. Select a minimum time parameter as high as possible
+     * while still providing a reasonable user experience. If your application is not in the
+     * foreground and showing location to the user then your application should consider switching
+     * to the {@link #PASSIVE_PROVIDER} instead.
+     *
+     * <p> The minimum distance parameter can also be used to control the frequency of location
+     * updates. If it is greater than 0 then the location provider will only send your application
+     * an update when the location has changed by at least minDistance meters, AND when the minimum
+     * time has elapsed. However it is more difficult for location providers to save power using the
+     * minimum distance parameter, so the minimum time parameter should be the primary tool for
+     * conserving battery life.
+     *
+     * <p> If your application wants to passively observe location updates triggered by other
+     * applications, but not consume any additional power otherwise, then use the {@link
+     * #PASSIVE_PROVIDER}. This provider does not turn on or modify active location providers, so
+     * you do not need to be as careful about minimum time and minimum distance parameters. However,
+     * if your application performs heavy work on a location update (such as network activity) then
+     * you should select non-zero values for the parameters to rate-limit your update frequency in
+     * the case another application enables a location provider with extremely fast updates.
+     *
+     * <p>In case the provider you have selected is disabled, location updates will cease, and a
+     * provider availability update will be sent. As soon as the provider is enabled again, another
+     * provider availability update will be sent and location updates will immediately resume.
+     *
+     * <p> When location callbacks are invoked, the system will hold a wakelock on your
+     * application's behalf for some period of time, but not indefinitely. If your application
+     * requires a long running wakelock within the location callback, you should acquire it
+     * yourself.
+     *
+     * <p class="note"> Prior to Jellybean, the minTime parameter was only a hint, and some location
+     * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for
+     * Android compatible devices to observe both the minTime and minDistance parameters.
+     *
+     * <p>To unregister for location updates, use {@link #removeUpdates(LocationListener)}.
+     *
+     * @param provider     a provider listed by {@link #getAllProviders()}
+     * @param minTimeMs    minimum time interval between location updates in milliseconds
+     * @param minDistanceM minimum distance between location updates in meters
+     * @param listener     the listener to receive location updates
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if listener is null
+     * @throws RuntimeException if the calling thread has no Looper
+     * @throws SecurityException if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM,
+            @NonNull LocationListener listener) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+        Preconditions.checkArgument(listener != null, "invalid null listener");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                provider, minTimeMs, minDistanceM, false);
+        requestLocationUpdates(request, listener, null);
+    }
+
+    /**
+     * Register for location updates using the named provider, and a callback on
+     * the specified {@link Looper}.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+     * for more detail on how this method works.
+     *
+     * @param provider     a provider listed by {@link #getAllProviders()}
+     * @param minTimeMs    minimum time interval between location updates in milliseconds
+     * @param minDistanceM minimum distance between location updates in meters
+     * @param listener     the listener to receive location updates
+     * @param looper       the looper handling listener callbacks, or null to use the looper of the
+     *                     calling thread
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM,
+            @NonNull LocationListener listener, @Nullable Looper looper) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+        Preconditions.checkArgument(listener != null, "invalid null listener");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                provider, minTimeMs, minDistanceM, false);
+        requestLocationUpdates(request, listener, looper);
+    }
+
+    /**
+     * Register for location updates using the named provider, and a callback on
+     * the specified {@link Executor}.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+     * for more detail on how this method works.
+     *
+     * @param provider     a provider listed by {@link #getAllProviders()}
+     * @param minTimeMs    minimum time interval between location updates in milliseconds
+     * @param minDistanceM minimum distance between location updates in meters
+     * @param executor     the executor handling listener callbacks
+     * @param listener     the listener to receive location updates
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(
+            @NonNull String provider,
+            long minTimeMs,
+            float minDistanceM,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull LocationListener listener) {
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                provider, minTimeMs, minDistanceM, false);
+        requestLocationUpdates(request, executor, listener);
+    }
+
+    /**
+     * Register for location updates using a provider selected through the given Criteria, and a
+     * callback on the specified {@link Looper}.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+     * for more detail on how this method works.
+     *
+     * @param minTimeMs minimum time interval between location updates in milliseconds
+     * @param minDistanceM minimum distance between location updates in meters
+     * @param criteria contains parameters to choose the appropriate provider for location updates
+     * @param listener the listener to receive location updates
+     *
+     * @throws IllegalArgumentException if criteria is null
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(long minTimeMs, float minDistanceM,
+            @NonNull Criteria criteria, @NonNull LocationListener listener,
+            @Nullable Looper looper) {
+        Preconditions.checkArgument(criteria != null, "invalid null criteria");
+        Preconditions.checkArgument(listener != null, "invalid null listener");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+                criteria, minTimeMs, minDistanceM, false);
+        requestLocationUpdates(request, listener, looper);
+    }
+
+    /**
+     * Register for location updates using a provider selected through the given Criteria, and a
+     * callback on the specified {@link Executor}.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+     * for more detail on how this method works.
+     *
+     * @param minTimeMs minimum time interval between location updates in milliseconds
+     * @param minDistanceM minimum distance between location updates in meters
+     * @param criteria contains parameters to choose the appropriate provider for location updates
+     * @param executor the executor handling listener callbacks
+     * @param listener the listener to receive location updates
+     *
+     * @throws IllegalArgumentException if criteria is null
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException        if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(
+            long minTimeMs,
+            float minDistanceM,
+            @NonNull Criteria criteria,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull LocationListener listener) {
+        LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+                criteria, minTimeMs, minDistanceM, false);
+        requestLocationUpdates(request, executor, listener);
+    }
+
+    /**
+     * Register for location updates using the named provider, and callbacks delivered via the
+     * provided {@link PendingIntent}.
+     *
+     * <p>The delivered pending intents will contain extras with the callback information. The keys
+     * used for the extras are {@link #KEY_LOCATION_CHANGED} and {@link #KEY_PROVIDER_ENABLED}. See
+     * the documentation for each respective extra key for information on the values.
+     *
+     * <p>To unregister for location updates, use {@link #removeUpdates(PendingIntent)}.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+     * for more detail on how this method works.
+     *
+     * @param provider      a provider listed by {@link #getAllProviders()}
+     * @param minTimeMs     minimum time interval between location updates in milliseconds
+     * @param minDistanceM  minimum distance between location updates in meters
+     * @param pendingIntent the pending intent to send location updates
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if pendingIntent is null
+     * @throws SecurityException if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM,
+            @NonNull PendingIntent pendingIntent) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedProvider(
+                provider, minTimeMs, minDistanceM, false);
+        requestLocationUpdates(request, pendingIntent);
+    }
+
+    /**
+     * Register for location updates using a provider selected through the given Criteria, and
+     * callbacks delivered via the provided {@link PendingIntent}.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on
+     * how this method works.
+     *
+     * @param minTimeMs minimum time interval between location updates in milliseconds
+     * @param minDistanceM minimum distance between location updates in meters
+     * @param criteria contains parameters to choose the appropriate provider for location updates
+     * @param pendingIntent the pending intent to send location updates
+     *
+     * @throws IllegalArgumentException if provider is null or doesn't exist
+     * @throws IllegalArgumentException if pendingIntent is null
+     * @throws SecurityException if no suitable permission is present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(long minTimeMs, float minDistanceM,
+            @NonNull Criteria criteria, @NonNull PendingIntent pendingIntent) {
+        Preconditions.checkArgument(criteria != null, "invalid null criteria");
+
+        LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
+                criteria, minTimeMs, minDistanceM, false);
+        requestLocationUpdates(request, pendingIntent);
+    }
+
+    /**
+     * Register for location updates using a {@link LocationRequest}, and a callback on the
+     * specified {@link Looper}.
+     *
+     * <p>The system will automatically select and enable the best provider based on the given
+     * {@link LocationRequest}. The LocationRequest can be null, in which case the system will
+     * choose default low power parameters for location updates, but this is heavily discouraged,
+     * and an explicit LocationRequest should always be provided.
+     *
+     * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener)}
+     * for more detail on how this method works.
+     *
+     * @param locationRequest the location request containing location parameters
+     * @param listener the listener to receive location updates
+     * @param looper the looper handling listener callbacks, or null to use the looper of the
+     *               calling thread
+     *
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if no suitable permission is present
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(
+            @Nullable LocationRequest locationRequest,
+            @NonNull LocationListener listener,
+            @Nullable Looper looper) {
+        Handler handler = looper == null ? new Handler() : new Handler(looper);
+        requestLocationUpdates(locationRequest, new HandlerExecutor(handler), listener);
+    }
+
+    /**
+     * Register for location updates using a {@link LocationRequest}, and a callback on the
+     * specified {@link Executor}.
+     *
+     * <p>See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)} for more
+     * detail on how this method works.
+     *
+     * @param locationRequest the location request containing location parameters
+     * @param executor the executor handling listener callbacks
+     * @param listener the listener to receive location updates
+     *
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if no suitable permission is present
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(
+            @Nullable LocationRequest locationRequest,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull LocationListener listener) {
+        synchronized (mListeners) {
+            LocationListenerTransport transport = mListeners.get(listener);
+            if (transport != null) {
+                transport.unregister();
+            } else {
+                transport = new LocationListenerTransport(listener);
+                mListeners.put(listener, transport);
+            }
+            transport.register(executor);
+
+            boolean registered = false;
+            try {
+                mService.requestLocationUpdates(locationRequest, transport, null,
+                        mContext.getPackageName(), mContext.getAttributionTag(),
+                        transport.getListenerId());
+                registered = true;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            } finally {
+                if (!registered) {
+                    // allow gc after exception
+                    transport.unregister();
+                    mListeners.remove(listener);
+                }
+            }
+        }
+    }
+
+    /**
+     * Register for location updates using a {@link LocationRequest}, and callbacks delivered via
+     * the provided {@link PendingIntent}.
+     *
+     * <p>See {@link #requestLocationUpdates(LocationRequest, LocationListener, Looper)} and
+     * {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on how
+     * this method works.
+     *
+     * @param locationRequest the location request containing location parameters
+     * @param pendingIntent the pending intent to send location updates
+     *
+     * @throws IllegalArgumentException if pendingIntent is null
+     * @throws SecurityException if no suitable permission is present
+     *
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void requestLocationUpdates(
+            @Nullable LocationRequest locationRequest,
+            @NonNull PendingIntent pendingIntent) {
+        Preconditions.checkArgument(locationRequest != null, "invalid null location request");
+        Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent");
+        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
+            Preconditions.checkArgument(pendingIntent.isTargetedToPackage(),
+                    "pending intent must be targeted to a package");
+        }
+
+        try {
+            mService.requestLocationUpdates(locationRequest, null, pendingIntent,
+                    mContext.getPackageName(), mContext.getAttributionTag(), null);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set the last known location with a new location.
+     *
+     * <p>A privileged client can inject a {@link Location} if it has a better estimate of what
+     * the recent location is.  This is especially useful when the device boots up and the GPS
+     * chipset is in the process of getting the first fix.  If the client has cached the location,
+     * it can inject the {@link Location}, so if an app requests for a {@link Location} from {@link
+     * #getLastKnownLocation(String)}, the location information is still useful before getting
+     * the first fix.
+     *
+     * @param location newly available {@link Location} object
+     * @return true if the location was injected, false otherwise
+     *
+     * @throws IllegalArgumentException if location is null
+     * @throws SecurityException if permissions are not present
+     *
+     * @hide
+     */
+    @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION})
+    public boolean injectLocation(@NonNull Location location) {
+        Preconditions.checkArgument(location != null, "invalid null location");
+        Preconditions.checkArgument(location.isComplete(),
+                "incomplete location object, missing timestamp or accuracy?");
+
+        try {
+            mService.injectLocation(location);
+            return true;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes location updates for the specified {@link LocationListener}. Following this call,
+     * the listener will no longer receive location updates.
+     *
+     * @param listener listener that no longer needs location updates
+     *
+     * @throws IllegalArgumentException if listener is null
+     */
+    public void removeUpdates(@NonNull LocationListener listener) {
+        Preconditions.checkArgument(listener != null, "invalid null listener");
+
+        synchronized (mListeners) {
+            LocationListenerTransport transport = mListeners.remove(listener);
+            if (transport == null) {
+                return;
+            }
+            transport.unregister();
+
+            try {
+                mService.removeUpdates(transport, null);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Removes location updates for the specified {@link PendingIntent}. Following this call, the
+     * PendingIntent will no longer receive location updates.
+     *
+     * @param pendingIntent pending intent that no longer needs location updates
+     *
+     * @throws IllegalArgumentException if pendingIntent is null
+     */
+    public void removeUpdates(@NonNull PendingIntent pendingIntent) {
+        Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent");
+
+        try {
+            mService.removeUpdates(null, pendingIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns a list of the names of all known location providers. All providers are returned,
+     * including ones that are not permitted to be accessed by the calling activity or are currently
+     * disabled.
+     *
+     * @return list of provider names
+     */
+    public @NonNull List<String> getAllProviders() {
+        try {
+            return mService.getAllProviders();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns a list of the names of location providers. Only providers that the caller has
+     * permission to access will be returned.
+     *
+     * @param enabledOnly if true then only enabled providers are included
+     * @return list of provider names
+     */
+    public @NonNull List<String> getProviders(boolean enabledOnly) {
+        try {
+            return mService.getProviders(null, enabledOnly);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns a list of the names of providers that satisfy the given criteria. Only providers that
+     * the caller has permission to access will be returned.
+     *
+     * @param criteria the criteria that providers must match
+     * @param enabledOnly if true then only enabled providers are included
+     * @return list of provider names
+     *
+     * @throws IllegalArgumentException if criteria is null
+     */
+    public @NonNull List<String> getProviders(@NonNull Criteria criteria, boolean enabledOnly) {
+        Preconditions.checkArgument(criteria != null, "invalid null criteria");
+
+        try {
+            return mService.getProviders(criteria, enabledOnly);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the name of the provider that best meets the given criteria. Only providers that are
+     * permitted to be accessed by the caller will be returned. If several providers meet the
+     * criteria, the one with the best accuracy is returned. If no provider meets the criteria, the
+     * criteria are loosened in the following order:
+     *
+     * <ul>
+     * <li> power requirement
+     * <li> accuracy
+     * <li> bearing
+     * <li> speed
+     * <li> altitude
+     * </ul>
+     *
+     * <p> Note that the requirement on monetary cost is not removed in this process.
+     *
+     * @param criteria the criteria that need to be matched
+     * @param enabledOnly if true then only enabled providers are included
+     * @return name of the provider that best matches the criteria, or null if none match
+     *
+     * @throws IllegalArgumentException if criteria is null
+     */
+    public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) {
+        Preconditions.checkArgument(criteria != null, "invalid null criteria");
+
+        try {
+            return mService.getBestProvider(criteria, enabledOnly);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the information about the location provider with the given name, or null if no
+     * provider exists by that name.
+     *
+     * @param provider a provider listed by {@link #getAllProviders()}
+     * @return location provider information, or null if provider does not exist
+     *
+     * @throws IllegalArgumentException if provider is null
+     */
+    public @Nullable LocationProvider getProvider(@NonNull String provider) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        if (!Compatibility.isChangeEnabled(GET_PROVIDER_SECURITY_EXCEPTIONS)) {
+            if (NETWORK_PROVIDER.equals(provider) || FUSED_PROVIDER.equals(provider)) {
+                try {
+                    mContext.enforcePermission(ACCESS_FINE_LOCATION, Process.myPid(),
+                            Process.myUid(), null);
+                } catch (SecurityException e) {
+                    mContext.enforcePermission(ACCESS_COARSE_LOCATION, Process.myPid(),
+                            Process.myUid(), null);
+                }
+            } else {
+                mContext.enforcePermission(ACCESS_FINE_LOCATION, Process.myPid(), Process.myUid(),
+                        null);
+            }
+        }
+
+        try {
+            ProviderProperties properties = mService.getProviderProperties(provider);
+            if (properties == null) {
+                return null;
+            }
+            return new LocationProvider(provider, properties);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if the given package name matches a location provider package, and false
+     * otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+    public boolean isProviderPackage(@NonNull String packageName) {
+        try {
+            return mService.isProviderPackage(packageName);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+            return false;
+        }
+    }
+
+    /**
+     * Returns a list of packages associated with the given provider,
+     * and an empty list if no package is associated with the provider.
+     *
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+    @Nullable
+    public List<String> getProviderPackages(@NonNull String provider) {
+        try {
+            return mService.getProviderPackages(provider);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * Sends additional commands to a location provider. Can be used to support provider specific
+     * extensions to the Location Manager API.
+     *
+     * @param provider a provider listed by {@link #getAllProviders()}
+     * @param command  name of the command to send to the provider
+     * @param extras   optional arguments for the command, or null
+     * @return true always, the return value may be ignored
+     */
+    public boolean sendExtraCommand(
+            @NonNull String provider, @NonNull String command, @Nullable Bundle extras) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+        Preconditions.checkArgument(command != null, "invalid null command");
+
+        try {
+            return mService.sendExtraCommand(provider, command, extras);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Creates a test location provider and adds it to the set of active providers. This provider
+     * will replace any provider with the same name that exists prior to this call.
+     *
+     * @param provider the provider name
+     *
+     * @throws IllegalArgumentException if provider is null
+     * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+     * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+     * allowed} for your app.
+     */
+    public void addTestProvider(
+            @NonNull String provider, boolean requiresNetwork, boolean requiresSatellite,
+            boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
+            boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        ProviderProperties properties = new ProviderProperties(requiresNetwork,
+                requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, supportsSpeed,
+                supportsBearing, powerRequirement, accuracy);
+        try {
+            mService.addTestProvider(provider, properties, mContext.getOpPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes the test location provider with the given name or does nothing if no such test
+     * location provider exists.
+     *
+     * @param provider the provider name
+     *
+     * @throws IllegalArgumentException if provider is null
+     * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+     * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+     * allowed} for your app.
+     */
+    public void removeTestProvider(@NonNull String provider) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        try {
+            mService.removeTestProvider(provider, mContext.getOpPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets a new location for the given test provider. This location will be identiable as a mock
+     * location to all clients via {@link Location#isFromMockProvider()}.
+     *
+     * <p>The location object must have a minimum number of fields set to be considered valid, as
+     * per documentation on {@link Location} class.
+     *
+     * @param provider the provider name
+     * @param location the mock location
+     *
+     * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+     * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+     * allowed} for your app.
+     * @throws IllegalArgumentException if the provider is null or not a test provider
+     * @throws IllegalArgumentException if the location is null or incomplete
+     */
+    public void setTestProviderLocation(@NonNull String provider, @NonNull Location location) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+        Preconditions.checkArgument(location != null, "invalid null location");
+
+        if (Compatibility.isChangeEnabled(INCOMPLETE_LOCATION)) {
+            Preconditions.checkArgument(location.isComplete(),
+                    "incomplete location object, missing timestamp or accuracy?");
+        } else {
+            location.makeComplete();
+        }
+
+        try {
+            mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Does nothing.
+     *
+     * @deprecated This method has always been a no-op, and may be removed in the future.
+     */
+    @Deprecated
+    public void clearTestProviderLocation(@NonNull String provider) {}
+
+    /**
+     * Sets the given test provider to be enabled or disabled.
+     *
+     * @param provider the provider name
+     * @param enabled the mock enabled value
+     *
+     * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+     * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+     * allowed} for your app.
+     * @throws IllegalArgumentException if provider is null or not a test provider
+     */
+    public void setTestProviderEnabled(@NonNull String provider, boolean enabled) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        try {
+            mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Equivalent to calling {@link #setTestProviderEnabled(String, boolean)} to disable a test
+     * provider.
+     *
+     * @deprecated Use {@link #setTestProviderEnabled(String, boolean)} instead.
+     */
+    @Deprecated
+    public void clearTestProviderEnabled(@NonNull String provider) {
+        setTestProviderEnabled(provider, false);
+    }
+
+    /**
+     * This method has no effect as provider status has been deprecated and is no longer supported.
+     *
+     * @deprecated This method has no effect.
+     */
+    @Deprecated
+    public void setTestProviderStatus(
+            @NonNull String provider, int status, @Nullable Bundle extras, long updateTime) {}
+
+    /**
+     * This method has no effect as provider status has been deprecated and is no longer supported.
+     *
+     * @deprecated This method has no effect.
+     */
+    @Deprecated
+    public void clearTestProviderStatus(@NonNull String provider) {}
+
+    /**
+     * Get the last list of {@link LocationRequest}s sent to the provider.
+     *
+     * @hide
+     */
+    @TestApi
+    @NonNull
+    public List<LocationRequest> getTestProviderCurrentRequests(String providerName) {
+        Preconditions.checkArgument(providerName != null, "invalid null provider");
+        try {
+            return mService.getTestProviderCurrentRequests(providerName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set a proximity alert for the location given by the position
+     * (latitude, longitude) and the given radius.
+     *
+     * <p> When the device
+     * detects that it has entered or exited the area surrounding the
+     * location, the given PendingIntent will be used to create an Intent
+     * to be fired.
+     *
+     * <p> The fired Intent will have a boolean extra added with key
+     * {@link #KEY_PROXIMITY_ENTERING}. If the value is true, the device is
+     * entering the proximity region; if false, it is exiting.
+     *
+     * <p> Due to the approximate nature of position estimation, if the
+     * device passes through the given area briefly, it is possible
+     * that no Intent will be fired.  Similarly, an Intent could be
+     * fired if the device passes very close to the given area but
+     * does not actually enter it.
+     *
+     * <p> After the number of milliseconds given by the expiration
+     * parameter, the location manager will delete this proximity
+     * alert and no longer monitor it.  A value of -1 indicates that
+     * there should be no expiration time.
+     *
+     * <p> Internally, this method uses both {@link #NETWORK_PROVIDER}
+     * and {@link #GPS_PROVIDER}.
+     *
+     * <p>Before API version 17, this method could be used with
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     * From API version 17 and onwards, this method requires
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission.
+     *
+     * @param latitude the latitude of the central point of the
+     * alert region
+     * @param longitude the longitude of the central point of the
+     * alert region
+     * @param radius the radius of the central point of the
+     * alert region, in meters
+     * @param expiration time for this proximity alert, in milliseconds,
+     * or -1 to indicate no expiration
+     * @param intent a PendingIntent that will be used to generate an Intent to
+     * fire when entry to or exit from the alert region is detected
+     *
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void addProximityAlert(double latitude, double longitude, float radius, long expiration,
+            @NonNull PendingIntent intent) {
+        Preconditions.checkArgument(intent != null, "invalid null pending intent");
+        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
+            Preconditions.checkArgument(intent.isTargetedToPackage(),
+                    "pending intent must be targeted to a package");
+        }
+        if (expiration < 0) expiration = Long.MAX_VALUE;
+
+        Geofence fence = Geofence.createCircle(latitude, longitude, radius);
+        LocationRequest request = new LocationRequest().setExpireIn(expiration);
+        try {
+            mService.requestGeofence(request, fence, intent, mContext.getPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes the proximity alert with the given PendingIntent.
+     *
+     * <p>Before API version 17, this method could be used with
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     * From API version 17 and onwards, this method requires
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission.
+     *
+     * @param intent the PendingIntent that no longer needs to be notified of
+     * proximity alerts
+     *
+     * @throws IllegalArgumentException if intent is null
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
+     */
+    public void removeProximityAlert(@NonNull PendingIntent intent) {
+        Preconditions.checkArgument(intent != null, "invalid null pending intent");
+        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
+            Preconditions.checkArgument(intent.isTargetedToPackage(),
+                    "pending intent must be targeted to a package");
+        }
+
+        try {
+            mService.removeGeofence(null, intent, mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Add a geofence with the specified LocationRequest quality of service.
+     *
+     * <p> When the device
+     * detects that it has entered or exited the area surrounding the
+     * location, the given PendingIntent will be used to create an Intent
+     * to be fired.
+     *
+     * <p> The fired Intent will have a boolean extra added with key
+     * {@link #KEY_PROXIMITY_ENTERING}. If the value is true, the device is
+     * entering the proximity region; if false, it is exiting.
+     *
+     * <p> The geofence engine fuses results from all location providers to
+     * provide the best balance between accuracy and power. Applications
+     * can choose the quality of service required using the
+     * {@link LocationRequest} object. If it is null then a default,
+     * low power geo-fencing implementation is used. It is possible to cross
+     * a geo-fence without notification, but the system will do its best
+     * to detect, using {@link LocationRequest} as a hint to trade-off
+     * accuracy and power.
+     *
+     * <p> The power required by the geofence engine can depend on many factors,
+     * such as quality and interval requested in {@link LocationRequest},
+     * distance to nearest geofence and current device velocity.
+     *
+     * @param request quality of service required, null for default low power
+     * @param fence a geographical description of the geofence area
+     * @param intent pending intent to receive geofence updates
+     *
+     * @throws IllegalArgumentException if fence is null
+     * @throws IllegalArgumentException if intent is null
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
+     *
+     * @hide
+     */
+    @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
+    public void addGeofence(
+            @NonNull LocationRequest request,
+            @NonNull Geofence fence,
+            @NonNull PendingIntent intent) {
+        Preconditions.checkArgument(request != null, "invalid null location request");
+        Preconditions.checkArgument(fence != null, "invalid null geofence");
+        Preconditions.checkArgument(intent != null, "invalid null pending intent");
+        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
+            Preconditions.checkArgument(intent.isTargetedToPackage(),
+                    "pending intent must be targeted to a package");
+        }
+
+        try {
+            mService.requestGeofence(request, fence, intent, mContext.getPackageName(),
+                    mContext.getAttributionTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Remove a single geofence.
+     *
+     * <p>This removes only the specified geofence associated with the
+     * specified pending intent. All other geofences remain unchanged.
+     *
+     * @param fence a geofence previously passed to {@link #addGeofence}
+     * @param intent a pending intent previously passed to {@link #addGeofence}
+     *
+     * @throws IllegalArgumentException if fence is null
+     * @throws IllegalArgumentException if intent is null
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
+     *
+     * @hide
+     */
+    public void removeGeofence(@NonNull Geofence fence, @NonNull PendingIntent intent) {
+        Preconditions.checkArgument(fence != null, "invalid null geofence");
+        Preconditions.checkArgument(intent != null, "invalid null pending intent");
+        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
+            Preconditions.checkArgument(intent.isTargetedToPackage(),
+                    "pending intent must be targeted to a package");
+        }
+
+        try {
+            mService.removeGeofence(fence, intent, mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Remove all geofences registered to the specified pending intent.
+     *
+     * @param intent a pending intent previously passed to {@link #addGeofence}
+     *
+     * @throws IllegalArgumentException if intent is null
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
+     *
+     * @hide
+     */
+    public void removeAllGeofences(@NonNull PendingIntent intent) {
+        Preconditions.checkArgument(intent != null, "invalid null pending intent");
+        if (Compatibility.isChangeEnabled(TARGETED_PENDING_INTENT)) {
+            Preconditions.checkArgument(intent.isTargetedToPackage(),
+                    "pending intent must be targeted to a package");
+        }
+
+        try {
+            mService.removeGeofence(null, intent, mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    // ================= GNSS APIs =================
+
+    /**
+     * Returns the supported capabilities of the GNSS chipset.
+     */
+    public @NonNull GnssCapabilities getGnssCapabilities() {
+        try {
+            long gnssCapabilities = mService.getGnssCapabilities();
+            if (gnssCapabilities == GnssCapabilities.INVALID_CAPABILITIES) {
+                gnssCapabilities = 0L;
+            }
+            return GnssCapabilities.of(gnssCapabilities);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the model year of the GNSS hardware and software build. More details, such as build
+     * date, may be available in {@link #getGnssHardwareModelName()}. May return 0 if the model year
+     * is less than 2016.
+     */
+    public int getGnssYearOfHardware() {
+        try {
+            return mService.getGnssYearOfHardware();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the Model Name (including Vendor and Hardware/Software Version) of the GNSS hardware
+     * driver.
+     *
+     * <p> No device-specific serial number or ID is returned from this API.
+     *
+     * <p> Will return null when the GNSS hardware abstraction layer does not support providing
+     * this value.
+     */
+    @Nullable
+    public String getGnssHardwareModelName() {
+        try {
+            return mService.getGnssHardwareModelName();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Retrieves information about the current status of the GPS engine. This should only be called
+     * from within the {@link GpsStatus.Listener#onGpsStatusChanged} callback to ensure that the
+     * data is copied atomically.
+     *
+     * The caller may either pass in an existing {@link GpsStatus} object to be overwritten, or pass
+     * null to create a new {@link GpsStatus} object.
+     *
+     * @param status object containing GPS status details, or null.
+     * @return status object containing updated GPS status.
+     *
+     * @deprecated GpsStatus APIs are deprecated, use {@link GnssStatus} APIs instead. No longer
+     * supported in apps targeting S and above.
+     */
+    @Deprecated
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) {
+        if (Compatibility.isChangeEnabled(GPS_STATUS_USAGE)) {
+            throw new UnsupportedOperationException(
+                    "GpsStatus APIs not supported, please use GnssStatus APIs instead");
+        }
+
+        GnssStatus gnssStatus = mGnssStatusListenerManager.getGnssStatus();
+        int ttff = mGnssStatusListenerManager.getTtff();
+        if (gnssStatus != null) {
+            if (status == null) {
+                status = GpsStatus.create(gnssStatus, ttff);
+            } else {
+                status.setStatus(gnssStatus, ttff);
+            }
+        }
+        return status;
+    }
+
+    /**
+     * Adds a GPS status listener.
+     *
+     * @param listener GPS status listener object to register
+     * @return true if the listener was successfully added
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     *
+     * @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead. No longer
+     * supported in apps targeting S and above.
+     */
+    @Deprecated
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean addGpsStatusListener(GpsStatus.Listener listener) {
+        if (Compatibility.isChangeEnabled(GPS_STATUS_USAGE)) {
+            throw new UnsupportedOperationException(
+                    "GpsStatus APIs not supported, please use GnssStatus APIs instead");
+        }
+
+        try {
+            return mGnssStatusListenerManager.addListener(listener, Runnable::run);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes a GPS status listener.
+     *
+     * @param listener GPS status listener object to remove
+     *
+     * @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead. No longer
+     * supported in apps targeting S and above.
+     */
+    @Deprecated
+    public void removeGpsStatusListener(GpsStatus.Listener listener) {
+        if (Compatibility.isChangeEnabled(GPS_STATUS_USAGE)) {
+            throw new UnsupportedOperationException(
+                    "GpsStatus APIs not supported, please use GnssStatus APIs instead");
+        }
+
+        try {
+            mGnssStatusListenerManager.removeListener(listener);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers a GNSS status callback.
+     *
+     * @param callback GNSS status callback object to register
+     * @return true if the listener was successfully added
+     *
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     *
+     * @deprecated Use {@link #registerGnssStatusCallback(GnssStatus.Callback, Handler)} or {@link
+     * #registerGnssStatusCallback(Executor, GnssStatus.Callback)} instead.
+     */
+    @Deprecated
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
+        return registerGnssStatusCallback(callback, null);
+    }
+
+    /**
+     * Registers a GNSS status callback.
+     *
+     * @param callback GNSS status callback object to register
+     * @param handler  a handler with a looper that the callback runs on
+     * @return true if the listener was successfully added
+     *
+     * @throws IllegalArgumentException if callback is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssStatusCallback(
+            @NonNull GnssStatus.Callback callback, @Nullable Handler handler) {
+        if (handler == null) {
+            handler = new Handler();
+        }
+
+        try {
+            return mGnssStatusListenerManager.addListener(callback, handler);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers a GNSS status callback.
+     *
+     * @param executor the executor that the callback runs on
+     * @param callback GNSS status callback object to register
+     * @return true if the listener was successfully added
+     *
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if callback is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssStatusCallback(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull GnssStatus.Callback callback) {
+        try {
+            return mGnssStatusListenerManager.addListener(callback, executor);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes a GNSS status callback.
+     *
+     * @param callback GNSS status callback object to remove
+     */
+    public void unregisterGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
+        try {
+            mGnssStatusListenerManager.removeListener(callback);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * No-op method to keep backward-compatibility.
+     *
+     * @deprecated Use {@link #addNmeaListener} instead.
+     */
+    @Deprecated
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean addNmeaListener(@NonNull GpsStatus.NmeaListener listener) {
+        return false;
+    }
+
+    /**
+     * No-op method to keep backward-compatibility.
+     *
+     * @deprecated Use {@link #removeNmeaListener(OnNmeaMessageListener)} instead.
+     */
+    @Deprecated
+    public void removeNmeaListener(@NonNull GpsStatus.NmeaListener listener) {}
+
+    /**
+     * Adds an NMEA listener.
+     *
+     * @param listener a {@link OnNmeaMessageListener} object to register
+     * @return true if the listener was successfully added
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     * @deprecated Use {@link #addNmeaListener(OnNmeaMessageListener, Handler)} or {@link
+     * #addNmeaListener(Executor, OnNmeaMessageListener)} instead.
+     */
+    @Deprecated
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) {
+        return addNmeaListener(Runnable::run, listener);
+    }
+
+    /**
+     * Adds an NMEA listener.
+     *
+     * @param listener a {@link OnNmeaMessageListener} object to register
+     * @param handler  a handler with the looper that the listener runs on.
+     * @return true if the listener was successfully added
+     *
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean addNmeaListener(
+            @NonNull OnNmeaMessageListener listener, @Nullable Handler handler) {
+        if (handler == null) {
+            handler = new Handler();
+        }
+        try {
+            return mGnssStatusListenerManager.addListener(listener, handler);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adds an NMEA listener.
+     *
+     * @param listener a {@link OnNmeaMessageListener} object to register
+     * @param executor the {@link Executor} that the listener runs on.
+     * @return true if the listener was successfully added
+     *
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean addNmeaListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnNmeaMessageListener listener) {
+        try {
+            return mGnssStatusListenerManager.addListener(listener, executor);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes an NMEA listener.
+     *
+     * @param listener a {@link OnNmeaMessageListener} object to remove
+     */
+    public void removeNmeaListener(@NonNull OnNmeaMessageListener listener) {
+        try {
+            mGnssStatusListenerManager.removeListener(listener);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * No-op method to keep backward-compatibility.
+     *
+     * @hide
+     * @deprecated Use {@link #registerGnssMeasurementsCallback} instead.
+     * @removed
+     */
+    @Deprecated
+    @SystemApi
+    public boolean addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) {
+        return false;
+    }
+
+    /**
+     * No-op method to keep backward-compatibility.
+     *
+     * @hide
+     * @deprecated Use {@link #unregisterGnssMeasurementsCallback} instead.
+     * @removed
+     */
+    @Deprecated
+    @SystemApi
+    public void removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) {}
+
+    /**
+     * Registers a GPS Measurement callback which will run on a binder thread.
+     *
+     * @param callback a {@link GnssMeasurementsEvent.Callback} object to register.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     * @deprecated Use {@link
+     * #registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback, Handler)} or {@link
+     * #registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback)} instead.
+     */
+    @Deprecated
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssMeasurementsCallback(
+            @NonNull GnssMeasurementsEvent.Callback callback) {
+        return registerGnssMeasurementsCallback(Runnable::run, callback);
+    }
+
+    /**
+     * Registers a GPS Measurement callback.
+     *
+     * @param callback a {@link GnssMeasurementsEvent.Callback} object to register.
+     * @param handler  the handler that the callback runs on.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if callback is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssMeasurementsCallback(
+            @NonNull GnssMeasurementsEvent.Callback callback, @Nullable Handler handler) {
+        if (handler == null) {
+            handler = new Handler();
+        }
+        try {
+            return mGnssMeasurementsListenerManager.addListener(callback, handler);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers a GPS Measurement callback.
+     *
+     * @param callback a {@link GnssMeasurementsEvent.Callback} object to register.
+     * @param executor the executor that the callback runs on.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if callback is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssMeasurementsCallback(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull GnssMeasurementsEvent.Callback callback) {
+        try {
+            return mGnssMeasurementsListenerManager.addListener(callback, executor);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers a GNSS Measurement callback.
+     *
+     * @param request  extra parameters to pass to GNSS measurement provider. For example, if {@link
+     *                 GnssRequest#isFullTracking()} is true, GNSS chipset switches off duty
+     *                 cycling.
+     * @param executor the executor that the callback runs on.
+     * @param callback a {@link GnssMeasurementsEvent.Callback} object to register.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     * @throws IllegalArgumentException if request is null
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if callback is null
+     * @throws SecurityException        if the ACCESS_FINE_LOCATION permission is not present
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {ACCESS_FINE_LOCATION, LOCATION_HARDWARE})
+    public boolean registerGnssMeasurementsCallback(
+            @NonNull GnssRequest request,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull GnssMeasurementsEvent.Callback callback) {
+        Preconditions.checkArgument(request != null, "invalid null request");
+        try {
+            return mGnssMeasurementsListenerManager.addListener(request, callback, executor);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Injects GNSS measurement corrections into the GNSS chipset.
+     *
+     * @param measurementCorrections a {@link GnssMeasurementCorrections} object with the GNSS
+     *     measurement corrections to be injected into the GNSS chipset.
+     *
+     * @throws IllegalArgumentException if measurementCorrections is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public void injectGnssMeasurementCorrections(
+            @NonNull GnssMeasurementCorrections measurementCorrections) {
+        Preconditions.checkArgument(measurementCorrections != null);
+        try {
+            mService.injectGnssMeasurementCorrections(
+                    measurementCorrections, mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Unregisters a GPS Measurement callback.
+     *
+     * @param callback a {@link GnssMeasurementsEvent.Callback} object to remove.
+     */
+    public void unregisterGnssMeasurementsCallback(
+            @NonNull GnssMeasurementsEvent.Callback callback) {
+        try {
+            mGnssMeasurementsListenerManager.removeListener(callback);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers a Gnss Antenna Info listener. Only expect results if
+     * {@link GnssCapabilities#hasGnssAntennaInfo()} shows that antenna info is supported.
+     *
+     * @param executor the executor that the listener runs on.
+     * @param listener a {@link GnssAntennaInfo.Listener} object to register.
+     * @return {@code true} if the listener was added successfully, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if listener is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerAntennaInfoListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull GnssAntennaInfo.Listener listener) {
+        try {
+            return mGnssAntennaInfoListenerManager.addListener(listener, executor);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Unregisters a GNSS Antenna Info listener.
+     *
+     * @param listener a {@link GnssAntennaInfo.Listener} object to remove.
+     */
+    public void unregisterAntennaInfoListener(@NonNull GnssAntennaInfo.Listener listener) {
+        try {
+            mGnssAntennaInfoListenerManager.removeListener(listener);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * No-op method to keep backward-compatibility.
+     *
+     * @hide
+     * @deprecated Use {@link #registerGnssNavigationMessageCallback} instead.
+     * @removed
+     */
+    @Deprecated
+    @SystemApi
+    public boolean addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
+        return false;
+    }
+
+    /**
+     * No-op method to keep backward-compatibility.
+     *
+     * @hide
+     * @deprecated Use {@link #unregisterGnssNavigationMessageCallback} instead.
+     * @removed
+     */
+    @Deprecated
+    @SystemApi
+    public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {}
+
+    /**
+     * Registers a GNSS Navigation Message callback which will run on a binder thread.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     * @deprecated Use {@link
+     * #registerGnssNavigationMessageCallback(GnssNavigationMessage.Callback, Handler)} or {@link
+     * #registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)} instead.
+     */
+    @Deprecated
+    public boolean registerGnssNavigationMessageCallback(
+            @NonNull GnssNavigationMessage.Callback callback) {
+        return registerGnssNavigationMessageCallback(Runnable::run, callback);
+    }
+
+    /**
+     * Registers a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+     * @param handler  the handler that the callback runs on.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if callback is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssNavigationMessageCallback(
+            @NonNull GnssNavigationMessage.Callback callback, @Nullable Handler handler) {
+        if (handler == null) {
+            handler = new Handler();
+        }
+
+        try {
+            return mGnssNavigationMessageListenerTransport.addListener(callback, handler);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Registers a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to register.
+     * @param executor the looper that the callback runs on.
+     * @return {@code true} if the callback was added successfully, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if executor is null
+     * @throws IllegalArgumentException if callback is null
+     * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
+     */
+    @RequiresPermission(ACCESS_FINE_LOCATION)
+    public boolean registerGnssNavigationMessageCallback(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull GnssNavigationMessage.Callback callback) {
+        try {
+            return mGnssNavigationMessageListenerTransport.addListener(callback, executor);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Unregisters a GNSS Navigation Message callback.
+     *
+     * @param callback a {@link GnssNavigationMessage.Callback} object to remove.
+     */
+    public void unregisterGnssNavigationMessageCallback(
+            @NonNull GnssNavigationMessage.Callback callback) {
+        try {
+            mGnssNavigationMessageListenerTransport.removeListener(callback);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the batch size (in number of Location objects) that are supported by the batching
+     * interface.
+     *
+     * @return Maximum number of location objects that can be returned
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public int getGnssBatchSize() {
+        try {
+            return mService.getGnssBatchSize(mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Start hardware-batching of GNSS locations. This API is primarily used when the AP is
+     * asleep and the device can batch GNSS locations in the hardware.
+     *
+     * Note this is designed (as was the fused location interface before it) for a single user
+     * SystemApi - requests are not consolidated.  Care should be taken when the System switches
+     * users that may have different batching requests, to stop hardware batching for one user, and
+     * restart it for the next.
+     *
+     * @param periodNanos Time interval, in nanoseconds, that the GNSS locations are requested
+     *                    within the batch
+     * @param wakeOnFifoFull True if the hardware batching should flush the locations in a
+     *                       a callback to the listener, when it's internal buffer is full.  If
+     *                       set to false, the oldest location information is, instead,
+     *                       dropped when the buffer is full.
+     * @param callback The listener on which to return the batched locations
+     * @param handler The handler on which to process the callback
+     *
+     * @return True if batching was successfully started
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public boolean registerGnssBatchedLocationCallback(long periodNanos, boolean wakeOnFifoFull,
+            @NonNull BatchedLocationCallback callback, @Nullable Handler handler) {
+        if (handler == null) {
+            handler = new Handler();
+        }
+
+        synchronized (mBatchedLocationCallbackManager) {
+            try {
+                if (mBatchedLocationCallbackManager.addListener(callback, handler)) {
+                    return mService.startGnssBatch(periodNanos, wakeOnFifoFull,
+                            mContext.getPackageName(), mContext.getAttributionTag());
+                }
+                return false;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Flush the batched GNSS locations.
+     * All GNSS locations currently ready in the batch are returned via the callback sent in
+     * startGnssBatch(), and the buffer containing the batched locations is cleared.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public void flushGnssBatch() {
+        try {
+            mService.flushGnssBatch(mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stop batching locations. This API is primarily used when the AP is
+     * asleep and the device can batch locations in the hardware.
+     *
+     * @param callback the specific callback class to remove from the transport layer
+     *
+     * @return True if batching was successfully started
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
+    public boolean unregisterGnssBatchedLocationCallback(
+            @NonNull BatchedLocationCallback callback) {
+        synchronized (mBatchedLocationCallbackManager) {
+            try {
+                mBatchedLocationCallbackManager.removeListener(callback);
+                mService.stopGnssBatch();
+                return true;
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    private static class GetCurrentLocationTransport extends ILocationListener.Stub implements
+            AlarmManager.OnAlarmListener {
+
+        @GuardedBy("this")
+        @Nullable
+        private Executor mExecutor;
+
+        @GuardedBy("this")
+        @Nullable
+        private Consumer<Location> mConsumer;
+
+        @GuardedBy("this")
+        @Nullable
+        private AlarmManager mAlarmManager;
+
+        @GuardedBy("this")
+        @Nullable
+        private ICancellationSignal mRemoteCancellationSignal;
+
+        private GetCurrentLocationTransport(Executor executor, Consumer<Location> consumer) {
+            Preconditions.checkArgument(executor != null, "illegal null executor");
+            Preconditions.checkArgument(consumer != null, "illegal null consumer");
+            mExecutor = executor;
+            mConsumer = consumer;
+            mAlarmManager = null;
+            mRemoteCancellationSignal = null;
+        }
+
+        public String getListenerId() {
+            return AppOpsManager.toReceiverId(mConsumer);
+        }
+
+        public synchronized void register(AlarmManager alarmManager,
+                ICancellationSignal remoteCancellationSignal) {
+            if (mConsumer == null) {
+                return;
+            }
+
+            mAlarmManager = alarmManager;
+            mAlarmManager.set(
+                    ELAPSED_REALTIME,
+                    SystemClock.elapsedRealtime() + GET_CURRENT_LOCATION_MAX_TIMEOUT_MS,
+                    "GetCurrentLocation",
+                    this,
+                    null);
+
+            mRemoteCancellationSignal = remoteCancellationSignal;
+        }
+
+        public void cancel() {
+            ICancellationSignal cancellationSignal;
+            synchronized (this) {
+                mExecutor = null;
+                mConsumer = null;
+
+                if (mAlarmManager != null) {
+                    mAlarmManager.cancel(this);
+                    mAlarmManager = null;
+                }
+
+                // ensure only one cancel event will go through
+                cancellationSignal = mRemoteCancellationSignal;
+                mRemoteCancellationSignal = null;
+            }
+
+            if (cancellationSignal != null) {
+                try {
+                    cancellationSignal.cancel();
+                } catch (RemoteException e) {
+                    // ignore
+                }
+            }
+        }
+
+        public void fail() {
+            deliverResult(null);
+        }
+
+        @Override
+        public void onAlarm() {
+            synchronized (this) {
+                // save ourselves a pointless x-process call to cancel the alarm
+                mAlarmManager = null;
+            }
+
+            deliverResult(null);
+        }
+
+        @Override
+        public void onLocationChanged(Location location) {
+            synchronized (this) {
+                // save ourselves a pointless x-process call to cancel the location request
+                mRemoteCancellationSignal = null;
+            }
+
+            deliverResult(location);
+        }
+
+        @Override
+        public void onProviderEnabled(String provider) {}
+
+        @Override
+        public void onProviderDisabled(String provider) {
+            // in the event of the provider being disabled it is unlikely that we will get further
+            // locations, so fail early so the client isn't left waiting hopelessly
+            deliverResult(null);
+        }
+
+        @Override
+        public void onRemoved() {
+            deliverResult(null);
+        }
+
+        private synchronized void deliverResult(@Nullable Location location) {
+            if (mExecutor == null) {
+                return;
+            }
+
+            PooledRunnable runnable =
+                    obtainRunnable(GetCurrentLocationTransport::acceptResult, this, location)
+                            .recycleOnUse();
+            try {
+                mExecutor.execute(runnable);
+            } catch (RejectedExecutionException e) {
+                runnable.recycle();
+                throw e;
+            }
+        }
+
+        private void acceptResult(Location location) {
+            Consumer<Location> consumer;
+            synchronized (this) {
+                if (mConsumer == null) {
+                    return;
+                }
+                consumer = mConsumer;
+                cancel();
+            }
+
+            consumer.accept(location);
+        }
+    }
+
+    private class LocationListenerTransport extends ILocationListener.Stub {
+
+        private final LocationListener mListener;
+        @Nullable private volatile Executor mExecutor = null;
+
+        private LocationListenerTransport(@NonNull LocationListener listener) {
+            Preconditions.checkArgument(listener != null, "invalid null listener");
+            mListener = listener;
+        }
+
+        public LocationListener getKey() {
+            return mListener;
+        }
+
+        public String getListenerId() {
+            return AppOpsManager.toReceiverId(mListener);
+        }
+
+        public void register(@NonNull Executor executor) {
+            Preconditions.checkArgument(executor != null, "invalid null executor");
+            mExecutor = executor;
+        }
+
+        public void unregister() {
+            mExecutor = null;
+        }
+
+        @Override
+        public void onLocationChanged(Location location) {
+            Executor currentExecutor = mExecutor;
+            if (currentExecutor == null) {
+                return;
+            }
+
+            PooledRunnable runnable =
+                    obtainRunnable(LocationListenerTransport::acceptLocation, this, currentExecutor,
+                            location).recycleOnUse();
+            try {
+                currentExecutor.execute(runnable);
+            } catch (RejectedExecutionException e) {
+                runnable.recycle();
+                locationCallbackFinished();
+                throw e;
+            }
+        }
+
+        private void acceptLocation(Executor currentExecutor, Location location) {
+            try {
+                if (currentExecutor != mExecutor) {
+                    return;
+                }
+
+                // we may be under the binder identity if a direct executor is used
+                long identity = Binder.clearCallingIdentity();
+                try {
+                    mListener.onLocationChanged(location);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            } finally {
+                locationCallbackFinished();
+            }
+        }
+
+        @Override
+        public void onProviderEnabled(String provider) {
+            Executor currentExecutor = mExecutor;
+            if (currentExecutor == null) {
+                return;
+            }
+
+            PooledRunnable runnable =
+                    obtainRunnable(LocationListenerTransport::acceptProviderChange, this,
+                            currentExecutor, provider, true).recycleOnUse();
+            try {
+                currentExecutor.execute(runnable);
+            } catch (RejectedExecutionException e) {
+                runnable.recycle();
+                locationCallbackFinished();
+                throw e;
+            }
+        }
+
+        @Override
+        public void onProviderDisabled(String provider) {
+            Executor currentExecutor = mExecutor;
+            if (currentExecutor == null) {
+                return;
+            }
+
+            PooledRunnable runnable =
+                    obtainRunnable(LocationListenerTransport::acceptProviderChange, this,
+                            currentExecutor, provider, false).recycleOnUse();
+            try {
+                currentExecutor.execute(runnable);
+            } catch (RejectedExecutionException e) {
+                runnable.recycle();
+                locationCallbackFinished();
+                throw e;
+            }
+        }
+
+        private void acceptProviderChange(Executor currentExecutor, String provider,
+                boolean enabled) {
+            try {
+                if (currentExecutor != mExecutor) {
+                    return;
+                }
+
+                // we may be under the binder identity if a direct executor is used
+                long identity = Binder.clearCallingIdentity();
+                try {
+                    if (enabled) {
+                        mListener.onProviderEnabled(provider);
+                    } else {
+                        mListener.onProviderDisabled(provider);
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            } finally {
+                locationCallbackFinished();
+            }
+        }
+
+        @Override
+        public void onRemoved() {
+            // TODO: onRemoved is necessary to GC hanging listeners, but introduces some interesting
+            //  broken edge cases. luckily these edge cases are quite unlikely. consider the
+            //  following interleaving for instance:
+            //    1) client adds single shot location request (A)
+            //    2) client gets removal callback, and schedules it for execution
+            //    3) client replaces single shot request with a different location request (B)
+            //    4) prior removal callback is executed, removing location request (B) incorrectly
+            //  what's needed is a way to identify which listener a callback belongs to. currently
+            //  we reuse the same transport object for the same listeners (so that we don't leak
+            //  transport objects on the server side). there seem to be two solutions:
+            //    1) when reregistering a request, first unregister the current transport, then
+            //       register with a new transport object (never reuse transport objects) - the
+            //       downside is that this breaks the server's knowledge that the request is the
+            //       same object, and thus breaks optimizations such as reusing the same transport
+            //       state.
+            //    2) pass some other type of marker in addition to the transport (for example an
+            //       incrementing integer representing the transport "version"), and pass this
+            //       marker back into callbacks so that each callback knows which transport
+            //       "version" it belongs to and can not execute itself if the version does not
+            //       match.
+            //  (1) seems like the preferred solution as it's simpler to implement and the above
+            //  mentioned server optimizations are not terribly important (they can be bypassed by
+            //  clients that use a new listener every time anyways).
+
+            Executor currentExecutor = mExecutor;
+            if (currentExecutor == null) {
+                // we've already been unregistered, no work to do anyways
+                return;
+            }
+
+            // must be executed on the same executor so callback execution cannot be reordered
+            currentExecutor.execute(() -> {
+                if (currentExecutor != mExecutor) {
+                    return;
+                }
+
+                unregister();
+                synchronized (mListeners) {
+                    mListeners.remove(mListener, this);
+                }
+            });
+        }
+
+        private void locationCallbackFinished() {
+            try {
+                mService.locationCallbackFinished(this);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    private static class NmeaAdapter extends GnssStatus.Callback implements OnNmeaMessageListener {
+
+        private final OnNmeaMessageListener mListener;
+
+        private NmeaAdapter(OnNmeaMessageListener listener) {
+            mListener = listener;
+        }
+
+        @Override
+        public void onNmeaMessage(String message, long timestamp) {
+            mListener.onNmeaMessage(message, timestamp);
+        }
+    }
+
+    private class GnssStatusListenerManager extends
+            AbstractListenerManager<Void, GnssStatus.Callback> {
+        @Nullable
+        private IGnssStatusListener mListenerTransport;
+
+        @Nullable
+        private volatile GnssStatus mGnssStatus;
+        private volatile int mTtff;
+
+        public GnssStatus getGnssStatus() {
+            return mGnssStatus;
+        }
+
+        public int getTtff() {
+            return mTtff;
+        }
+
+        public boolean addListener(@NonNull GpsStatus.Listener listener, @NonNull Executor executor)
+                throws RemoteException {
+            return addInternal(null, listener, executor);
+        }
+
+        public boolean addListener(@NonNull OnNmeaMessageListener listener,
+                @NonNull Handler handler)
+                throws RemoteException {
+            return addInternal(null, listener, handler);
+        }
+
+        public boolean addListener(@NonNull OnNmeaMessageListener listener,
+                @NonNull Executor executor)
+                throws RemoteException {
+            return addInternal(null, listener, executor);
+        }
+
+        @Override
+        protected GnssStatus.Callback convertKey(Object listener) {
+            if (listener instanceof GnssStatus.Callback) {
+                return (GnssStatus.Callback) listener;
+            } else if (listener instanceof GpsStatus.Listener) {
+                return new GnssStatus.Callback() {
+                    private final GpsStatus.Listener mGpsListener = (GpsStatus.Listener) listener;
+
+                    @Override
+                    public void onStarted() {
+                        mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
+                    }
+
+                    @Override
+                    public void onStopped() {
+                        mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED);
+                    }
+
+                    @Override
+                    public void onFirstFix(int ttffMillis) {
+                        mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX);
+                    }
+
+                    @Override
+                    public void onSatelliteStatusChanged(GnssStatus status) {
+                        mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
+                    }
+                };
+            } else if (listener instanceof OnNmeaMessageListener) {
+                return new NmeaAdapter((OnNmeaMessageListener) listener);
+            } else {
+                throw new IllegalStateException();
+            }
+        }
+
+        @Override
+        protected boolean registerService(Void ignored) throws RemoteException {
+            Preconditions.checkState(mListenerTransport == null);
+
+            GnssStatusListener transport = new GnssStatusListener();
+            if (mService.registerGnssStatusCallback(transport, mContext.getPackageName(),
+                    mContext.getAttributionTag())) {
+                mListenerTransport = transport;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        protected void unregisterService() throws RemoteException {
+            Preconditions.checkState(mListenerTransport != null);
+
+            mService.unregisterGnssStatusCallback(mListenerTransport);
+            mListenerTransport = null;
+        }
+
+        private class GnssStatusListener extends IGnssStatusListener.Stub {
+            @Override
+            public void onGnssStarted() {
+                execute(GnssStatus.Callback::onStarted);
+            }
+
+            @Override
+            public void onGnssStopped() {
+                execute(GnssStatus.Callback::onStopped);
+            }
+
+            @Override
+            public void onFirstFix(int ttff) {
+                mTtff = ttff;
+                execute((callback) -> callback.onFirstFix(ttff));
+            }
+
+            @Override
+            public void onSvStatusChanged(int svCount, int[] svidWithFlags, float[] cn0s,
+                    float[] elevations, float[] azimuths, float[] carrierFreqs,
+                    float[] basebandCn0s) {
+                GnssStatus localStatus = GnssStatus.wrap(svCount, svidWithFlags, cn0s,
+                        elevations, azimuths, carrierFreqs, basebandCn0s);
+                mGnssStatus = localStatus;
+                execute((callback) -> callback.onSatelliteStatusChanged(localStatus));
+            }
+
+            @Override
+            public void onNmeaReceived(long timestamp, String nmea) {
+                execute((callback) -> {
+                    if (callback instanceof NmeaAdapter) {
+                        ((NmeaAdapter) callback).onNmeaMessage(nmea, timestamp);
+                    }
+                });
+            }
+        }
+    }
+
+    private class GnssMeasurementsListenerManager extends
+            AbstractListenerManager<GnssRequest, GnssMeasurementsEvent.Callback> {
+
+        @Nullable
+        private IGnssMeasurementsListener mListenerTransport;
+
+        @Override
+        protected boolean registerService(GnssRequest request) throws RemoteException {
+            Preconditions.checkState(mListenerTransport == null);
+
+            GnssMeasurementsListener transport = new GnssMeasurementsListener();
+            if (mService.addGnssMeasurementsListener(request, transport, mContext.getPackageName(),
+                    mContext.getAttributionTag())) {
+                mListenerTransport = transport;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        protected void unregisterService() throws RemoteException {
+            Preconditions.checkState(mListenerTransport != null);
+
+            mService.removeGnssMeasurementsListener(mListenerTransport);
+            mListenerTransport = null;
+        }
+
+        @Override
+        @Nullable
+        protected GnssRequest merge(@NonNull GnssRequest[] requests) {
+            Preconditions.checkArgument(requests.length > 0);
+            for (GnssRequest request : requests) {
+                if (request.isFullTracking()) {
+                    return request;
+                }
+            }
+            return requests[0];
+        }
+
+        private class GnssMeasurementsListener extends IGnssMeasurementsListener.Stub {
+            @Override
+            public void onGnssMeasurementsReceived(final GnssMeasurementsEvent event) {
+                execute((callback) -> callback.onGnssMeasurementsReceived(event));
+            }
+
+            @Override
+            public void onStatusChanged(int status) {
+                execute((callback) -> callback.onStatusChanged(status));
+            }
+        }
+    }
+
+    private class GnssNavigationMessageListenerManager extends
+            AbstractListenerManager<Void, GnssNavigationMessage.Callback> {
+
+        @Nullable
+        private IGnssNavigationMessageListener mListenerTransport;
+
+        @Override
+        protected boolean registerService(Void ignored) throws RemoteException {
+            Preconditions.checkState(mListenerTransport == null);
+
+            GnssNavigationMessageListener transport = new GnssNavigationMessageListener();
+            if (mService.addGnssNavigationMessageListener(transport, mContext.getPackageName(),
+                    mContext.getAttributionTag())) {
+                mListenerTransport = transport;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        protected void unregisterService() throws RemoteException {
+            Preconditions.checkState(mListenerTransport != null);
+
+            mService.removeGnssNavigationMessageListener(mListenerTransport);
+            mListenerTransport = null;
+        }
+
+        private class GnssNavigationMessageListener extends IGnssNavigationMessageListener.Stub {
+            @Override
+            public void onGnssNavigationMessageReceived(GnssNavigationMessage event) {
+                execute((listener) -> listener.onGnssNavigationMessageReceived(event));
+            }
+
+            @Override
+            public void onStatusChanged(int status) {
+                execute((listener) -> listener.onStatusChanged(status));
+            }
+        }
+    }
+
+    private class GnssAntennaInfoListenerManager extends
+            AbstractListenerManager<Void, GnssAntennaInfo.Listener> {
+
+        @Nullable
+        private IGnssAntennaInfoListener mListenerTransport;
+
+        @Override
+        protected boolean registerService(Void ignored) throws RemoteException {
+            Preconditions.checkState(mListenerTransport == null);
+
+            GnssAntennaInfoListener transport = new GnssAntennaInfoListener();
+            if (mService.addGnssAntennaInfoListener(transport, mContext.getPackageName(),
+                    mContext.getAttributionTag())) {
+                mListenerTransport = transport;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        protected void unregisterService() throws RemoteException {
+            Preconditions.checkState(mListenerTransport != null);
+
+            mService.removeGnssAntennaInfoListener(mListenerTransport);
+            mListenerTransport = null;
+        }
+
+        private class GnssAntennaInfoListener extends IGnssAntennaInfoListener.Stub {
+            @Override
+            public void onGnssAntennaInfoReceived(final List<GnssAntennaInfo> gnssAntennaInfos) {
+                execute((callback) -> callback.onGnssAntennaInfoReceived(gnssAntennaInfos));
+            }
+        }
+
+    }
+
+    private class BatchedLocationCallbackManager extends
+            AbstractListenerManager<Void, BatchedLocationCallback> {
+
+        @Nullable
+        private IBatchedLocationCallback mListenerTransport;
+
+        @Override
+        protected boolean registerService(Void ignored) throws RemoteException {
+            Preconditions.checkState(mListenerTransport == null);
+
+            BatchedLocationCallback transport = new BatchedLocationCallback();
+            if (mService.addGnssBatchingCallback(transport, mContext.getPackageName(),
+                    mContext.getAttributionTag())) {
+                mListenerTransport = transport;
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        protected void unregisterService() throws RemoteException {
+            Preconditions.checkState(mListenerTransport != null);
+
+            mService.removeGnssBatchingCallback();
+            mListenerTransport = null;
+        }
+
+        private class BatchedLocationCallback extends IBatchedLocationCallback.Stub {
+            @Override
+            public void onLocationBatch(List<Location> locations) {
+                execute((listener) -> listener.onLocationBatch(locations));
+            }
+
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static final String CACHE_KEY_LOCATION_ENABLED_PROPERTY =
+            "cache_key.location_enabled";
+
+    /**
+     * @hide
+     */
+    public static void invalidateLocalLocationEnabledCaches() {
+        PropertyInvalidatedCache.invalidateCache(CACHE_KEY_LOCATION_ENABLED_PROPERTY);
+    }
+
+    /**
+     * @hide
+     */
+    public void disableLocalLocationEnabledCaches() {
+        synchronized (mLock) {
+            mLocationEnabledCache = null;
+        }
+    }
+}
diff --git a/android/location/LocationManagerInternal.java b/android/location/LocationManagerInternal.java
new file mode 100644
index 0000000..6006d50
--- /dev/null
+++ b/android/location/LocationManagerInternal.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 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.location;
+
+
+import android.annotation.NonNull;
+
+/**
+ * Location manager local system service interface.
+ *
+ * @hide Only for use within the system server.
+ */
+public abstract class LocationManagerInternal {
+
+    /**
+     * Returns true if the given provider is enabled for the given user.
+     *
+     * @param provider A location provider as listed by {@link LocationManager#getAllProviders()}
+     * @param userId   The user id to check
+     * @return True if the provider is enabled, false otherwise
+     */
+    public abstract boolean isProviderEnabledForUser(@NonNull String provider, int userId);
+
+    /**
+     * Returns true if the given package belongs to a location provider, and so should be afforded
+     * some special privileges.
+     *
+     * @param packageName The package name to check
+     * @return True is the given package belongs to a location provider, false otherwise
+     */
+    public abstract boolean isProviderPackage(@NonNull String packageName);
+
+    /**
+     * Should only be used by GNSS code.
+     */
+    // TODO: there is no reason for this to exist as part of any API. move all the logic into gnss
+    public abstract void sendNiResponse(int notifId, int userResponse);
+}
diff --git a/android/location/LocationProvider.java b/android/location/LocationProvider.java
new file mode 100644
index 0000000..52a03b6
--- /dev/null
+++ b/android/location/LocationProvider.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2007 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.location;
+
+
+import com.android.internal.location.ProviderProperties;
+
+/**
+ * An abstract superclass for location providers.  A location provider
+ * provides periodic reports on the geographical location of the
+ * device.
+ *
+ * <p> Each provider has a set of criteria under which it may be used;
+ * for example, some providers require GPS hardware and visibility to
+ * a number of satellites; others require the use of the cellular
+ * radio, or access to a specific carrier's network, or to the
+ * internet.  They may also have different battery consumption
+ * characteristics or monetary costs to the user.  The {@link
+ * Criteria} class allows providers to be selected based on
+ * user-specified criteria.
+ */
+public class LocationProvider {
+
+    /**
+     * @deprecated Location provider statuses are no longer supported.
+     */
+    @Deprecated
+    public static final int OUT_OF_SERVICE = 0;
+
+    /**
+     * @deprecated Location provider statuses are no longer supported.
+     */
+    @Deprecated
+    public static final int TEMPORARILY_UNAVAILABLE = 1;
+
+    /**
+     * @deprecated Location provider statuses are no longer supported.
+     */
+    @Deprecated
+    public static final int AVAILABLE = 2;
+
+    private final String mName;
+    private final ProviderProperties mProperties;
+
+    LocationProvider(String name, ProviderProperties properties) {
+        mName = name;
+        mProperties = properties;
+    }
+
+    /**
+     * Returns the name of this provider.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Returns true if this provider meets the given criteria,
+     * false otherwise.
+     */
+    public boolean meetsCriteria(Criteria criteria) {
+        return propertiesMeetCriteria(mName, mProperties, criteria);
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean propertiesMeetCriteria(String name, ProviderProperties properties,
+            Criteria criteria) {
+        if (LocationManager.PASSIVE_PROVIDER.equals(name)) {
+            // passive provider never matches
+            return false;
+        }
+        if (properties == null) {
+            // unfortunately this can happen for provider in remote services
+            // that have not finished binding yet
+            return false;
+        }
+
+        if (criteria.getAccuracy() != Criteria.NO_REQUIREMENT &&
+                criteria.getAccuracy() < properties.mAccuracy) {
+            return false;
+        }
+        if (criteria.getPowerRequirement() != Criteria.NO_REQUIREMENT &&
+                criteria.getPowerRequirement() < properties.mPowerRequirement) {
+            return false;
+        }
+        if (criteria.isAltitudeRequired() && !properties.mSupportsAltitude) {
+            return false;
+        }
+        if (criteria.isSpeedRequired() && !properties.mSupportsSpeed) {
+            return false;
+        }
+        if (criteria.isBearingRequired() && !properties.mSupportsBearing) {
+            return false;
+        }
+        if (!criteria.isCostAllowed() && properties.mHasMonetaryCost) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the provider requires access to a
+     * data network (e.g., the Internet), false otherwise.
+     */
+    public boolean requiresNetwork() {
+        return mProperties.mRequiresNetwork;
+    }
+
+    /**
+     * Returns true if the provider requires access to a
+     * satellite-based positioning system (e.g., GPS), false
+     * otherwise.
+     */
+    public boolean requiresSatellite() {
+        return mProperties.mRequiresSatellite;
+    }
+
+    /**
+     * Returns true if the provider requires access to an appropriate
+     * cellular network (e.g., to make use of cell tower IDs), false
+     * otherwise.
+     */
+    public boolean requiresCell() {
+        return mProperties.mRequiresCell;
+    }
+
+    /**
+     * Returns true if the use of this provider may result in a
+     * monetary charge to the user, false if use is free.  It is up to
+     * each provider to give accurate information.
+     */
+    public boolean hasMonetaryCost() {
+        return mProperties.mHasMonetaryCost;
+    }
+
+    /**
+     * Returns true if the provider is able to provide altitude
+     * information, false otherwise.  A provider that reports altitude
+     * under most circumstances but may occassionally not report it
+     * should return true.
+     */
+    public boolean supportsAltitude() {
+        return mProperties.mSupportsAltitude;
+    }
+
+    /**
+     * Returns true if the provider is able to provide speed
+     * information, false otherwise.  A provider that reports speed
+     * under most circumstances but may occassionally not report it
+     * should return true.
+     */
+    public boolean supportsSpeed() {
+        return mProperties.mSupportsSpeed;
+    }
+
+    /**
+     * Returns true if the provider is able to provide bearing
+     * information, false otherwise.  A provider that reports bearing
+     * under most circumstances but may occassionally not report it
+     * should return true.
+     */
+    public boolean supportsBearing() {
+        return mProperties.mSupportsBearing;
+    }
+
+    /**
+     * Returns the power requirement for this provider.
+     *
+     * @return the power requirement for this provider, as one of the
+     * constants Criteria.POWER_REQUIREMENT_*.
+     */
+    public int getPowerRequirement() {
+        return mProperties.mPowerRequirement;
+    }
+
+    /**
+     * Returns a constant describing horizontal accuracy of this provider.
+     * If the provider returns finer grain or exact location,
+     * {@link Criteria#ACCURACY_FINE} is returned, otherwise if the
+     * location is only approximate then {@link Criteria#ACCURACY_COARSE}
+     * is returned.
+     */
+    public int getAccuracy() {
+        return mProperties.mAccuracy;
+    }
+}
diff --git a/android/location/LocationRequest.java b/android/location/LocationRequest.java
new file mode 100644
index 0000000..5f0acc8
--- /dev/null
+++ b/android/location/LocationRequest.java
@@ -0,0 +1,799 @@
+/*
+ * Copyright (C) 2012 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.location;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.WorkSource;
+import android.util.TimeUtils;
+
+import com.android.internal.util.Preconditions;
+
+
+/**
+ * A data object that contains quality of service parameters for requests
+ * to the {@link LocationManager}.
+ *
+ * <p>LocationRequest objects are used to request a quality of service
+ * for location updates from the Location Manager.
+ *
+ * <p>For example, if your application wants high accuracy location
+ * it should create a location request with {@link #setQuality} set to
+ * {@link #ACCURACY_FINE} or {@link #POWER_HIGH}, and it should set
+ * {@link #setInterval} to less than one second. This would be
+ * appropriate for mapping applications that are showing your location
+ * in real-time.
+ *
+ * <p>At the other extreme, if you want negligible power
+ * impact, but to still receive location updates when available, then use
+ * {@link #setQuality} with {@link #POWER_NONE}. With this request your
+ * application will not trigger (and therefore will not receive any
+ * power blame) any location updates, but will receive locations
+ * triggered by other applications. This would be appropriate for
+ * applications that have no firm requirement for location, but can
+ * take advantage when available.
+ *
+ * <p>In between these two extremes is a very common use-case, where
+ * applications definitely want to receive
+ * updates at a specified interval, and can receive them faster when
+ * available, but still want a low power impact. These applications
+ * should consider {@link #POWER_LOW} combined with a faster
+ * {@link #setFastestInterval} (such as 1 minute) and a slower
+ * {@link #setInterval} (such as 60 minutes). They will only be assigned
+ * power blame for the interval set by {@link #setInterval}, but can
+ * still receive locations triggered by other applications at a rate up
+ * to {@link #setFastestInterval}. This style of request is appropriate for
+ * many location aware applications, including background usage. Do be
+ * careful to also throttle {@link #setFastestInterval} if you perform
+ * heavy-weight work after receiving an update - such as using the network.
+ *
+ * <p>Activities should strongly consider removing all location
+ * request when entering the background, or
+ * at least swap the request to a larger interval and lower quality.
+ * Future version of the location manager may automatically perform background
+ * throttling on behalf of applications.
+ *
+ * <p>Applications cannot specify the exact location sources that are
+ * used by Android's <em>Fusion Engine</em>. In fact, the system
+ * may have multiple location sources (providers) running and may
+ * fuse the results from several sources into a single Location object.
+ *
+ * <p>Location requests from applications with
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and not
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} will
+ * be automatically throttled to a slower interval, and the location
+ * object will be obfuscated to only show a coarse level of accuracy.
+ *
+ * <p>All location requests are considered hints, and you may receive
+ * locations that are more accurate, less accurate, and slower
+ * than requested.
+ *
+ * @hide
+ */
+@SystemApi
+@TestApi
+public final class LocationRequest implements Parcelable {
+    /**
+     * Used with {@link #setQuality} to request the most accurate locations available.
+     *
+     * <p>This may be up to 1 meter accuracy, although this is implementation dependent.
+     */
+    public static final int ACCURACY_FINE = 100;
+
+    /**
+     * Used with {@link #setQuality} to request "block" level accuracy.
+     *
+     * <p>Block level accuracy is considered to be about 100 meter accuracy,
+     * although this is implementation dependent. Using a coarse accuracy
+     * such as this often consumes less power.
+     */
+    public static final int ACCURACY_BLOCK = 102;
+
+    /**
+     * Used with {@link #setQuality} to request "city" level accuracy.
+     *
+     * <p>City level accuracy is considered to be about 10km accuracy,
+     * although this is implementation dependent. Using a coarse accuracy
+     * such as this often consumes less power.
+     */
+    public static final int ACCURACY_CITY = 104;
+
+    /**
+     * Used with {@link #setQuality} to require no direct power impact (passive locations).
+     *
+     * <p>This location request will not trigger any active location requests,
+     * but will receive locations triggered by other applications. Your application
+     * will not receive any direct power blame for location work.
+     */
+    public static final int POWER_NONE = 200;
+
+    /**
+     * Used with {@link #setQuality} to request low power impact.
+     *
+     * <p>This location request will avoid high power location work where
+     * possible.
+     */
+    public static final int POWER_LOW = 201;
+
+    /**
+     * Used with {@link #setQuality} to allow high power consumption for location.
+     *
+     * <p>This location request will allow high power location work.
+     */
+    public static final int POWER_HIGH = 203;
+
+    private static final long DEFAULT_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
+    private static final double FASTEST_INTERVAL_FACTOR = 6.0;  // 6x
+
+    @UnsupportedAppUsage
+    private String mProvider;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private int mQuality;
+    @UnsupportedAppUsage
+    private long mInterval;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private long mFastestInterval;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private boolean mExplicitFastestInterval;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private long mExpireAt;
+    private long mExpireIn;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private int mNumUpdates;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private float mSmallestDisplacement;
+    @UnsupportedAppUsage
+    private boolean mHideFromAppOps;
+    private boolean mLocationSettingsIgnored;
+    private boolean mLowPowerMode;
+    @UnsupportedAppUsage
+    private @Nullable WorkSource mWorkSource;
+
+    /**
+     * Create a location request with default parameters.
+     *
+     * <p>Default parameters are for a low power, slowly updated location.
+     * It can then be adjusted as required by the applications before passing
+     * to the {@link LocationManager}
+     *
+     * @return a new location request
+     */
+    @NonNull
+    public static LocationRequest create() {
+        return new LocationRequest();
+    }
+
+    /** @hide */
+    @SystemApi
+    @NonNull
+    public static LocationRequest createFromDeprecatedProvider(
+            @NonNull String provider, long minTime, float minDistance, boolean singleShot) {
+        Preconditions.checkArgument(provider != null, "invalid null provider");
+
+        if (minTime < 0) minTime = 0;
+        if (minDistance < 0) minDistance = 0;
+
+        int quality;
+        if (LocationManager.PASSIVE_PROVIDER.equals(provider)) {
+            quality = POWER_NONE;
+        } else if (LocationManager.GPS_PROVIDER.equals(provider)) {
+            quality = ACCURACY_FINE;
+        } else {
+            quality = POWER_LOW;
+        }
+
+        LocationRequest request = new LocationRequest()
+                .setProvider(provider)
+                .setQuality(quality)
+                .setInterval(minTime)
+                .setFastestInterval(minTime)
+                .setSmallestDisplacement(minDistance);
+        if (singleShot) request.setNumUpdates(1);
+        return request;
+    }
+
+    /** @hide */
+    @SystemApi
+    @NonNull
+    public static LocationRequest createFromDeprecatedCriteria(
+            @NonNull Criteria criteria, long minTime, float minDistance, boolean singleShot) {
+        Preconditions.checkArgument(criteria != null, "invalid null criteria");
+
+        if (minTime < 0) minTime = 0;
+        if (minDistance < 0) minDistance = 0;
+
+        int quality;
+        switch (criteria.getAccuracy()) {
+            case Criteria.ACCURACY_COARSE:
+                quality = ACCURACY_BLOCK;
+                break;
+            case Criteria.ACCURACY_FINE:
+                quality = ACCURACY_FINE;
+                break;
+            default: {
+                if (criteria.getPowerRequirement() == Criteria.POWER_HIGH) {
+                    quality = POWER_HIGH;
+                } else {
+                    quality = POWER_LOW;
+                }
+            }
+        }
+
+        LocationRequest request = new LocationRequest()
+                .setQuality(quality)
+                .setInterval(minTime)
+                .setFastestInterval(minTime)
+                .setSmallestDisplacement(minDistance);
+        if (singleShot) request.setNumUpdates(1);
+        return request;
+    }
+
+    /** @hide */
+    public LocationRequest() {
+        this(
+                /* provider= */ LocationManager.FUSED_PROVIDER,
+                /* quality= */ POWER_LOW,
+                /* interval= */ DEFAULT_INTERVAL_MS,
+                /* fastestInterval= */ (long) (DEFAULT_INTERVAL_MS / FASTEST_INTERVAL_FACTOR),
+                /* explicitFastestInterval= */ false,
+                /* expireAt= */ Long.MAX_VALUE,
+                /* expireIn= */ Long.MAX_VALUE,
+                /* numUpdates= */ Integer.MAX_VALUE,
+                /* smallestDisplacement= */ 0,
+                /* hideFromAppOps= */ false,
+                /* locationSettingsIgnored= */ false,
+                /* lowPowerMode= */ false,
+                /* workSource= */ null);
+    }
+
+    /** @hide */
+    public LocationRequest(LocationRequest src) {
+        this(
+                src.mProvider,
+                src.mQuality,
+                src.mInterval,
+                src.mFastestInterval,
+                src.mExplicitFastestInterval,
+                src.mExpireAt,
+                src.mExpireIn,
+                src.mNumUpdates,
+                src.mSmallestDisplacement,
+                src.mHideFromAppOps,
+                src.mLocationSettingsIgnored,
+                src.mLowPowerMode,
+                src.mWorkSource);
+    }
+
+    private LocationRequest(
+            @NonNull String provider,
+            int quality,
+            long intervalMs,
+            long fastestIntervalMs,
+            boolean explicitFastestInterval,
+            long expireAt,
+            long expireInMs,
+            int numUpdates,
+            float smallestDisplacementM,
+            boolean hideFromAppOps,
+            boolean locationSettingsIgnored,
+            boolean lowPowerMode,
+            WorkSource workSource) {
+        Preconditions.checkArgument(provider != null, "invalid provider: null");
+        checkQuality(quality);
+
+        mProvider = provider;
+        mQuality = quality;
+        mInterval = intervalMs;
+        mFastestInterval = fastestIntervalMs;
+        mExplicitFastestInterval = explicitFastestInterval;
+        mExpireAt = expireAt;
+        mExpireIn = expireInMs;
+        mNumUpdates = numUpdates;
+        mSmallestDisplacement = Preconditions.checkArgumentInRange(smallestDisplacementM, 0,
+                Float.MAX_VALUE, "smallestDisplacementM");
+        mHideFromAppOps = hideFromAppOps;
+        mLowPowerMode = lowPowerMode;
+        mLocationSettingsIgnored = locationSettingsIgnored;
+        mWorkSource = workSource;
+    }
+
+    /**
+     * Set the quality of the request.
+     *
+     * <p>Use with a accuracy constant such as {@link #ACCURACY_FINE}, or a power
+     * constant such as {@link #POWER_LOW}. You cannot request both accuracy and
+     * power, only one or the other can be specified. The system will then
+     * maximize accuracy or minimize power as appropriate.
+     *
+     * <p>The quality of the request is a strong hint to the system for which
+     * location sources to use. For example, {@link #ACCURACY_FINE} is more likely
+     * to use GPS, and {@link #POWER_LOW} is more likely to use WIFI & Cell tower
+     * positioning, but it also depends on many other factors (such as which sources
+     * are available) and is implementation dependent.
+     *
+     * <p>{@link #setQuality} and {@link #setInterval} are the most important parameters
+     * on a location request.
+     *
+     * @param quality an accuracy or power constant
+     * @return the same object, so that setters can be chained
+     * @throws IllegalArgumentException if the quality constant is not valid
+     */
+    public @NonNull LocationRequest setQuality(int quality) {
+        checkQuality(quality);
+        mQuality = quality;
+        return this;
+    }
+
+    /**
+     * Get the quality of the request.
+     *
+     * @return an accuracy or power constant
+     */
+    public int getQuality() {
+        return mQuality;
+    }
+
+    /**
+     * Set the desired interval for active location updates, in milliseconds.
+     *
+     * <p>The location manager will actively try to obtain location updates
+     * for your application at this interval, so it has a
+     * direct influence on the amount of power used by your application.
+     * Choose your interval wisely.
+     *
+     * <p>This interval is inexact. You may not receive updates at all (if
+     * no location sources are available), or you may receive them
+     * slower than requested. You may also receive them faster than
+     * requested (if other applications are requesting location at a
+     * faster interval). The fastest rate that you will receive
+     * updates can be controlled with {@link #setFastestInterval}.
+     *
+     * <p>Applications with only the coarse location permission may have their
+     * interval silently throttled.
+     *
+     * <p>An interval of 0 is allowed, but not recommended, since
+     * location updates may be extremely fast on future implementations.
+     *
+     * <p>{@link #setQuality} and {@link #setInterval} are the most important parameters
+     * on a location request.
+     *
+     * @param millis desired interval in millisecond, inexact
+     * @return the same object, so that setters can be chained
+     * @throws IllegalArgumentException if the interval is less than zero
+     */
+    public @NonNull LocationRequest setInterval(long millis) {
+        Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
+        mInterval = millis;
+        if (!mExplicitFastestInterval) {
+            mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR);
+        }
+        return this;
+    }
+
+    /**
+     * Get the desired interval of this request, in milliseconds.
+     *
+     * @return desired interval in milliseconds, inexact
+     */
+    public long getInterval() {
+        return mInterval;
+    }
+
+
+    /**
+     * Requests the GNSS chipset to run in a low power mode and make strong tradeoffs to
+     * substantially restrict power.
+     *
+     * <p>In this mode, the GNSS chipset will not, on average, run power hungry operations like RF &
+     * signal searches for more than one second per interval (specified by
+     * {@link #setInterval(long)}).
+     *
+     * @param enabled Enable or disable low power mode
+     * @return the same object, so that setters can be chained
+     */
+    public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
+        mLowPowerMode = enabled;
+        return this;
+    }
+
+    /**
+     * Returns true if low power mode is enabled.
+     */
+    public boolean isLowPowerMode() {
+        return mLowPowerMode;
+    }
+
+    /**
+     * Requests that user location settings be ignored in order to satisfy this request. This API
+     * is only for use in extremely rare scenarios where it is appropriate to ignore user location
+     * settings, such as a user initiated emergency (dialing 911 for instance).
+     *
+     * @param locationSettingsIgnored Whether to ignore location settings
+     * @return the same object, so that setters can be chained
+     */
+    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+    public @NonNull LocationRequest setLocationSettingsIgnored(boolean locationSettingsIgnored) {
+        mLocationSettingsIgnored = locationSettingsIgnored;
+        return this;
+    }
+
+    /**
+     * Returns true if location settings will be ignored in order to satisfy this request.
+     */
+    public boolean isLocationSettingsIgnored() {
+        return mLocationSettingsIgnored;
+    }
+
+    /**
+     * Explicitly set the fastest interval for location updates, in
+     * milliseconds.
+     *
+     * <p>This controls the fastest rate at which your application will
+     * receive location updates, which might be faster than
+     * {@link #setInterval} in some situations (for example, if other
+     * applications are triggering location updates).
+     *
+     * <p>This allows your application to passively acquire locations
+     * at a rate faster than it actively acquires locations, saving power.
+     *
+     * <p>Unlike {@link #setInterval}, this parameter is exact. Your
+     * application will never receive updates faster than this value.
+     *
+     * <p>If you don't call this method, a fastest interval
+     * will be selected for you. It will be a value faster than your
+     * active interval ({@link #setInterval}).
+     *
+     * <p>An interval of 0 is allowed, but not recommended, since
+     * location updates may be extremely fast on future implementations.
+     *
+     * <p>If the fastest interval set is slower than {@link #setInterval},
+     * then your effective fastest interval is {@link #setInterval}.
+     *
+     * @param millis fastest interval for updates in milliseconds
+     * @return the same object, so that setters can be chained
+     * @throws IllegalArgumentException if the interval is less than zero
+     */
+    public @NonNull LocationRequest setFastestInterval(long millis) {
+        Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
+        mExplicitFastestInterval = true;
+        mFastestInterval = millis;
+        return this;
+    }
+
+    /**
+     * Get the fastest interval of this request in milliseconds. The system will never provide
+     * location updates faster than the minimum of the fastest interval and {@link #getInterval}.
+     *
+     * @return fastest interval in milliseconds
+     */
+    public long getFastestInterval() {
+        return mFastestInterval;
+    }
+
+    /**
+     * Set the expiration time of this request in milliseconds of realtime since boot. Values in the
+     * past are allowed, but indicate that the request has already expired. The location manager
+     * will automatically stop updates after the request expires.
+     *
+     * @param millis expiration time of request in milliseconds since boot
+     * @return the same object, so that setters can be chained
+     * @see SystemClock#elapsedRealtime()
+     * @deprecated Prefer {@link #setExpireIn(long)}.
+     */
+    @Deprecated
+    public @NonNull LocationRequest setExpireAt(long millis) {
+        mExpireAt = Math.max(millis, 0);
+        return this;
+    }
+
+    /**
+     * Get the request expiration time in milliseconds of realtime since boot.
+     *
+     * @return request expiration time in milliseconds since boot
+     * @see SystemClock#elapsedRealtime()
+     * @deprecated Prefer {@link #getExpireIn()}.
+     */
+    @Deprecated
+    public long getExpireAt() {
+        return mExpireAt;
+    }
+
+    /**
+     * Set the duration of this request in milliseconds of realtime. Values less than 0 are allowed,
+     * but indicate that the request has already expired. The location manager will automatically
+     * stop updates after the request expires.
+     *
+     * @param millis duration of request in milliseconds
+     * @return the same object, so that setters can be chained
+     * @see SystemClock#elapsedRealtime()
+     */
+    public @NonNull LocationRequest setExpireIn(long millis) {
+        mExpireIn = millis;
+        return this;
+    }
+
+    /**
+     * Get the request expiration duration in milliseconds of realtime.
+     *
+     * @return request expiration duration in milliseconds
+     * @see SystemClock#elapsedRealtime()
+     */
+    public long getExpireIn() {
+        return mExpireIn;
+    }
+
+    /**
+     * Returns the realtime at which this request expires, taking into account both
+     * {@link #setExpireAt(long)} and {@link #setExpireIn(long)} relative to the given realtime.
+     *
+     * @hide
+     */
+    public long getExpirationRealtimeMs(long startRealtimeMs) {
+        long expirationRealtimeMs;
+        // Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
+        if (mExpireIn > Long.MAX_VALUE - startRealtimeMs) {
+            expirationRealtimeMs = Long.MAX_VALUE;
+        } else {
+            expirationRealtimeMs = startRealtimeMs + mExpireIn;
+        }
+        return Math.min(expirationRealtimeMs, mExpireAt);
+    }
+
+    /**
+     * Set the number of location updates.
+     *
+     * <p>By default locations are continuously updated until the request is explicitly
+     * removed, however you can optionally request a set number of updates.
+     * For example, if your application only needs a single fresh location,
+     * then call this method with a value of 1 before passing the request
+     * to the location manager.
+     *
+     * @param numUpdates the number of location updates requested
+     * @return the same object, so that setters can be chained
+     * @throws IllegalArgumentException if numUpdates is 0 or less
+     */
+    public @NonNull LocationRequest setNumUpdates(int numUpdates) {
+        if (numUpdates <= 0) {
+            throw new IllegalArgumentException(
+                    "invalid numUpdates: " + numUpdates);
+        }
+        mNumUpdates = numUpdates;
+        return this;
+    }
+
+    /**
+     * Get the number of updates requested.
+     *
+     * <p>By default this is {@link Integer#MAX_VALUE}, which indicates that
+     * locations are updated until the request is explicitly removed.
+     *
+     * @return number of updates
+     */
+    public int getNumUpdates() {
+        return mNumUpdates;
+    }
+
+    /** @hide */
+    public void decrementNumUpdates() {
+        if (mNumUpdates != Integer.MAX_VALUE) {
+            mNumUpdates--;
+        }
+        if (mNumUpdates < 0) {
+            mNumUpdates = 0;
+        }
+    }
+
+    /** Sets the provider to use for this location request. */
+    public @NonNull LocationRequest setProvider(@NonNull String provider) {
+        Preconditions.checkArgument(provider != null, "invalid provider: null");
+        mProvider = provider;
+        return this;
+    }
+
+    /** @hide */
+    @SystemApi
+    public @NonNull String getProvider() {
+        return mProvider;
+    }
+
+    /** @hide */
+    @SystemApi
+    public @NonNull LocationRequest setSmallestDisplacement(float smallestDisplacementM) {
+        mSmallestDisplacement = Preconditions.checkArgumentInRange(smallestDisplacementM, 0,
+                Float.MAX_VALUE, "smallestDisplacementM");
+        return this;
+    }
+
+    /** @hide */
+    @SystemApi
+    public float getSmallestDisplacement() {
+        return mSmallestDisplacement;
+    }
+
+    /**
+     * Sets the WorkSource to use for power blaming of this location request.
+     *
+     * <p>No permissions are required to make this call, however the LocationManager
+     * will throw a SecurityException when requesting location updates if the caller
+     * doesn't have the {@link android.Manifest.permission#UPDATE_DEVICE_STATS} permission.
+     *
+     * @param workSource WorkSource defining power blame for this location request.
+     * @hide
+     */
+    @SystemApi
+    public void setWorkSource(@Nullable WorkSource workSource) {
+        mWorkSource = workSource;
+    }
+
+    /** @hide */
+    @SystemApi
+    public @Nullable WorkSource getWorkSource() {
+        return mWorkSource;
+    }
+
+    /**
+     * Sets whether or not this location request should be hidden from AppOps.
+     *
+     * <p>Hiding a location request from AppOps will remove user visibility in the UI as to this
+     * request's existence.  It does not affect power blaming in the Battery page.
+     *
+     * <p>No permissions are required to make this call, however the LocationManager
+     * will throw a SecurityException when requesting location updates if the caller
+     * doesn't have the {@link android.Manifest.permission#UPDATE_APP_OPS_STATS} permission.
+     *
+     * @param hideFromAppOps If true AppOps won't keep track of this location request.
+     * @hide
+     * @see android.app.AppOpsManager
+     */
+    @SystemApi
+    public void setHideFromAppOps(boolean hideFromAppOps) {
+        mHideFromAppOps = hideFromAppOps;
+    }
+
+    /** @hide */
+    @SystemApi
+    public boolean getHideFromAppOps() {
+        return mHideFromAppOps;
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static void checkQuality(int quality) {
+        switch (quality) {
+            case ACCURACY_FINE:
+            case ACCURACY_BLOCK:
+            case ACCURACY_CITY:
+            case POWER_NONE:
+            case POWER_LOW:
+            case POWER_HIGH:
+                break;
+            default:
+                throw new IllegalArgumentException("invalid quality: " + quality);
+        }
+    }
+
+    public static final @NonNull Parcelable.Creator<LocationRequest> CREATOR =
+            new Parcelable.Creator<LocationRequest>() {
+                @Override
+                public LocationRequest createFromParcel(Parcel in) {
+                    return new LocationRequest(
+                            /* provider= */ in.readString(),
+                            /* quality= */ in.readInt(),
+                            /* interval= */ in.readLong(),
+                            /* fastestInterval= */ in.readLong(),
+                            /* explicitFastestInterval= */ in.readBoolean(),
+                            /* expireAt= */ in.readLong(),
+                            /* expireIn= */ in.readLong(),
+                            /* numUpdates= */ in.readInt(),
+                            /* smallestDisplacement= */ in.readFloat(),
+                            /* hideFromAppOps= */ in.readBoolean(),
+                            /* locationSettingsIgnored= */ in.readBoolean(),
+                            /* lowPowerMode= */ in.readBoolean(),
+                            /* workSource= */ in.readTypedObject(WorkSource.CREATOR));
+                }
+
+                @Override
+                public LocationRequest[] newArray(int size) {
+                    return new LocationRequest[size];
+                }
+            };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mProvider);
+        parcel.writeInt(mQuality);
+        parcel.writeLong(mInterval);
+        parcel.writeLong(mFastestInterval);
+        parcel.writeBoolean(mExplicitFastestInterval);
+        parcel.writeLong(mExpireAt);
+        parcel.writeLong(mExpireIn);
+        parcel.writeInt(mNumUpdates);
+        parcel.writeFloat(mSmallestDisplacement);
+        parcel.writeBoolean(mHideFromAppOps);
+        parcel.writeBoolean(mLocationSettingsIgnored);
+        parcel.writeBoolean(mLowPowerMode);
+        parcel.writeTypedObject(mWorkSource, 0);
+    }
+
+    /** @hide */
+    public static String qualityToString(int quality) {
+        switch (quality) {
+            case ACCURACY_FINE:
+                return "ACCURACY_FINE";
+            case ACCURACY_BLOCK:
+                return "ACCURACY_BLOCK";
+            case ACCURACY_CITY:
+                return "ACCURACY_CITY";
+            case POWER_NONE:
+                return "POWER_NONE";
+            case POWER_LOW:
+                return "POWER_LOW";
+            case POWER_HIGH:
+                return "POWER_HIGH";
+            default:
+                return "???";
+        }
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("Request[");
+        s.append(qualityToString(mQuality));
+        s.append(" ").append(mProvider);
+        if (mQuality != POWER_NONE) {
+            s.append(" interval=");
+            TimeUtils.formatDuration(mInterval, s);
+            if (mExplicitFastestInterval) {
+                s.append(" fastestInterval=");
+                TimeUtils.formatDuration(mFastestInterval, s);
+            }
+        }
+        if (mExpireAt != Long.MAX_VALUE) {
+            s.append(" expireAt=").append(TimeUtils.formatRealtime(mExpireAt));
+        }
+        if (mExpireIn != Long.MAX_VALUE) {
+            s.append(" expireIn=");
+            TimeUtils.formatDuration(mExpireIn, s);
+        }
+        if (mNumUpdates != Integer.MAX_VALUE) {
+            s.append(" num=").append(mNumUpdates);
+        }
+        if (mLowPowerMode) {
+            s.append(" lowPowerMode");
+        }
+        if (mLocationSettingsIgnored) {
+            s.append(" locationSettingsIgnored");
+        }
+        s.append(']');
+        return s.toString();
+    }
+}
diff --git a/android/location/LocationTime.java b/android/location/LocationTime.java
new file mode 100644
index 0000000..e5535d1
--- /dev/null
+++ b/android/location/LocationTime.java
@@ -0,0 +1,73 @@
+/*
+ * 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.location;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Data class for passing location derived time.
+ * @hide
+ */
+public final class LocationTime implements Parcelable {
+
+    private final long mTime;
+    private final long mElapsedRealtimeNanos;
+
+    public LocationTime(long time, long elapsedRealtimeNanos) {
+        mTime = time;
+        mElapsedRealtimeNanos = elapsedRealtimeNanos;
+    }
+
+    /**
+     * The current time, according to the Gnss location provider. */
+    public long getTime() {
+        return mTime;
+    }
+
+    /**
+     * The elapsed nanos since boot {@link #getTime} was computed at.
+     */
+    public long getElapsedRealtimeNanos() {
+        return mElapsedRealtimeNanos;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(mTime);
+        out.writeLong(mElapsedRealtimeNanos);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Parcelable.Creator<LocationTime> CREATOR =
+            new Parcelable.Creator<LocationTime>() {
+                public LocationTime createFromParcel(Parcel in) {
+                    long time = in.readLong();
+                    long elapsedRealtimeNanos = in.readLong();
+                    return new LocationTime(time, elapsedRealtimeNanos);
+                }
+
+                public LocationTime[] newArray(int size) {
+                    return new LocationTime[size];
+                }
+            };
+}
diff --git a/android/location/OnNmeaMessageListener.java b/android/location/OnNmeaMessageListener.java
new file mode 100644
index 0000000..05647bc
--- /dev/null
+++ b/android/location/OnNmeaMessageListener.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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.location;
+
+/**
+* Used for receiving NMEA sentences from the GNSS.
+* NMEA 0183 is a standard for communicating with marine electronic devices
+* and is a common method for receiving data from a GNSS, typically over a serial port.
+* See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
+* You can implement this interface and call {@link LocationManager#addNmeaListener}
+* to receive NMEA data from the GNSS engine.
+*/
+public interface OnNmeaMessageListener {
+    /**
+     * Called when an NMEA message is received.
+     * @param message NMEA message
+     * @param timestamp Date and time of the location fix, as reported by the GNSS
+     *                  chipset. The value is specified in milliseconds since 0:00
+     *                  UTC 1 January 1970.
+     */
+    void onNmeaMessage(String message, long timestamp);
+}
diff --git a/android/location/SettingInjectorService.java b/android/location/SettingInjectorService.java
new file mode 100644
index 0000000..d6f8a7c
--- /dev/null
+++ b/android/location/SettingInjectorService.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2013 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.location;
+
+import android.annotation.NonNull;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Dynamically specifies the summary (subtitle) and enabled status of a preference injected into
+ * the list of app settings displayed by the system settings app
+ * <p/>
+ * For use only by apps that are included in the system image, for preferences that affect multiple
+ * apps. Location settings that apply only to one app should be shown within that app,
+ * rather than in the system settings.
+ * <p/>
+ * To add a preference to the list, a subclass of {@link SettingInjectorService} must be declared in
+ * the manifest as so:
+ *
+ * <pre>
+ *     &lt;service android:name="com.example.android.injector.MyInjectorService" &gt;
+ *         &lt;intent-filter&gt;
+ *             &lt;action android:name="android.location.SettingInjectorService" /&gt;
+ *         &lt;/intent-filter&gt;
+ *
+ *         &lt;meta-data
+ *             android:name="android.location.SettingInjectorService"
+ *             android:resource="@xml/my_injected_location_setting" /&gt;
+ *     &lt;/service&gt;
+ * </pre>
+ * The resource file specifies the static data for the setting:
+ * <pre>
+ *     &lt;injected-location-setting xmlns:android="http://schemas.android.com/apk/res/android"
+ *         android:title="@string/injected_setting_title"
+ *         android:icon="@drawable/ic_acme_corp"
+ *         android:settingsActivity="com.example.android.injector.MySettingActivity"
+ *     /&gt;
+ * </pre>
+ * Here:
+ * <ul>
+ * <li>title: The {@link android.preference.Preference#getTitle()} value. The title should make
+ * it clear which apps are affected by the setting, typically by including the name of the
+ * developer. For example, "Acme Corp. ads preferences." </li>
+ *
+ * <li>icon: The {@link android.preference.Preference#getIcon()} value. Typically this will be a
+ * generic icon for the developer rather than the icon for an individual app.</li>
+ *
+ * <li>settingsActivity: the activity which is launched to allow the user to modify the setting
+ * value.  The activity must be in the same package as the subclass of
+ * {@link SettingInjectorService}. The activity should use your own branding to help emphasize
+ * to the user that it is not part of the system settings.</li>
+ * </ul>
+ *
+ * To ensure a good user experience, your {@link android.app.Application#onCreate()},
+ * {@link #onGetSummary()}, and {@link #onGetEnabled()} methods must all be fast. If any are slow,
+ * it can delay the display of settings values for other apps as well. Note further that all are
+ * called on your app's UI thread.
+ * <p/>
+ * For compactness, only one copy of a given setting should be injected. If each account has a
+ * distinct value for the setting, then the {@link #onGetSummary()} value should represent a summary
+ * of the state across all of the accounts and {@code settingsActivity} should display the value for
+ * each account.
+ */
+public abstract class SettingInjectorService extends Service {
+
+    private static final String TAG = "SettingInjectorService";
+
+    /**
+     * Intent action that must be declared in the manifest for the subclass. Used to start the
+     * service to read the dynamic status for the setting.
+     */
+    public static final String ACTION_SERVICE_INTENT = "android.location.SettingInjectorService";
+
+    /**
+     * Name of the meta-data tag used to specify the resource file that includes the settings
+     * attributes.
+     */
+    public static final String META_DATA_NAME = "android.location.SettingInjectorService";
+
+    /**
+     * Name of the XML tag that includes the attributes for the setting.
+     */
+    public static final String ATTRIBUTES_NAME = "injected-location-setting";
+
+    /**
+     * Intent action a client should broadcast when the value of one of its injected settings has
+     * changed, so that the setting can be updated in the UI.
+     */
+    public static final String ACTION_INJECTED_SETTING_CHANGED =
+            "android.location.InjectedSettingChanged";
+
+    /**
+     * Name of the bundle key for the string specifying the summary for the setting (e.g., "ON" or
+     * "OFF").
+     *
+     * @hide
+     */
+    public static final String SUMMARY_KEY = "summary";
+
+    /**
+     * Name of the bundle key for the string specifying whether the setting is currently enabled.
+     *
+     * @hide
+     */
+    public static final String ENABLED_KEY = "enabled";
+
+    /**
+     * Name of the intent key used to specify the messenger
+     *
+     * @hide
+     */
+    public static final String MESSENGER_KEY = "messenger";
+
+    private final String mName;
+
+    /**
+     * Constructor.
+     *
+     * @param name used to identify your subclass in log messages
+     */
+    public SettingInjectorService(String name) {
+        mName = name;
+    }
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return null;
+    }
+
+    @Override
+    public final void onStart(Intent intent, int startId) {
+        super.onStart(intent, startId);
+    }
+
+    @Override
+    public final int onStartCommand(Intent intent, int flags, int startId) {
+        onHandleIntent(intent);
+        stopSelf(startId);
+        return START_NOT_STICKY;
+    }
+
+    private void onHandleIntent(Intent intent) {
+        String summary = null;
+        boolean enabled = false;
+        try {
+            summary = onGetSummary();
+            enabled = onGetEnabled();
+        } finally {
+            // If exception happens, send status anyway, so that settings injector can immediately
+            // start loading the status of the next setting. But leave the exception uncaught to
+            // crash the injector service itself.
+            sendStatus(intent, summary, enabled);
+        }
+    }
+
+    /**
+     * Send the enabled values back to the caller via the messenger encoded in the
+     * intent.
+     */
+    private void sendStatus(Intent intent, String summary, boolean enabled) {
+        Messenger messenger = intent.getParcelableExtra(MESSENGER_KEY);
+        // Bail out to avoid crashing GmsCore with incoming malicious Intent.
+        if (messenger == null) {
+            return;
+        }
+
+        Message message = Message.obtain();
+        Bundle bundle = new Bundle();
+        bundle.putString(SUMMARY_KEY, summary);
+        bundle.putBoolean(ENABLED_KEY, enabled);
+        message.setData(bundle);
+
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            Log.d(TAG, mName + ": received " + intent + ", summary=" + summary
+                    + ", enabled=" + enabled + ", sending message: " + message);
+        }
+
+        try {
+            messenger.send(message);
+        } catch (RemoteException e) {
+            Log.e(TAG, mName + ": sending dynamic status failed", e);
+        }
+    }
+
+    /**
+     * Returns the {@link android.preference.Preference#getSummary()} value (allowed to be null or
+     * empty). Should not perform unpredictably-long operations such as network access--see the
+     * running-time comments in the class-level javadoc.
+     * <p/>
+     * This method is called on KitKat, and Q+ devices.
+     *
+     * @return the {@link android.preference.Preference#getSummary()} value
+     */
+    protected abstract String onGetSummary();
+
+    /**
+     * Returns the {@link android.preference.Preference#isEnabled()} value. Should not perform
+     * unpredictably-long operations such as network access--see the running-time comments in the
+     * class-level javadoc.
+     * <p/>
+     * Note that to prevent churn in the settings list, there is no support for dynamically choosing
+     * to hide a setting. Instead you should have this method return false, which will disable the
+     * setting and its link to your setting activity. One reason why you might choose to do this is
+     * if {@link android.provider.Settings.Secure#LOCATION_MODE} is {@link
+     * android.provider.Settings.Secure#LOCATION_MODE_OFF}.
+     * <p/>
+     * It is possible that the user may click on the setting before this method returns, so your
+     * settings activity must handle the case where it is invoked even though the setting is
+     * disabled. The simplest approach may be to simply call {@link android.app.Activity#finish()}
+     * when disabled.
+     *
+     * @return the {@link android.preference.Preference#isEnabled()} value
+     */
+    protected abstract boolean onGetEnabled();
+
+    /**
+     * Sends a broadcast to refresh the injected settings on location settings page.
+     */
+    public static final void refreshSettings(@NonNull Context context) {
+        Intent intent = new Intent(ACTION_INJECTED_SETTING_CHANGED);
+        context.sendBroadcast(intent);
+    }
+}
