The recently-built Error Prone checker has found many instances where we're always paying the cost of StringBuilder concatenation, even in the typical cases where preconditions are successfully met. Benchmarks have shown that even when replacing these with varargs formatter strings, the default case is 20x faster. Bug: 170978902 Test: none Exempt-From-Owner-Approval: trivial refactoring Change-Id: If8c00bc73467bfb91ec16c162969c9d26ca53646
160 lines
5.0 KiB
Java
160 lines
5.0 KiB
Java
/*
|
|
* 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.annotation.NonNull;
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.os.SystemClock;
|
|
import android.util.TimeUtils;
|
|
|
|
import com.android.internal.util.Preconditions;
|
|
|
|
import java.util.Objects;
|
|
|
|
/**
|
|
* 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 {
|
|
|
|
private final double mLatitude;
|
|
private final double mLongitude;
|
|
private final float mRadius;
|
|
private long mExpirationRealtimeMs;
|
|
|
|
/**
|
|
* 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,
|
|
long expirationRealtimeMs) {
|
|
return new Geofence(latitude, longitude, radius, expirationRealtimeMs);
|
|
}
|
|
|
|
Geofence(double latitude, double longitude, float radius, long expirationRealtimeMs) {
|
|
Preconditions.checkArgumentInRange(latitude, -90.0, 90.0, "latitude");
|
|
Preconditions.checkArgumentInRange(longitude, -180.0, 180.0, "latitude");
|
|
Preconditions.checkArgument(radius > 0, "invalid radius: %f", radius);
|
|
|
|
mLatitude = latitude;
|
|
mLongitude = longitude;
|
|
mRadius = radius;
|
|
mExpirationRealtimeMs = expirationRealtimeMs;
|
|
}
|
|
|
|
public double getLatitude() {
|
|
return mLatitude;
|
|
}
|
|
|
|
public double getLongitude() {
|
|
return mLongitude;
|
|
}
|
|
|
|
public float getRadius() {
|
|
return mRadius;
|
|
}
|
|
|
|
public boolean isExpired() {
|
|
return isExpired(SystemClock.elapsedRealtime());
|
|
}
|
|
|
|
/**
|
|
* Returns true if this geofence is expired with reference to the given realtime.
|
|
*/
|
|
public boolean isExpired(long referenceRealtimeMs) {
|
|
return referenceRealtimeMs >= mExpirationRealtimeMs;
|
|
}
|
|
|
|
@UnsupportedAppUsage
|
|
public static final @NonNull Parcelable.Creator<Geofence> CREATOR =
|
|
new Parcelable.Creator<Geofence>() {
|
|
@Override
|
|
public Geofence createFromParcel(Parcel in) {
|
|
return new Geofence(
|
|
in.readDouble(),
|
|
in.readDouble(),
|
|
in.readFloat(),
|
|
in.readLong());
|
|
}
|
|
|
|
@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.writeDouble(mLatitude);
|
|
parcel.writeDouble(mLongitude);
|
|
parcel.writeFloat(mRadius);
|
|
parcel.writeLong(mExpirationRealtimeMs);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) {
|
|
return true;
|
|
}
|
|
if (!(o instanceof Geofence)) {
|
|
return false;
|
|
}
|
|
Geofence geofence = (Geofence) o;
|
|
return Double.compare(geofence.mLatitude, mLatitude) == 0
|
|
&& Double.compare(geofence.mLongitude, mLongitude) == 0
|
|
&& Float.compare(geofence.mRadius, mRadius) == 0
|
|
&& mExpirationRealtimeMs == geofence.mExpirationRealtimeMs;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(mLatitude, mLongitude, mRadius);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
StringBuilder builder = new StringBuilder();
|
|
builder.append("Geofence[(").append(mLatitude).append(", ").append(mLongitude).append(")");
|
|
builder.append(" ").append(mRadius).append("m");
|
|
if (mExpirationRealtimeMs < Long.MAX_VALUE) {
|
|
if (isExpired()) {
|
|
builder.append(" expired");
|
|
} else {
|
|
builder.append(" expires=");
|
|
TimeUtils.formatDuration(mExpirationRealtimeMs, builder);
|
|
}
|
|
}
|
|
builder.append("]");
|
|
return builder.toString();
|
|
}
|
|
}
|