Delete location.timezone.provider API classes
Delete location.timezone.provider API classes and associated internal classes that are no longer used. Bug: 175633818 Test: build Change-Id: I66319e63e3150e3b71f31f8d9404e4114f802662
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.internal.location.timezone;
|
||||
|
||||
import com.android.internal.location.timezone.ILocationTimeZoneProviderManager;
|
||||
import com.android.internal.location.timezone.LocationTimeZoneProviderRequest;
|
||||
|
||||
/**
|
||||
* Binder interface for location time zone provider implementations. Do not implement this
|
||||
* directly, extend {@link com.android.location.timezone.provider.LocationTimeZoneProviderBase}
|
||||
* instead.
|
||||
* @hide
|
||||
*/
|
||||
interface ILocationTimeZoneProvider {
|
||||
|
||||
oneway void setLocationTimeZoneProviderManager(in ILocationTimeZoneProviderManager manager);
|
||||
|
||||
oneway void setRequest(in LocationTimeZoneProviderRequest request);
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.internal.location.timezone;
|
||||
|
||||
import com.android.internal.location.timezone.LocationTimeZoneEvent;
|
||||
|
||||
/**
|
||||
* Binder interface for the manager of location time zone provider implementations.
|
||||
* @hide
|
||||
*/
|
||||
interface ILocationTimeZoneProviderManager {
|
||||
void onLocationTimeZoneEvent(in LocationTimeZoneEvent locationTimeZoneEvent);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.internal.location.timezone;
|
||||
|
||||
parcelable LocationTimeZoneEvent;
|
||||
@@ -1,244 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.internal.location.timezone;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An event containing location time zone information.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class LocationTimeZoneEvent implements Parcelable {
|
||||
|
||||
@IntDef({ EVENT_TYPE_UNKNOWN, EVENT_TYPE_PERMANENT_FAILURE, EVENT_TYPE_SUCCESS,
|
||||
EVENT_TYPE_UNCERTAIN })
|
||||
public @interface EventType {}
|
||||
|
||||
/** Uninitialized value for {@link #mEventType} - must not be used for real events. */
|
||||
private static final int EVENT_TYPE_UNKNOWN = 0;
|
||||
|
||||
/**
|
||||
* Indicates there was a permanent failure. This is not generally expected, and probably means a
|
||||
* required backend service has been turned down, or the client is unreasonably old.
|
||||
*/
|
||||
public static final int EVENT_TYPE_PERMANENT_FAILURE = 1;
|
||||
|
||||
/**
|
||||
* Indicates a successful geolocation time zone detection event. {@link #getTimeZoneIds()} will
|
||||
* be non-null but can legitimately be empty, e.g. for disputed areas, oceans.
|
||||
*/
|
||||
public static final int EVENT_TYPE_SUCCESS = 2;
|
||||
|
||||
/**
|
||||
* Indicates the time zone is not known because of an expected runtime state or error, e.g. when
|
||||
* the provider is unable to detect location, or there was a problem when resolving the location
|
||||
* to a time zone.
|
||||
*/
|
||||
public static final int EVENT_TYPE_UNCERTAIN = 3;
|
||||
|
||||
private static final int EVENT_TYPE_MAX = EVENT_TYPE_UNCERTAIN;
|
||||
|
||||
@EventType
|
||||
private final int mEventType;
|
||||
|
||||
@NonNull
|
||||
private final List<String> mTimeZoneIds;
|
||||
|
||||
private final long mElapsedRealtimeMillis;
|
||||
|
||||
private LocationTimeZoneEvent(@EventType int eventType, @NonNull List<String> timeZoneIds,
|
||||
long elapsedRealtimeMillis) {
|
||||
mEventType = checkValidEventType(eventType);
|
||||
mTimeZoneIds = immutableList(timeZoneIds);
|
||||
|
||||
boolean emptyTimeZoneIdListExpected = eventType != EVENT_TYPE_SUCCESS;
|
||||
Preconditions.checkState(!emptyTimeZoneIdListExpected || timeZoneIds.isEmpty());
|
||||
|
||||
mElapsedRealtimeMillis = elapsedRealtimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time of this fix, in elapsed real-time since system boot.
|
||||
*
|
||||
* <p>This value can be reliably compared to {@link
|
||||
* android.os.SystemClock#elapsedRealtime()}, to calculate the age of a fix and to compare
|
||||
* {@link LocationTimeZoneEvent} instances.
|
||||
*
|
||||
* @return elapsed real-time of fix, in milliseconds
|
||||
*/
|
||||
public long getElapsedRealtimeMillis() {
|
||||
return mElapsedRealtimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the event type.
|
||||
*/
|
||||
@Nullable
|
||||
public @EventType int getEventType() {
|
||||
return mEventType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time zone IDs of this event. Contains zero or more IDs for a successful lookup.
|
||||
* The value is undefined for an unsuccessful lookup. See also {@link #getEventType()}.
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getTimeZoneIds() {
|
||||
return mTimeZoneIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocationTimeZoneEvent{"
|
||||
+ "mEventType=" + mEventType
|
||||
+ ", mTimeZoneIds=" + mTimeZoneIds
|
||||
+ ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
|
||||
+ "(" + Duration.ofMillis(mElapsedRealtimeMillis) + ")"
|
||||
+ '}';
|
||||
}
|
||||
|
||||
public static final @NonNull Parcelable.Creator<LocationTimeZoneEvent> CREATOR =
|
||||
new Parcelable.Creator<LocationTimeZoneEvent>() {
|
||||
@Override
|
||||
public LocationTimeZoneEvent createFromParcel(Parcel in) {
|
||||
int eventType = in.readInt();
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayList<String> timeZoneIds =
|
||||
(ArrayList<String>) in.readArrayList(null /* classLoader */);
|
||||
long elapsedRealtimeMillis = in.readLong();
|
||||
return new LocationTimeZoneEvent(eventType, timeZoneIds, elapsedRealtimeMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationTimeZoneEvent[] newArray(int size) {
|
||||
return new LocationTimeZoneEvent[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeInt(mEventType);
|
||||
parcel.writeList(mTimeZoneIds);
|
||||
parcel.writeLong(mElapsedRealtimeMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LocationTimeZoneEvent that = (LocationTimeZoneEvent) o;
|
||||
return mEventType == that.mEventType
|
||||
&& mElapsedRealtimeMillis == that.mElapsedRealtimeMillis
|
||||
&& mTimeZoneIds.equals(that.mTimeZoneIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mEventType, mTimeZoneIds, mElapsedRealtimeMillis);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static final class Builder {
|
||||
|
||||
private @EventType int mEventType = EVENT_TYPE_UNKNOWN;
|
||||
private @NonNull List<String> mTimeZoneIds = Collections.emptyList();
|
||||
private long mElapsedRealtimeMillis;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the contents of this from the supplied instance.
|
||||
*/
|
||||
public Builder(@NonNull LocationTimeZoneEvent ltz) {
|
||||
mEventType = ltz.mEventType;
|
||||
mTimeZoneIds = ltz.mTimeZoneIds;
|
||||
mElapsedRealtimeMillis = ltz.mElapsedRealtimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time zone ID of this event.
|
||||
*/
|
||||
public Builder setEventType(@EventType int eventType) {
|
||||
checkValidEventType(eventType);
|
||||
mEventType = eventType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time zone IDs of this event.
|
||||
*/
|
||||
public Builder setTimeZoneIds(@NonNull List<String> timeZoneIds) {
|
||||
mTimeZoneIds = Objects.requireNonNull(timeZoneIds);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time of this event, in elapsed real-time since system boot.
|
||||
*/
|
||||
public Builder setElapsedRealtimeMillis(long time) {
|
||||
mElapsedRealtimeMillis = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link LocationTimeZoneEvent} instance.
|
||||
*/
|
||||
public LocationTimeZoneEvent build() {
|
||||
return new LocationTimeZoneEvent(mEventType, mTimeZoneIds, mElapsedRealtimeMillis);
|
||||
}
|
||||
}
|
||||
|
||||
private static int checkValidEventType(int eventType) {
|
||||
if (eventType <= EVENT_TYPE_UNKNOWN || eventType > EVENT_TYPE_MAX) {
|
||||
throw new IllegalStateException("eventType " + eventType + " unknown");
|
||||
}
|
||||
return eventType;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static List<String> immutableList(@NonNull List<String> list) {
|
||||
Objects.requireNonNull(list);
|
||||
if (list.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return Collections.unmodifiableList(new ArrayList<>(list));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.internal.location.timezone;
|
||||
|
||||
parcelable LocationTimeZoneProviderRequest;
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.internal.location.timezone;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A request passed to a location time zone provider to configure it.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class LocationTimeZoneProviderRequest implements Parcelable {
|
||||
|
||||
public static final LocationTimeZoneProviderRequest EMPTY_REQUEST =
|
||||
new LocationTimeZoneProviderRequest(
|
||||
false /* reportLocationTimeZone */,
|
||||
0 /* initializationTimeoutMillis */);
|
||||
|
||||
public static final Creator<LocationTimeZoneProviderRequest> CREATOR =
|
||||
new Creator<LocationTimeZoneProviderRequest>() {
|
||||
@Override
|
||||
public LocationTimeZoneProviderRequest createFromParcel(Parcel in) {
|
||||
return LocationTimeZoneProviderRequest.createFromParcel(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocationTimeZoneProviderRequest[] newArray(int size) {
|
||||
return new LocationTimeZoneProviderRequest[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final boolean mReportLocationTimeZone;
|
||||
|
||||
private final long mInitializationTimeoutMillis;
|
||||
|
||||
private LocationTimeZoneProviderRequest(
|
||||
boolean reportLocationTimeZone, long initializationTimeoutMillis) {
|
||||
mReportLocationTimeZone = reportLocationTimeZone;
|
||||
mInitializationTimeoutMillis = initializationTimeoutMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the provider should report events related to the device's current
|
||||
* time zone, {@code false} otherwise.
|
||||
*/
|
||||
public boolean getReportLocationTimeZone() {
|
||||
return mReportLocationTimeZone;
|
||||
}
|
||||
|
||||
// TODO(b/152744911) - once there are a couple of implementations, decide whether this needs to
|
||||
// be passed to the LocationTimeZoneProvider and remove if it is not useful.
|
||||
/**
|
||||
* Returns the maximum time that the provider is allowed to initialize before it is expected to
|
||||
* send an event of any sort. Only valid when {@link #getReportLocationTimeZone()} is {@code
|
||||
* true}. Failure to send an event in this time (with some fuzz) may be interpreted as if the
|
||||
* provider is uncertain of the time zone, and/or it could lead to the provider being disabled.
|
||||
*/
|
||||
public long getInitializationTimeoutMillis() {
|
||||
return mInitializationTimeoutMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
parcel.writeBoolean(mReportLocationTimeZone);
|
||||
parcel.writeLong(mInitializationTimeoutMillis);
|
||||
}
|
||||
|
||||
static LocationTimeZoneProviderRequest createFromParcel(Parcel in) {
|
||||
boolean reportLocationTimeZone = in.readBoolean();
|
||||
long initializationTimeoutMillis = in.readLong();
|
||||
return new LocationTimeZoneProviderRequest(
|
||||
reportLocationTimeZone, initializationTimeoutMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LocationTimeZoneProviderRequest that = (LocationTimeZoneProviderRequest) o;
|
||||
return mReportLocationTimeZone == that.mReportLocationTimeZone
|
||||
&& mInitializationTimeoutMillis == that.mInitializationTimeoutMillis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mReportLocationTimeZone, mInitializationTimeoutMillis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocationTimeZoneProviderRequest{"
|
||||
+ "mReportLocationTimeZone=" + mReportLocationTimeZone
|
||||
+ ", mInitializationTimeoutMillis=" + mInitializationTimeoutMillis
|
||||
+ "}";
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static final class Builder {
|
||||
|
||||
private boolean mReportLocationTimeZone;
|
||||
private long mInitializationTimeoutMillis;
|
||||
|
||||
/**
|
||||
* Sets the property that enables / disables the provider. This is set to {@code false} by
|
||||
* default.
|
||||
*/
|
||||
public Builder setReportLocationTimeZone(boolean reportLocationTimeZone) {
|
||||
mReportLocationTimeZone = reportLocationTimeZone;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initialization timeout. See {@link
|
||||
* LocationTimeZoneProviderRequest#getInitializationTimeoutMillis()} for details.
|
||||
*/
|
||||
public Builder setInitializationTimeoutMillis(long timeoutMillis) {
|
||||
mInitializationTimeoutMillis = timeoutMillis;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Builds the {@link LocationTimeZoneProviderRequest} instance. */
|
||||
@NonNull
|
||||
public LocationTimeZoneProviderRequest build() {
|
||||
return new LocationTimeZoneProviderRequest(
|
||||
mReportLocationTimeZone, mInitializationTimeoutMillis);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,35 +67,3 @@ package com.android.location.provider {
|
||||
|
||||
}
|
||||
|
||||
package com.android.location.timezone.provider {
|
||||
|
||||
public final class LocationTimeZoneEventUnbundled {
|
||||
method public int getEventType();
|
||||
method @NonNull public java.util.List<java.lang.String> getTimeZoneIds();
|
||||
field public static final int EVENT_TYPE_PERMANENT_FAILURE = 1; // 0x1
|
||||
field public static final int EVENT_TYPE_SUCCESS = 2; // 0x2
|
||||
field public static final int EVENT_TYPE_UNCERTAIN = 3; // 0x3
|
||||
}
|
||||
|
||||
public static final class LocationTimeZoneEventUnbundled.Builder {
|
||||
ctor public LocationTimeZoneEventUnbundled.Builder();
|
||||
method @NonNull public com.android.location.timezone.provider.LocationTimeZoneEventUnbundled build();
|
||||
method @NonNull public com.android.location.timezone.provider.LocationTimeZoneEventUnbundled.Builder setEventType(int);
|
||||
method @NonNull public com.android.location.timezone.provider.LocationTimeZoneEventUnbundled.Builder setTimeZoneIds(@NonNull java.util.List<java.lang.String>);
|
||||
}
|
||||
|
||||
public abstract class LocationTimeZoneProviderBase {
|
||||
ctor public LocationTimeZoneProviderBase(android.content.Context, String);
|
||||
method public final android.os.IBinder getBinder();
|
||||
method protected final android.content.Context getContext();
|
||||
method protected abstract void onSetRequest(@NonNull com.android.location.timezone.provider.LocationTimeZoneProviderRequestUnbundled);
|
||||
method protected final void reportLocationTimeZoneEvent(@NonNull com.android.location.timezone.provider.LocationTimeZoneEventUnbundled);
|
||||
}
|
||||
|
||||
public final class LocationTimeZoneProviderRequestUnbundled {
|
||||
method @IntRange(from=0) public long getInitializationTimeoutMillis();
|
||||
method public boolean getReportLocationTimeZone();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.location.timezone.provider;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.android.internal.location.timezone.LocationTimeZoneEvent;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An event from a {@link LocationTimeZoneProviderBase} sent while determining a device's time zone
|
||||
* using its location.
|
||||
*/
|
||||
public final class LocationTimeZoneEventUnbundled {
|
||||
|
||||
@IntDef({ EVENT_TYPE_PERMANENT_FAILURE, EVENT_TYPE_SUCCESS, EVENT_TYPE_UNCERTAIN })
|
||||
@interface EventType {}
|
||||
|
||||
/**
|
||||
* Indicates there was a permanent failure. This is not generally expected, and probably means a
|
||||
* required backend service has been turned down, or the client is unreasonably old.
|
||||
*/
|
||||
public static final int EVENT_TYPE_PERMANENT_FAILURE =
|
||||
LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE;
|
||||
|
||||
/**
|
||||
* Indicates a successful geolocation time zone detection event. {@link #getTimeZoneIds()} will
|
||||
* be non-null but can legitimately be empty, e.g. for disputed areas, oceans.
|
||||
*/
|
||||
public static final int EVENT_TYPE_SUCCESS = LocationTimeZoneEvent.EVENT_TYPE_SUCCESS;
|
||||
|
||||
/**
|
||||
* Indicates the time zone is not known because of an expected runtime state or error, e.g. when
|
||||
* the provider is unable to detect location, or there was a problem when resolving the location
|
||||
* to a time zone.
|
||||
*/
|
||||
public static final int EVENT_TYPE_UNCERTAIN = LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN;
|
||||
|
||||
@NonNull
|
||||
private final LocationTimeZoneEvent mDelegate;
|
||||
|
||||
private LocationTimeZoneEventUnbundled(@NonNull LocationTimeZoneEvent delegate) {
|
||||
mDelegate = Objects.requireNonNull(delegate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the event type.
|
||||
*/
|
||||
public @EventType int getEventType() {
|
||||
return mDelegate.getEventType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time zone IDs of this event. Contains zero or more IDs for a successful lookup.
|
||||
* The value is undefined for an unsuccessful lookup. See also {@link #getEventType()}.
|
||||
*/
|
||||
@NonNull
|
||||
public List<String> getTimeZoneIds() {
|
||||
return mDelegate.getTimeZoneIds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information from this as a {@link LocationTimeZoneEvent}.
|
||||
* @hide
|
||||
*/
|
||||
@NonNull
|
||||
public LocationTimeZoneEvent getInternalLocationTimeZoneEvent() {
|
||||
return mDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LocationTimeZoneEventUnbundled{"
|
||||
+ "mDelegate=" + mDelegate
|
||||
+ '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LocationTimeZoneEventUnbundled that = (LocationTimeZoneEventUnbundled) o;
|
||||
return mDelegate.equals(that.mDelegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return mDelegate.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder of {@link LocationTimeZoneEventUnbundled} instances.
|
||||
*/
|
||||
public static final class Builder {
|
||||
|
||||
private @EventType int mEventType;
|
||||
private @NonNull List<String> mTimeZoneIds = Collections.emptyList();
|
||||
|
||||
/**
|
||||
* Set the time zone ID of this event.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setEventType(@EventType int eventType) {
|
||||
checkValidEventType(eventType);
|
||||
mEventType = eventType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time zone IDs of this event.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setTimeZoneIds(@NonNull List<String> timeZoneIds) {
|
||||
mTimeZoneIds = Objects.requireNonNull(timeZoneIds);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a {@link LocationTimeZoneEventUnbundled} instance.
|
||||
*/
|
||||
@NonNull
|
||||
public LocationTimeZoneEventUnbundled build() {
|
||||
final int internalEventType = this.mEventType;
|
||||
LocationTimeZoneEvent event = new LocationTimeZoneEvent.Builder()
|
||||
.setEventType(internalEventType)
|
||||
.setTimeZoneIds(mTimeZoneIds)
|
||||
.setElapsedRealtimeMillis(SystemClock.elapsedRealtime())
|
||||
.build();
|
||||
return new LocationTimeZoneEventUnbundled(event);
|
||||
}
|
||||
}
|
||||
|
||||
private static int checkValidEventType(int eventType) {
|
||||
if (eventType != EVENT_TYPE_SUCCESS
|
||||
&& eventType != EVENT_TYPE_UNCERTAIN
|
||||
&& eventType != EVENT_TYPE_PERMANENT_FAILURE) {
|
||||
throw new IllegalStateException("eventType=" + eventType);
|
||||
}
|
||||
return eventType;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.location.timezone.provider;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.location.timezone.ILocationTimeZoneProvider;
|
||||
import com.android.internal.location.timezone.ILocationTimeZoneProviderManager;
|
||||
import com.android.internal.location.timezone.LocationTimeZoneProviderRequest;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A base class for location time zone providers implemented as unbundled services.
|
||||
*
|
||||
* <p>Provider implementations are enabled / disabled via a call to {@link
|
||||
* #onSetRequest(LocationTimeZoneProviderRequestUnbundled)}.
|
||||
*
|
||||
* <p>Once enabled, providers are expected to detect the time zone if possible, and report the
|
||||
* result via {@link #reportLocationTimeZoneEvent(LocationTimeZoneEventUnbundled)} with a type of
|
||||
* either {@link LocationTimeZoneEventUnbundled#EVENT_TYPE_UNCERTAIN} or {@link
|
||||
* LocationTimeZoneEventUnbundled#EVENT_TYPE_SUCCESS}. Providers may also report that they have
|
||||
* permanently failed by sending an event of type {@link
|
||||
* LocationTimeZoneEventUnbundled#EVENT_TYPE_PERMANENT_FAILURE}. See the javadocs for each event
|
||||
* type for details.
|
||||
*
|
||||
* <p>Providers are expected to issue their first event within {@link
|
||||
* LocationTimeZoneProviderRequest#getInitializationTimeoutMillis()}.
|
||||
*
|
||||
* <p>Once disabled or have failed, providers are required to stop producing events.
|
||||
*
|
||||
* <p>Threading:
|
||||
*
|
||||
* <p>Calls to {@link #reportLocationTimeZoneEvent(LocationTimeZoneEventUnbundled)} can be made on
|
||||
* on any thread, but may be processed asynchronously by the system server. Similarly, calls to
|
||||
* {@link #onSetRequest(LocationTimeZoneProviderRequestUnbundled)} may occur on any thread.
|
||||
*
|
||||
* <p>IMPORTANT: This class is effectively a public API for unbundled applications, and must remain
|
||||
* API stable.
|
||||
*/
|
||||
public abstract class LocationTimeZoneProviderBase {
|
||||
|
||||
private final Context mContext;
|
||||
private final String mTag;
|
||||
private final IBinder mBinder;
|
||||
|
||||
// write locked on mBinder, read lock is optional depending on atomicity requirements
|
||||
@Nullable private volatile ILocationTimeZoneProviderManager mManager;
|
||||
|
||||
public LocationTimeZoneProviderBase(Context context, String tag) {
|
||||
mContext = context;
|
||||
mTag = tag;
|
||||
mBinder = new Service();
|
||||
mManager = null;
|
||||
}
|
||||
|
||||
protected final Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
public final IBinder getBinder() {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports a new location time zone event from this provider.
|
||||
*/
|
||||
protected final void reportLocationTimeZoneEvent(
|
||||
@NonNull LocationTimeZoneEventUnbundled event) {
|
||||
ILocationTimeZoneProviderManager manager = mManager;
|
||||
if (manager != null) {
|
||||
try {
|
||||
manager.onLocationTimeZoneEvent(event.getInternalLocationTimeZoneEvent());
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
Log.w(mTag, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link LocationTimeZoneProviderRequestUnbundled} requirements for this provider. Each
|
||||
* call to this method overrides all previous requests. This method might trigger the provider
|
||||
* to start returning location time zones, or to stop returning location time zones, depending
|
||||
* on the parameters in the request.
|
||||
*/
|
||||
protected abstract void onSetRequest(@NonNull LocationTimeZoneProviderRequestUnbundled request);
|
||||
|
||||
private final class Service extends ILocationTimeZoneProvider.Stub {
|
||||
|
||||
@Override
|
||||
public void setLocationTimeZoneProviderManager(ILocationTimeZoneProviderManager manager) {
|
||||
mManager = Objects.requireNonNull(manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequest(LocationTimeZoneProviderRequest request) {
|
||||
onSetRequest(new LocationTimeZoneProviderRequestUnbundled(request));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* 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 com.android.location.timezone.provider;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import com.android.internal.location.timezone.LocationTimeZoneProviderRequest;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This class is an interface to LocationTimeZoneProviderRequest for provider implementations.
|
||||
*
|
||||
* <p>IMPORTANT: This class is effectively a public API for unbundled code, and must remain API
|
||||
* stable.
|
||||
*/
|
||||
public final class LocationTimeZoneProviderRequestUnbundled {
|
||||
|
||||
private final LocationTimeZoneProviderRequest mRequest;
|
||||
|
||||
/** @hide */
|
||||
public LocationTimeZoneProviderRequestUnbundled(
|
||||
@NonNull LocationTimeZoneProviderRequest request) {
|
||||
mRequest = Objects.requireNonNull(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the provider should report events related to the device's current
|
||||
* time zone, {@code false} otherwise.
|
||||
*/
|
||||
public boolean getReportLocationTimeZone() {
|
||||
return mRequest.getReportLocationTimeZone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum time that the provider is allowed to initialize before it is expected to
|
||||
* send an event of any sort. Only valid when {@link #getReportLocationTimeZone()} is {@code
|
||||
* true}. Failure to send an event in this time (with some fuzz) may be interpreted as if the
|
||||
* provider is uncertain of the time zone, and/or it could lead to the provider being disabled.
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public long getInitializationTimeoutMillis() {
|
||||
return mRequest.getInitializationTimeoutMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
LocationTimeZoneProviderRequestUnbundled that =
|
||||
(LocationTimeZoneProviderRequestUnbundled) o;
|
||||
return mRequest.equals(that.mRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mRequest.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 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 com.android.internal.location.timezone;
|
||||
|
||||
import static com.android.internal.location.timezone.ParcelableTestSupport.assertRoundTripParcelable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LocationTimeZoneEventTest {
|
||||
|
||||
private static final long ARBITRARY_ELAPSED_REALTIME_MILLIS = 9999;
|
||||
|
||||
private static final List<String> ARBITRARY_TIME_ZONE_IDS = singletonList("Europe/London");
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testSetInvalidEventType() {
|
||||
new LocationTimeZoneEvent.Builder().setEventType(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testBuildUnsetEventType() {
|
||||
new LocationTimeZoneEvent.Builder()
|
||||
.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS)
|
||||
.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void testInvalidTimeZoneIds() {
|
||||
new LocationTimeZoneEvent.Builder()
|
||||
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
|
||||
.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS)
|
||||
.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEquals() {
|
||||
LocationTimeZoneEvent.Builder builder1 = new LocationTimeZoneEvent.Builder()
|
||||
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
|
||||
.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
assertEquals(one, one);
|
||||
}
|
||||
|
||||
LocationTimeZoneEvent.Builder builder2 = new LocationTimeZoneEvent.Builder()
|
||||
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_UNCERTAIN)
|
||||
.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
LocationTimeZoneEvent two = builder2.build();
|
||||
assertEquals(one, two);
|
||||
assertEquals(two, one);
|
||||
}
|
||||
|
||||
builder1.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
LocationTimeZoneEvent two = builder2.build();
|
||||
assertNotEquals(one, two);
|
||||
assertNotEquals(two, one);
|
||||
}
|
||||
|
||||
builder2.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS + 1);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
LocationTimeZoneEvent two = builder2.build();
|
||||
assertEquals(one, two);
|
||||
assertEquals(two, one);
|
||||
}
|
||||
|
||||
builder2.setEventType(LocationTimeZoneEvent.EVENT_TYPE_SUCCESS);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
LocationTimeZoneEvent two = builder2.build();
|
||||
assertNotEquals(one, two);
|
||||
assertNotEquals(two, one);
|
||||
}
|
||||
|
||||
builder1.setEventType(LocationTimeZoneEvent.EVENT_TYPE_SUCCESS);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
LocationTimeZoneEvent two = builder2.build();
|
||||
assertEquals(one, two);
|
||||
assertEquals(two, one);
|
||||
}
|
||||
|
||||
builder2.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
LocationTimeZoneEvent two = builder2.build();
|
||||
assertNotEquals(one, two);
|
||||
assertNotEquals(two, one);
|
||||
}
|
||||
|
||||
builder1.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS);
|
||||
{
|
||||
LocationTimeZoneEvent one = builder1.build();
|
||||
LocationTimeZoneEvent two = builder2.build();
|
||||
assertEquals(one, two);
|
||||
assertEquals(two, one);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelable() {
|
||||
LocationTimeZoneEvent.Builder builder = new LocationTimeZoneEvent.Builder()
|
||||
.setEventType(LocationTimeZoneEvent.EVENT_TYPE_PERMANENT_FAILURE)
|
||||
.setElapsedRealtimeMillis(ARBITRARY_ELAPSED_REALTIME_MILLIS);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
|
||||
builder.setEventType(LocationTimeZoneEvent.EVENT_TYPE_SUCCESS)
|
||||
.setTimeZoneIds(ARBITRARY_TIME_ZONE_IDS);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 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 com.android.internal.location.timezone;
|
||||
|
||||
import static com.android.internal.location.timezone.ParcelableTestSupport.assertRoundTripParcelable;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class LocationTimeZoneProviderRequestTest {
|
||||
|
||||
@Test
|
||||
public void testParcelable() {
|
||||
LocationTimeZoneProviderRequest.Builder builder =
|
||||
new LocationTimeZoneProviderRequest.Builder()
|
||||
.setReportLocationTimeZone(false);
|
||||
assertRoundTripParcelable(builder.build());
|
||||
|
||||
builder.setReportLocationTimeZone(true)
|
||||
.setInitializationTimeoutMillis(Duration.ofMinutes(5).toMillis());
|
||||
|
||||
assertRoundTripParcelable(builder.build());
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 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 com.android.internal.location.timezone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/** Utility methods related to {@link Parcelable} objects used in several tests. */
|
||||
final class ParcelableTestSupport {
|
||||
|
||||
private ParcelableTestSupport() {}
|
||||
|
||||
/** Returns the result of parceling and unparceling the argument. */
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Parcelable> T roundTripParcelable(T parcelable) {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.writeTypedObject(parcelable, 0);
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
Parcelable.Creator<T> creator;
|
||||
try {
|
||||
Field creatorField = parcelable.getClass().getField("CREATOR");
|
||||
creator = (Parcelable.Creator<T>) creatorField.get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
T toReturn = parcel.readTypedObject(creator);
|
||||
parcel.recycle();
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public static <T extends Parcelable> void assertRoundTripParcelable(T instance) {
|
||||
assertEquals(instance, roundTripParcelable(instance));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user