Prepare for rate limiting TimeZoneProviderService
Prepare for rate limiting TimeZoneProviderService. The first step is to add duplicate event detection. Later, this will be extended to add a time component. i.e. the android.service.timezone.TimeZoneProviderService will pass on suggestions that are semantically different from a previous event, but will not if they are semantically the same. In a later commit it will be made to pass on changes that are the same but newer than some threshold. Most of the changes in this commit are to track a change to the binder API and the move of TimeZoneProviderEvent so that it can be used in code outside of the system server. Also: + TimeZoneProviderService is now stateful, so add dump() implementation. Because dump() is called on the main thread, add locks needed for safe threading (previously, all logic took place on a known handler thread). Test: atest hostsidetests/time/host/src/android/time/cts/host/LocationTimeZoneManagerHostTest.java Test: atest core/tests/coretests/src/android/service/timezone/TimeZoneProviderEventTest.java Test: atest services/tests/servicestests/src/com/android/server/timezonedetector/location/ZoneInfoDbTimeZoneProviderEventPreProcessorTest.java Test: treehugger Bug: 197624972 Bug: 200710190 Change-Id: Ia3246e969fda61836c8e1eee3007a8177d119994
This commit is contained in:
@@ -16,13 +16,11 @@
|
||||
|
||||
package android.service.timezone;
|
||||
|
||||
import android.service.timezone.TimeZoneProviderSuggestion;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
oneway interface ITimeZoneProviderManager {
|
||||
void onTimeZoneProviderSuggestion(in TimeZoneProviderSuggestion timeZoneProviderSuggestion);
|
||||
void onTimeZoneProviderUncertain();
|
||||
void onTimeZoneProviderPermanentFailure(in String failureReason);
|
||||
void onTimeZoneProviderEvent(in TimeZoneProviderEvent timeZoneProviderEvent);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2021, 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.service.timezone;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
parcelable TimeZoneProviderEvent;
|
||||
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.timezonedetector.location;
|
||||
package android.service.timezone;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.service.timezone.TimeZoneProviderService;
|
||||
import android.service.timezone.TimeZoneProviderSuggestion;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -29,9 +29,11 @@ import java.lang.annotation.Target;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An event from a {@link TimeZoneProviderService}.
|
||||
* Encapsulates a reported event from a {@link TimeZoneProviderService}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
final class TimeZoneProviderEvent {
|
||||
public final class TimeZoneProviderEvent implements Parcelable {
|
||||
|
||||
@IntDef(prefix = "EVENT_TYPE_",
|
||||
value = { EVENT_TYPE_PERMANENT_FAILURE, EVENT_TYPE_SUGGESTION, EVENT_TYPE_UNCERTAIN })
|
||||
@@ -118,6 +120,35 @@ final class TimeZoneProviderEvent {
|
||||
return mFailureCause;
|
||||
}
|
||||
|
||||
public static final @NonNull Creator<TimeZoneProviderEvent> CREATOR =
|
||||
new Creator<TimeZoneProviderEvent>() {
|
||||
@Override
|
||||
public TimeZoneProviderEvent createFromParcel(Parcel in) {
|
||||
int type = in.readInt();
|
||||
TimeZoneProviderSuggestion suggestion =
|
||||
in.readParcelable(getClass().getClassLoader());
|
||||
String failureCause = in.readString8();
|
||||
return new TimeZoneProviderEvent(type, suggestion, failureCause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeZoneProviderEvent[] newArray(int size) {
|
||||
return new TimeZoneProviderEvent[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel parcel, int flags) {
|
||||
parcel.writeInt(mType);
|
||||
parcel.writeParcelable(mSuggestion, 0);
|
||||
parcel.writeString8(mFailureCause);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TimeZoneProviderEvent{"
|
||||
@@ -127,6 +158,27 @@ final class TimeZoneProviderEvent {
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #equals} except this methods checks for equivalence, not equality.
|
||||
* i.e. two {@link #EVENT_TYPE_UNCERTAIN} and {@link #EVENT_TYPE_PERMANENT_FAILURE} events are
|
||||
* always equivalent, two {@link #EVENT_TYPE_SUGGESTION} events are equivalent if they suggest
|
||||
* the same time zones.
|
||||
*/
|
||||
@SuppressWarnings("ReferenceEquality")
|
||||
public boolean isEquivalentTo(@Nullable TimeZoneProviderEvent other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (other == null || mType != other.mType) {
|
||||
return false;
|
||||
}
|
||||
if (mType == EVENT_TYPE_SUGGESTION) {
|
||||
// Only check the time zone IDs. The times will be different, but we don't mind.
|
||||
return mSuggestion.getTimeZoneIds().equals(other.getSuggestion().getTimeZoneIds());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -28,8 +28,11 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -122,7 +125,9 @@ import java.util.Objects;
|
||||
* #onDestroy()} can occur on a different thread from those made to {@link
|
||||
* TimeZoneProviderService}-defined service methods, so implementations must be defensive and not
|
||||
* assume an ordering between them, e.g. a call to {@link #onStopUpdates()} can occur after {@link
|
||||
* #onDestroy()} and should be handled safely.
|
||||
* #onDestroy()} and should be handled safely. {@link #mLock} is used to ensure that synchronous
|
||||
* calls like {@link #dump(FileDescriptor, PrintWriter, String[])} are safe with respect to
|
||||
* asynchronous behavior.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@@ -162,12 +167,26 @@ public abstract class TimeZoneProviderService extends Service {
|
||||
|
||||
private final TimeZoneProviderServiceWrapper mWrapper = new TimeZoneProviderServiceWrapper();
|
||||
|
||||
/** The object used for operations that occur between the main / handler thread. */
|
||||
private final Object mLock = new Object();
|
||||
|
||||
/** The handler used for most operations. */
|
||||
private final Handler mHandler = BackgroundThread.getHandler();
|
||||
|
||||
/** Set by {@link #mHandler} thread. */
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private ITimeZoneProviderManager mManager;
|
||||
|
||||
/**
|
||||
* The type of the last suggestion sent to the system server. Used to de-dupe suggestions client
|
||||
* side and avoid calling into the system server unnecessarily. {@code null} means no previous
|
||||
* event has been sent this cycle; this field is cleared when the service is started.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private TimeZoneProviderEvent mLastEventSent;
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public final IBinder onBind(@NonNull Intent intent) {
|
||||
@@ -182,12 +201,19 @@ public abstract class TimeZoneProviderService extends Service {
|
||||
Objects.requireNonNull(suggestion);
|
||||
|
||||
mHandler.post(() -> {
|
||||
ITimeZoneProviderManager manager = mManager;
|
||||
if (manager != null) {
|
||||
try {
|
||||
manager.onTimeZoneProviderSuggestion(suggestion);
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
Log.w(TAG, e);
|
||||
synchronized (mLock) {
|
||||
ITimeZoneProviderManager manager = mManager;
|
||||
if (manager != null) {
|
||||
try {
|
||||
TimeZoneProviderEvent thisEvent =
|
||||
TimeZoneProviderEvent.createSuggestionEvent(suggestion);
|
||||
if (!thisEvent.isEquivalentTo(mLastEventSent)) {
|
||||
manager.onTimeZoneProviderEvent(thisEvent);
|
||||
mLastEventSent = thisEvent;
|
||||
}
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -200,12 +226,19 @@ public abstract class TimeZoneProviderService extends Service {
|
||||
*/
|
||||
public final void reportUncertain() {
|
||||
mHandler.post(() -> {
|
||||
ITimeZoneProviderManager manager = mManager;
|
||||
if (manager != null) {
|
||||
try {
|
||||
manager.onTimeZoneProviderUncertain();
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
Log.w(TAG, e);
|
||||
synchronized (mLock) {
|
||||
ITimeZoneProviderManager manager = mManager;
|
||||
if (manager != null) {
|
||||
try {
|
||||
TimeZoneProviderEvent thisEvent =
|
||||
TimeZoneProviderEvent.createUncertainEvent();
|
||||
if (!thisEvent.isEquivalentTo(mLastEventSent)) {
|
||||
manager.onTimeZoneProviderEvent(thisEvent);
|
||||
mLastEventSent = thisEvent;
|
||||
}
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -219,12 +252,20 @@ public abstract class TimeZoneProviderService extends Service {
|
||||
Objects.requireNonNull(cause);
|
||||
|
||||
mHandler.post(() -> {
|
||||
ITimeZoneProviderManager manager = mManager;
|
||||
if (manager != null) {
|
||||
try {
|
||||
manager.onTimeZoneProviderPermanentFailure(cause.getMessage());
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
Log.w(TAG, e);
|
||||
synchronized (mLock) {
|
||||
ITimeZoneProviderManager manager = mManager;
|
||||
if (manager != null) {
|
||||
try {
|
||||
String causeString = cause.getMessage();
|
||||
TimeZoneProviderEvent thisEvent =
|
||||
TimeZoneProviderEvent.createPermanentFailureEvent(causeString);
|
||||
if (!thisEvent.isEquivalentTo(mLastEventSent)) {
|
||||
manager.onTimeZoneProviderEvent(thisEvent);
|
||||
mLastEventSent = thisEvent;
|
||||
}
|
||||
} catch (RemoteException | RuntimeException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -232,8 +273,11 @@ public abstract class TimeZoneProviderService extends Service {
|
||||
|
||||
private void onStartUpdatesInternal(@NonNull ITimeZoneProviderManager manager,
|
||||
@DurationMillisLong long initializationTimeoutMillis) {
|
||||
mManager = manager;
|
||||
onStartUpdates(initializationTimeoutMillis);
|
||||
synchronized (mLock) {
|
||||
mManager = manager;
|
||||
mLastEventSent = null;
|
||||
onStartUpdates(initializationTimeoutMillis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,8 +309,10 @@ public abstract class TimeZoneProviderService extends Service {
|
||||
public abstract void onStartUpdates(@DurationMillisLong long initializationTimeoutMillis);
|
||||
|
||||
private void onStopUpdatesInternal() {
|
||||
onStopUpdates();
|
||||
mManager = null;
|
||||
synchronized (mLock) {
|
||||
onStopUpdates();
|
||||
mManager = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,6 +321,14 @@ public abstract class TimeZoneProviderService extends Service {
|
||||
*/
|
||||
public abstract void onStopUpdates();
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
synchronized (mLock) {
|
||||
writer.append("mLastEventSent=" + mLastEventSent);
|
||||
}
|
||||
}
|
||||
|
||||
private class TimeZoneProviderServiceWrapper extends ITimeZoneProvider.Stub {
|
||||
|
||||
public void startUpdates(@NonNull ITimeZoneProviderManager manager,
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2021 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.service.timezone;
|
||||
|
||||
import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
public class TimeZoneProviderEventTest {
|
||||
|
||||
@Test
|
||||
public void isEquivalentToAndEquals() {
|
||||
TimeZoneProviderEvent fail1v1 = TimeZoneProviderEvent.createPermanentFailureEvent("one");
|
||||
assertEquals(fail1v1, fail1v1);
|
||||
assertIsEquivalentTo(fail1v1, fail1v1);
|
||||
assertNotEquals(fail1v1, null);
|
||||
assertNotEquivalentTo(fail1v1, null);
|
||||
|
||||
{
|
||||
TimeZoneProviderEvent fail1v2 =
|
||||
TimeZoneProviderEvent.createPermanentFailureEvent("one");
|
||||
assertEquals(fail1v1, fail1v2);
|
||||
assertIsEquivalentTo(fail1v1, fail1v2);
|
||||
|
||||
TimeZoneProviderEvent fail2 = TimeZoneProviderEvent.createPermanentFailureEvent("two");
|
||||
assertNotEquals(fail1v1, fail2);
|
||||
assertIsEquivalentTo(fail1v1, fail2);
|
||||
}
|
||||
|
||||
TimeZoneProviderEvent uncertain1v1 = TimeZoneProviderEvent.createUncertainEvent();
|
||||
assertEquals(uncertain1v1, uncertain1v1);
|
||||
assertIsEquivalentTo(uncertain1v1, uncertain1v1);
|
||||
assertNotEquals(uncertain1v1, null);
|
||||
assertNotEquivalentTo(uncertain1v1, null);
|
||||
|
||||
{
|
||||
TimeZoneProviderEvent uncertain1v2 = TimeZoneProviderEvent.createUncertainEvent();
|
||||
assertEquals(uncertain1v1, uncertain1v2);
|
||||
assertIsEquivalentTo(uncertain1v1, uncertain1v2);
|
||||
}
|
||||
|
||||
TimeZoneProviderSuggestion suggestion1 = new TimeZoneProviderSuggestion.Builder()
|
||||
.setElapsedRealtimeMillis(1111L)
|
||||
.setTimeZoneIds(Collections.singletonList("Europe/London"))
|
||||
.build();
|
||||
TimeZoneProviderEvent certain1v1 = TimeZoneProviderEvent.createSuggestionEvent(suggestion1);
|
||||
assertEquals(certain1v1, certain1v1);
|
||||
assertIsEquivalentTo(certain1v1, certain1v1);
|
||||
assertNotEquals(certain1v1, null);
|
||||
assertNotEquivalentTo(certain1v1, null);
|
||||
|
||||
{
|
||||
TimeZoneProviderEvent certain1v2 =
|
||||
TimeZoneProviderEvent.createSuggestionEvent(suggestion1);
|
||||
assertEquals(certain1v1, certain1v2);
|
||||
assertIsEquivalentTo(certain1v1, certain1v2);
|
||||
|
||||
TimeZoneProviderSuggestion suggestion2 = new TimeZoneProviderSuggestion.Builder()
|
||||
.setElapsedRealtimeMillis(2222L)
|
||||
.setTimeZoneIds(Collections.singletonList("Europe/London"))
|
||||
.build();
|
||||
assertNotEquals(suggestion1, suggestion2);
|
||||
TimeZoneProviderEvent certain2 =
|
||||
TimeZoneProviderEvent.createSuggestionEvent(suggestion2);
|
||||
assertNotEquals(certain1v1, certain2);
|
||||
assertIsEquivalentTo(certain1v1, certain2);
|
||||
|
||||
TimeZoneProviderSuggestion suggestion3 = new TimeZoneProviderSuggestion.Builder()
|
||||
.setTimeZoneIds(Collections.singletonList("Europe/Paris"))
|
||||
.build();
|
||||
TimeZoneProviderEvent certain3 =
|
||||
TimeZoneProviderEvent.createSuggestionEvent(suggestion3);
|
||||
assertNotEquals(certain1v1, certain3);
|
||||
assertNotEquivalentTo(certain1v1, certain3);
|
||||
}
|
||||
|
||||
assertNotEquals(fail1v1, uncertain1v1);
|
||||
assertNotEquivalentTo(fail1v1, uncertain1v1);
|
||||
|
||||
assertNotEquals(fail1v1, certain1v1);
|
||||
assertNotEquivalentTo(fail1v1, certain1v1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelable_failureEvent() {
|
||||
TimeZoneProviderEvent event =
|
||||
TimeZoneProviderEvent.createPermanentFailureEvent("failure reason");
|
||||
assertRoundTripParcelable(event);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelable_uncertain() {
|
||||
TimeZoneProviderEvent event = TimeZoneProviderEvent.createUncertainEvent();
|
||||
assertRoundTripParcelable(event);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParcelable_suggestion() {
|
||||
TimeZoneProviderSuggestion suggestion = new TimeZoneProviderSuggestion.Builder()
|
||||
.setTimeZoneIds(Arrays.asList("Europe/London", "Europe/Paris"))
|
||||
.build();
|
||||
TimeZoneProviderEvent event = TimeZoneProviderEvent.createSuggestionEvent(suggestion);
|
||||
assertRoundTripParcelable(event);
|
||||
}
|
||||
|
||||
private static void assertNotEquivalentTo(
|
||||
TimeZoneProviderEvent one, TimeZoneProviderEvent two) {
|
||||
if (one == null && two == null) {
|
||||
fail("null arguments");
|
||||
}
|
||||
if (one != null) {
|
||||
assertFalse("one=" + one + ", two=" + two, one.isEquivalentTo(two));
|
||||
}
|
||||
if (two != null) {
|
||||
assertFalse("one=" + one + ", two=" + two, two.isEquivalentTo(one));
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertIsEquivalentTo(TimeZoneProviderEvent one, TimeZoneProviderEvent two) {
|
||||
if (one == null || two == null) {
|
||||
fail("null arguments");
|
||||
}
|
||||
assertTrue("one=" + one + ", two=" + two, one.isEquivalentTo(two));
|
||||
assertTrue("one=" + one + ", two=" + two, two.isEquivalentTo(one));
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import static com.android.server.timezonedetector.location.LocationTimeZoneProvi
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package com.android.server.timezonedetector.location;
|
||||
|
||||
import static android.service.timezone.TimeZoneProviderEvent.EVENT_TYPE_PERMANENT_FAILURE;
|
||||
import static android.service.timezone.TimeZoneProviderEvent.EVENT_TYPE_SUGGESTION;
|
||||
import static android.service.timezone.TimeZoneProviderEvent.EVENT_TYPE_UNCERTAIN;
|
||||
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.debugLog;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState;
|
||||
@@ -25,14 +29,12 @@ import static com.android.server.timezonedetector.location.LocationTimeZoneProvi
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_INITIALIZING;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_UNCERTAIN;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STOPPED;
|
||||
import static com.android.server.timezonedetector.location.TimeZoneProviderEvent.EVENT_TYPE_PERMANENT_FAILURE;
|
||||
import static com.android.server.timezonedetector.location.TimeZoneProviderEvent.EVENT_TYPE_SUGGESTION;
|
||||
import static com.android.server.timezonedetector.location.TimeZoneProviderEvent.EVENT_TYPE_UNCERTAIN;
|
||||
|
||||
import android.annotation.DurationMillisLong;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.ShellCallback;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.service.timezone.TimeZoneProviderService;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package com.android.server.timezonedetector.location;
|
||||
|
||||
import static android.service.timezone.TimeZoneProviderEvent.EVENT_TYPE_PERMANENT_FAILURE;
|
||||
import static android.service.timezone.TimeZoneProviderEvent.EVENT_TYPE_SUGGESTION;
|
||||
import static android.service.timezone.TimeZoneProviderEvent.EVENT_TYPE_UNCERTAIN;
|
||||
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.debugLog;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.warnLog;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_DESTROYED;
|
||||
@@ -24,9 +28,6 @@ import static com.android.server.timezonedetector.location.LocationTimeZoneProvi
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_INITIALIZING;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STARTED_UNCERTAIN;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneProvider.ProviderState.PROVIDER_STATE_STOPPED;
|
||||
import static com.android.server.timezonedetector.location.TimeZoneProviderEvent.EVENT_TYPE_PERMANENT_FAILURE;
|
||||
import static com.android.server.timezonedetector.location.TimeZoneProviderEvent.EVENT_TYPE_SUGGESTION;
|
||||
import static com.android.server.timezonedetector.location.TimeZoneProviderEvent.EVENT_TYPE_UNCERTAIN;
|
||||
|
||||
import android.annotation.ElapsedRealtimeLong;
|
||||
import android.annotation.IntDef;
|
||||
@@ -34,6 +35,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.timezonedetector.location;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.service.timezone.ITimeZoneProvider;
|
||||
import android.service.timezone.ITimeZoneProviderManager;
|
||||
import android.service.timezone.TimeZoneProviderSuggestion;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -177,25 +177,7 @@ class RealLocationTimeZoneProviderProxy extends LocationTimeZoneProviderProxy im
|
||||
|
||||
// executed on binder thread
|
||||
@Override
|
||||
public void onTimeZoneProviderSuggestion(TimeZoneProviderSuggestion suggestion) {
|
||||
onTimeZoneProviderEvent(TimeZoneProviderEvent.createSuggestionEvent(suggestion));
|
||||
}
|
||||
|
||||
// executed on binder thread
|
||||
@Override
|
||||
public void onTimeZoneProviderUncertain() {
|
||||
onTimeZoneProviderEvent(TimeZoneProviderEvent.createUncertainEvent());
|
||||
|
||||
}
|
||||
|
||||
// executed on binder thread
|
||||
@Override
|
||||
public void onTimeZoneProviderPermanentFailure(String failureReason) {
|
||||
onTimeZoneProviderEvent(
|
||||
TimeZoneProviderEvent.createPermanentFailureEvent(failureReason));
|
||||
}
|
||||
|
||||
private void onTimeZoneProviderEvent(TimeZoneProviderEvent event) {
|
||||
public void onTimeZoneProviderEvent(TimeZoneProviderEvent event) {
|
||||
synchronized (mSharedLock) {
|
||||
if (mManagerProxy != this) {
|
||||
// Ignore incoming calls if this instance is no longer the current
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.timezonedetector.location;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
|
||||
/**
|
||||
* Used by {@link LocationTimeZoneProvider} to ensure that all time zone IDs are understood by the
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.timezonedetector.location;
|
||||
import static com.android.server.timezonedetector.location.LocationTimeZoneManagerService.infoLog;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
|
||||
import com.android.i18n.timezone.ZoneInfoDb;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import static java.util.Arrays.asList;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.service.timezone.TimeZoneProviderSuggestion;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.server.timezonedetector.location;
|
||||
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
|
||||
/**
|
||||
* Fake implementation of {@link TimeZoneProviderEventPreProcessor} which assumes that all events
|
||||
* are valid or always uncertain if {@link #enterUncertainMode()} was called.
|
||||
|
||||
@@ -32,6 +32,7 @@ import static java.util.Arrays.asList;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.service.timezone.TimeZoneProviderSuggestion;
|
||||
import android.util.IndentingPrintWriter;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.server.timezonedetector.location;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.service.timezone.TimeZoneProviderEvent;
|
||||
import android.service.timezone.TimeZoneProviderSuggestion;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
Reference in New Issue
Block a user