/*
 * 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.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;


/**
 * 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
 * (for example at {@link android.app.Activity#onPause}), 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;

    /**
     * By default, mFastestInterval = FASTEST_INTERVAL_MULTIPLE * mInterval
     */
    private static final double FASTEST_INTERVAL_FACTOR = 6.0;  // 6x

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private int mQuality = POWER_LOW;
    @UnsupportedAppUsage
    private long mInterval = 60 * 60 * 1000;   // 60 minutes
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private long mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR);  // 10 minutes
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private boolean mExplicitFastestInterval = false;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private long mExpireAt = Long.MAX_VALUE;  // no expiry
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private int mNumUpdates = Integer.MAX_VALUE;  // no expiry
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private float mSmallestDisplacement = 0.0f;    // meters
    @UnsupportedAppUsage
    private WorkSource mWorkSource = null;
    @UnsupportedAppUsage
    private boolean mHideFromAppOps = false; // True if this request shouldn't be counted by AppOps
    private boolean mLocationSettingsIgnored = false;

    @UnsupportedAppUsage
    private String mProvider = LocationManager.FUSED_PROVIDER;
            // for deprecated APIs that explicitly request a provider

    /** If true, GNSS chipset will make strong tradeoffs to substantially restrict power use */
    private boolean mLowPowerMode = false;

    /**
     * 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) {
        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) {
        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() {
    }

    /** @hide */
    public LocationRequest(LocationRequest src) {
        mQuality = src.mQuality;
        mInterval = src.mInterval;
        mFastestInterval = src.mFastestInterval;
        mExplicitFastestInterval = src.mExplicitFastestInterval;
        mExpireAt = src.mExpireAt;
        mNumUpdates = src.mNumUpdates;
        mSmallestDisplacement = src.mSmallestDisplacement;
        mProvider = src.mProvider;
        mWorkSource = src.mWorkSource;
        mHideFromAppOps = src.mHideFromAppOps;
        mLowPowerMode = src.mLowPowerMode;
        mLocationSettingsIgnored = src.mLocationSettingsIgnored;
    }

    /**
     * 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) {
        checkInterval(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
     * @hide
     */
    @SystemApi
    public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
        mLowPowerMode = enabled;
        return this;
    }

    /**
     * Returns true if low power mode is enabled.
     *
     * @hide
     */
    @SystemApi
    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 {@link #setFastestInterval} is set slower than {@link #setInterval},
     * then your effective fastest interval is {@link #setInterval}.
     *
     * @param millis fastest interval for updates in milliseconds, exact
     * @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) {
        checkInterval(millis);
        mExplicitFastestInterval = true;
        mFastestInterval = millis;
        return this;
    }

    /**
     * Get the fastest interval of this request, in milliseconds.
     *
     * <p>The system will never provide location updates faster
     * than the minimum of {@link #getFastestInterval} and
     * {@link #getInterval}.
     *
     * @return fastest interval in milliseconds, exact
     */
    public long getFastestInterval() {
        return mFastestInterval;
    }

    /**
     * Set the duration of this request, in milliseconds.
     *
     * <p>The duration begins immediately (and not when the request
     * is passed to the location manager), so call this method again
     * if the request is re-used at a later time.
     *
     * <p>The location manager will automatically stop updates after
     * the request expires.
     *
     * <p>The duration includes suspend time. Values less than 0
     * are allowed, but indicate that the request has already expired.
     *
     * @param millis duration of request in milliseconds
     * @return the same object, so that setters can be chained
     */
    public @NonNull LocationRequest setExpireIn(long millis) {
        long elapsedRealtime = SystemClock.elapsedRealtime();

        // Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
        if (millis > Long.MAX_VALUE - elapsedRealtime) {
            mExpireAt = Long.MAX_VALUE;
        } else {
            mExpireAt = millis + elapsedRealtime;
        }

        if (mExpireAt < 0) mExpireAt = 0;
        return this;
    }

    /**
     * Set the request expiration time, in millisecond since boot.
     *
     * <p>This expiration time uses the same time base as {@link SystemClock#elapsedRealtime}.
     *
     * <p>The location manager will automatically stop updates after
     * the request expires.
     *
     * <p>The duration includes suspend time. Values before {@link SystemClock#elapsedRealtime}
     * are allowed,  but indicate that the request has already expired.
     *
     * @param millis expiration time of request, in milliseconds since boot including suspend
     * @return the same object, so that setters can be chained
     */
    public @NonNull LocationRequest setExpireAt(long millis) {
        mExpireAt = millis;
        if (mExpireAt < 0) mExpireAt = 0;
        return this;
    }

    /**
     * Get the request expiration time, in milliseconds since boot.
     *
     * <p>This value can be compared to {@link SystemClock#elapsedRealtime} to determine
     * the time until expiration.
     *
     * @return expiration time of request, in milliseconds since boot including suspend
     */
    public long getExpireAt() {
        return 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) {
        checkProvider(provider);
        mProvider = provider;
        return this;
    }

    /** @hide */
    @SystemApi
    public @NonNull String getProvider() {
        return mProvider;
    }

    /** @hide */
    @SystemApi
    public @NonNull LocationRequest setSmallestDisplacement(float meters) {
        checkDisplacement(meters);
        mSmallestDisplacement = meters;
        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 checkInterval(long millis) {
        if (millis < 0) {
            throw new IllegalArgumentException("invalid interval: " + millis);
        }
    }

    @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);
        }
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private static void checkDisplacement(float meters) {
        if (meters < 0.0f) {
            throw new IllegalArgumentException("invalid displacement: " + meters);
        }
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private static void checkProvider(String name) {
        if (name == null) {
            throw new IllegalArgumentException("invalid provider: null");
        }
    }

    public static final @android.annotation.NonNull Parcelable.Creator<LocationRequest> CREATOR =
            new Parcelable.Creator<LocationRequest>() {
                @Override
                public LocationRequest createFromParcel(Parcel in) {
                    LocationRequest request = new LocationRequest();
                    request.setQuality(in.readInt());
                    request.setFastestInterval(in.readLong());
                    request.setInterval(in.readLong());
                    request.setExpireAt(in.readLong());
                    request.setNumUpdates(in.readInt());
                    request.setSmallestDisplacement(in.readFloat());
                    request.setHideFromAppOps(in.readInt() != 0);
                    request.setLowPowerMode(in.readInt() != 0);
                    request.setLocationSettingsIgnored(in.readInt() != 0);
                    String provider = in.readString();
                    if (provider != null) request.setProvider(provider);
                    WorkSource workSource = in.readParcelable(null);
                    if (workSource != null) request.setWorkSource(workSource);
                    return request;
                }

                @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.writeInt(mQuality);
        parcel.writeLong(mFastestInterval);
        parcel.writeLong(mInterval);
        parcel.writeLong(mExpireAt);
        parcel.writeInt(mNumUpdates);
        parcel.writeFloat(mSmallestDisplacement);
        parcel.writeInt(mHideFromAppOps ? 1 : 0);
        parcel.writeInt(mLowPowerMode ? 1 : 0);
        parcel.writeInt(mLocationSettingsIgnored ? 1 : 0);
        parcel.writeString(mProvider);
        parcel.writeParcelable(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 "???";
        }
    }

    @Override
    public String toString() {
        StringBuilder s = new StringBuilder();
        s.append("Request[").append(qualityToString(mQuality));
        if (mProvider != null) s.append(' ').append(mProvider);
        if (mQuality != POWER_NONE) {
            s.append(" requested=");
            TimeUtils.formatDuration(mInterval, s);
        }
        s.append(" fastest=");
        TimeUtils.formatDuration(mFastestInterval, s);
        if (mExpireAt != Long.MAX_VALUE) {
            long expireIn = mExpireAt - SystemClock.elapsedRealtime();
            s.append(" expireIn=");
            TimeUtils.formatDuration(expireIn, 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();
    }
}
