Loading src/java/com/android/internal/telephony/nitz/NewNitzStateMachineImpl.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.telephony.nitz; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import android.content.Context; import android.content.Context; import android.telephony.Rlog; import android.telephony.Rlog; import android.util.TimestampedValue; import android.util.TimestampedValue; Loading @@ -28,7 +29,6 @@ import com.android.internal.telephony.NitzData; import com.android.internal.telephony.NitzStateMachine; import com.android.internal.telephony.NitzStateMachine; import com.android.internal.telephony.Phone; import com.android.internal.telephony.Phone; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading Loading @@ -287,6 +287,7 @@ public final class NewNitzStateMachineImpl implements NitzStateMachine { PhoneTimeZoneSuggestion suggestion = PhoneTimeZoneSuggestion suggestion = mTimeZoneSuggester.getTimeZoneSuggestion(mPhoneId, countryIsoCode, nitzSignal); mTimeZoneSuggester.getTimeZoneSuggestion(mPhoneId, countryIsoCode, nitzSignal); suggestion.addDebugInfo("Detection reason=" + reason); suggestion.addDebugInfo("Detection reason=" + reason); if (DBG) { if (DBG) { Rlog.d(LOG_TAG, "doTimeZoneDetection: countryIsoCode=" + countryIsoCode Rlog.d(LOG_TAG, "doTimeZoneDetection: countryIsoCode=" + countryIsoCode + ", nitzSignal=" + nitzSignal + ", suggestion=" + suggestion + ", nitzSignal=" + nitzSignal + ", suggestion=" + suggestion Loading src/java/com/android/internal/telephony/nitz/NewTimeServiceHelper.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.internal.telephony.nitz; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.TimeDetector; import android.app.timedetector.TimeDetector; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import java.io.PrintWriter; import java.io.PrintWriter; Loading src/java/com/android/internal/telephony/nitz/NewTimeServiceHelperImpl.java +5 −8 Original line number Original line Diff line number Diff line Loading @@ -20,14 +20,14 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.TimeDetector; import android.app.timedetector.TimeDetector; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import android.app.timezonedetector.TimeZoneDetector; import android.content.Context; import android.content.Context; import android.util.LocalLog; import android.util.LocalLog; import android.util.TimestampedValue; import android.util.TimestampedValue; import com.android.internal.telephony.Phone; import com.android.internal.telephony.Phone; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import com.android.internal.telephony.nitz.service.TimeZoneDetectionService; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import java.io.PrintWriter; import java.io.PrintWriter; Loading @@ -40,7 +40,7 @@ public final class NewTimeServiceHelperImpl implements NewTimeServiceHelper { private final int mPhoneId; private final int mPhoneId; private final TimeDetector mTimeDetector; private final TimeDetector mTimeDetector; private final TimeZoneDetectionService mTimeZoneDetector; private final TimeZoneDetector mTimeZoneDetector; private final LocalLog mTimeZoneLog = new LocalLog(30); private final LocalLog mTimeZoneLog = new LocalLog(30); private final LocalLog mTimeLog = new LocalLog(30); private final LocalLog mTimeLog = new LocalLog(30); Loading @@ -57,7 +57,8 @@ public final class NewTimeServiceHelperImpl implements NewTimeServiceHelper { mPhoneId = phone.getPhoneId(); mPhoneId = phone.getPhoneId(); Context context = Objects.requireNonNull(phone.getContext()); Context context = Objects.requireNonNull(phone.getContext()); mTimeDetector = Objects.requireNonNull(context.getSystemService(TimeDetector.class)); mTimeDetector = Objects.requireNonNull(context.getSystemService(TimeDetector.class)); mTimeZoneDetector = Objects.requireNonNull(TimeZoneDetectionService.getInstance(context)); mTimeZoneDetector = Objects.requireNonNull(context.getSystemService(TimeZoneDetector.class)); } } @Override @Override Loading Loading @@ -110,14 +111,10 @@ public final class NewTimeServiceHelperImpl implements NewTimeServiceHelper { mTimeZoneLog.dump(ipw); mTimeZoneLog.dump(ipw); ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.decreaseIndent(); // TODO Remove this line when the service moves to the system server. mTimeZoneDetector.dumpLogs(ipw); } } @Override @Override public void dumpState(PrintWriter pw) { public void dumpState(PrintWriter pw) { pw.println(" NewTimeServiceHelperImpl.mLastSuggestedTimeZone=" + mLastSuggestedTimeZone); pw.println(" NewTimeServiceHelperImpl.mLastSuggestedTimeZone=" + mLastSuggestedTimeZone); mTimeZoneDetector.dumpState(pw); } } } } src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java +70 −60 Original line number Original line Diff line number Diff line Loading @@ -16,14 +16,11 @@ package com.android.internal.telephony.nitz; package com.android.internal.telephony.nitz; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_DEFAULT_BOOSTED; import static android.app.timezonedetector.PhoneTimeZoneSuggestion.createEmptySuggestion; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_MULTIPLE_ZONES_DIFFERENT_OFFSETS; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_MULTIPLE_ZONES_SAME_OFFSET; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_SINGLE_ZONE; import static com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion.createEmptySuggestion; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import android.telephony.Rlog; import android.telephony.Rlog; import android.text.TextUtils; import android.text.TextUtils; import android.util.TimestampedValue; import android.util.TimestampedValue; Loading @@ -34,7 +31,6 @@ import com.android.internal.telephony.NitzStateMachine.DeviceState; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult; import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult; import com.android.internal.telephony.nitz.NewNitzStateMachineImpl.TimeZoneSuggester; import com.android.internal.telephony.nitz.NewNitzStateMachineImpl.TimeZoneSuggester; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import java.util.Objects; import java.util.Objects; Loading Loading @@ -66,11 +62,13 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { if (nitzSignal != null) { if (nitzSignal != null) { NitzData nitzData = nitzSignal.getValue(); NitzData nitzData = nitzSignal.getValue(); if (nitzData.getEmulatorHostTimeZone() != null) { if (nitzData.getEmulatorHostTimeZone() != null) { overridingSuggestion = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder builder = overridingSuggestion.setZoneId(nitzData.getEmulatorHostTimeZone().getID()); new PhoneTimeZoneSuggestion.Builder(phoneId) overridingSuggestion.setMatchType(PhoneTimeZoneSuggestion.EMULATOR_ZONE_ID); .setZoneId(nitzData.getEmulatorHostTimeZone().getID()) overridingSuggestion.setQuality(PhoneTimeZoneSuggestion.SINGLE_ZONE); .setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID) overridingSuggestion.addDebugInfo("Emulator time zone override: " + nitzData); .setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE) .addDebugInfo("Emulator time zone override: " + nitzData); overridingSuggestion = builder.build(); } } } } Loading Loading @@ -125,7 +123,6 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { + ", nitzSignal=" + nitzSignal + ", nitzSignal=" + nitzSignal + ", e=" + e.getMessage(); + ", e=" + e.getMessage(); PhoneTimeZoneSuggestion errorSuggestion = createEmptySuggestion(phoneId, message); PhoneTimeZoneSuggestion errorSuggestion = createEmptySuggestion(phoneId, message); errorSuggestion.addDebugInfo(message); Rlog.w(LOG_TAG, message, e); Rlog.w(LOG_TAG, message, e); return errorSuggestion; return errorSuggestion; } } Loading @@ -142,21 +139,25 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { Objects.requireNonNull(nitzSignal); Objects.requireNonNull(nitzSignal); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); PhoneTimeZoneSuggestion result = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder suggestionBuilder = result.addDebugInfo("findTimeZoneForTestNetwork: nitzSignal=" + nitzSignal); new PhoneTimeZoneSuggestion.Builder(phoneId); suggestionBuilder.addDebugInfo("findTimeZoneForTestNetwork: nitzSignal=" + nitzSignal); TimeZoneLookupHelper.OffsetResult lookupResult = TimeZoneLookupHelper.OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitz(nitzData); mTimeZoneLookupHelper.lookupByNitz(nitzData); if (lookupResult == null) { if (lookupResult == null) { result.addDebugInfo("findTimeZoneForTestNetwork: No zone found"); suggestionBuilder.addDebugInfo("findTimeZoneForTestNetwork: No zone found"); } else { } else { result.setZoneId(lookupResult.getTimeZone().getID()); suggestionBuilder.setZoneId(lookupResult.getTimeZone().getID()); result.setMatchType(PhoneTimeZoneSuggestion.TEST_NETWORK_OFFSET_ONLY); suggestionBuilder.setMatchType( int quality = lookupResult.getIsOnlyMatch() ? PhoneTimeZoneSuggestion.SINGLE_ZONE PhoneTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY); : PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_SAME_OFFSET; int quality = lookupResult.getIsOnlyMatch() result.setQuality(quality); ? PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE result.addDebugInfo("findTimeZoneForTestNetwork: lookupResult=" + lookupResult); : PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET; suggestionBuilder.setQuality(quality); suggestionBuilder.addDebugInfo( "findTimeZoneForTestNetwork: lookupResult=" + lookupResult); } } return result; return suggestionBuilder.build(); } } /** /** Loading @@ -169,27 +170,32 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { Objects.requireNonNull(countryIsoCode); Objects.requireNonNull(countryIsoCode); Objects.requireNonNull(nitzSignal); Objects.requireNonNull(nitzSignal); PhoneTimeZoneSuggestion suggestion = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder suggestionBuilder = suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: countryIsoCode=" + countryIsoCode new PhoneTimeZoneSuggestion.Builder(phoneId); suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz:" + " countryIsoCode=" + countryIsoCode + ", nitzSignal=" + nitzSignal); + ", nitzSignal=" + nitzSignal); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); if (isNitzSignalOffsetInfoBogus(countryIsoCode, nitzData)) { if (isNitzSignalOffsetInfoBogus(countryIsoCode, nitzData)) { suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: NITZ signal looks bogus"); suggestionBuilder.addDebugInfo( return suggestion; "findTimeZoneFromCountryAndNitz: NITZ signal looks bogus"); return suggestionBuilder.build(); } } // Try to find a match using both country + NITZ signal. // Try to find a match using both country + NITZ signal. TimeZoneLookupHelper.OffsetResult lookupResult = TimeZoneLookupHelper.OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, countryIsoCode); mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, countryIsoCode); if (lookupResult != null) { if (lookupResult != null) { suggestion.setZoneId(lookupResult.getTimeZone().getID()); suggestionBuilder.setZoneId(lookupResult.getTimeZone().getID()); suggestion.setMatchType(PhoneTimeZoneSuggestion.NETWORK_COUNTRY_AND_OFFSET); suggestionBuilder.setMatchType( PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET); int quality = lookupResult.getIsOnlyMatch() int quality = lookupResult.getIsOnlyMatch() ? PhoneTimeZoneSuggestion.SINGLE_ZONE ? PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE : PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_SAME_OFFSET; : PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET; suggestion.setQuality(quality); suggestionBuilder.setQuality(quality); suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: lookupResult=" + lookupResult); suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz:" return suggestion; + " lookupResult=" + lookupResult); return suggestionBuilder.build(); } } // The country + offset provided no match, so see if the country by itself would be enough. // The country + offset provided no match, so see if the country by itself would be enough. Loading @@ -197,29 +203,29 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { countryIsoCode, nitzData.getCurrentTimeInMillis()); countryIsoCode, nitzData.getCurrentTimeInMillis()); if (countryResult == null) { if (countryResult == null) { // Country not recognized. // Country not recognized. suggestion.addDebugInfo( suggestionBuilder.addDebugInfo( "findTimeZoneFromCountryAndNitz: lookupByCountry() country not recognized"); "findTimeZoneFromCountryAndNitz: lookupByCountry() country not recognized"); return suggestion; return suggestionBuilder.build(); } } // If the country has a single zone, or it has multiple zones but the default zone is // If the country has a single zone, or it has multiple zones but the default zone is // "boosted" (i.e. the country default is considered a good suggestion in most cases) then // "boosted" (i.e. the country default is considered a good suggestion in most cases) then // use it. // use it. if (countryResult.quality == QUALITY_SINGLE_ZONE if (countryResult.quality == CountryResult.QUALITY_SINGLE_ZONE || countryResult.quality == QUALITY_DEFAULT_BOOSTED) { || countryResult.quality == CountryResult.QUALITY_DEFAULT_BOOSTED) { suggestion.setZoneId(countryResult.zoneId); suggestionBuilder.setZoneId(countryResult.zoneId); suggestion.setMatchType(PhoneTimeZoneSuggestion.NETWORK_COUNTRY_ONLY); suggestionBuilder.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY); suggestion.setQuality(PhoneTimeZoneSuggestion.SINGLE_ZONE); suggestionBuilder.setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE); suggestion.addDebugInfo( suggestionBuilder.addDebugInfo( "findTimeZoneFromCountryAndNitz: high quality country-only suggestion:" "findTimeZoneFromCountryAndNitz: high quality country-only suggestion:" + " countryResult=" + countryResult); + " countryResult=" + countryResult); return suggestion; return suggestionBuilder.build(); } } // Quality is not high enough to set the zone using country only. // Quality is not high enough to set the zone using country only. suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: country-only suggestion quality" suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz: country-only suggestion" + " not high enough. countryResult=" + countryResult); + " quality not high enough. countryResult=" + countryResult); return suggestion; return suggestionBuilder.build(); } } /** /** Loading @@ -237,35 +243,39 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { throw new IllegalArgumentException("countryIsoCode must not be empty"); throw new IllegalArgumentException("countryIsoCode must not be empty"); } } PhoneTimeZoneSuggestion result = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder suggestionBuilder = result.addDebugInfo("findTimeZoneFromNetworkCountryCode:" new PhoneTimeZoneSuggestion.Builder(phoneId); suggestionBuilder.addDebugInfo("findTimeZoneFromNetworkCountryCode:" + " whenMillis=" + whenMillis + ", countryIsoCode=" + countryIsoCode); + " whenMillis=" + whenMillis + ", countryIsoCode=" + countryIsoCode); CountryResult lookupResult = mTimeZoneLookupHelper.lookupByCountry( CountryResult lookupResult = mTimeZoneLookupHelper.lookupByCountry( countryIsoCode, whenMillis); countryIsoCode, whenMillis); if (lookupResult != null) { if (lookupResult != null) { result.setZoneId(lookupResult.zoneId); suggestionBuilder.setZoneId(lookupResult.zoneId); result.setMatchType(PhoneTimeZoneSuggestion.NETWORK_COUNTRY_ONLY); suggestionBuilder.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY); int quality; int quality; if (lookupResult.quality == QUALITY_SINGLE_ZONE if (lookupResult.quality == CountryResult.QUALITY_SINGLE_ZONE || lookupResult.quality == QUALITY_DEFAULT_BOOSTED) { || lookupResult.quality == CountryResult.QUALITY_DEFAULT_BOOSTED) { quality = PhoneTimeZoneSuggestion.SINGLE_ZONE; quality = PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE; } else if (lookupResult.quality == QUALITY_MULTIPLE_ZONES_SAME_OFFSET) { } else if (lookupResult.quality == CountryResult.QUALITY_MULTIPLE_ZONES_SAME_OFFSET) { quality = PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_SAME_OFFSET; quality = PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET; } else if (lookupResult.quality == QUALITY_MULTIPLE_ZONES_DIFFERENT_OFFSETS) { } else if (lookupResult.quality quality = PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS; == CountryResult.QUALITY_MULTIPLE_ZONES_DIFFERENT_OFFSETS) { quality = PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS; } else { } else { // This should never happen. // This should never happen. throw new IllegalArgumentException( throw new IllegalArgumentException( "lookupResult.quality not recognized: countryIsoCode=" + countryIsoCode "lookupResult.quality not recognized: countryIsoCode=" + countryIsoCode + ", whenMillis=" + whenMillis + ", lookupResult=" + lookupResult); + ", whenMillis=" + whenMillis + ", lookupResult=" + lookupResult); } } result.setQuality(quality); suggestionBuilder.setQuality(quality); result.addDebugInfo("findTimeZoneFromNetworkCountryCode: lookupResult=" + lookupResult); suggestionBuilder.addDebugInfo( "findTimeZoneFromNetworkCountryCode: lookupResult=" + lookupResult); } else { } else { result.addDebugInfo("findTimeZoneFromNetworkCountryCode: Country not recognized?"); suggestionBuilder.addDebugInfo( "findTimeZoneFromNetworkCountryCode: Country not recognized?"); } } return result; return suggestionBuilder.build(); } } /** /** Loading src/java/com/android/internal/telephony/nitz/service/PhoneTimeZoneSuggestion.javadeleted 100644 → 0 +0 −254 Original line number Original line Diff line number Diff line /* * 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.telephony.nitz.service; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; /** * A suggested time zone from a Phone-based signal, e.g. from MCC and NITZ information. */ public final class PhoneTimeZoneSuggestion implements Parcelable { public static final Creator<PhoneTimeZoneSuggestion> CREATOR = new Creator<PhoneTimeZoneSuggestion>() { public PhoneTimeZoneSuggestion createFromParcel(Parcel in) { return PhoneTimeZoneSuggestion.createFromParcel(in); } public PhoneTimeZoneSuggestion[] newArray(int size) { return new PhoneTimeZoneSuggestion[size]; } }; /** * Creates an empty time zone suggestion, i.e. one that will cancel previous suggestions with * the same {@code phoneId}. */ @NonNull public static PhoneTimeZoneSuggestion createEmptySuggestion( int phoneId, @NonNull String debugInfo) { PhoneTimeZoneSuggestion timeZoneSuggestion = new PhoneTimeZoneSuggestion(phoneId); timeZoneSuggestion.addDebugInfo(debugInfo); return timeZoneSuggestion; } @IntDef({ MATCH_TYPE_NA, NETWORK_COUNTRY_ONLY, NETWORK_COUNTRY_AND_OFFSET, EMULATOR_ZONE_ID, TEST_NETWORK_OFFSET_ONLY }) @Retention(RetentionPolicy.SOURCE) public @interface MatchType {} /** Used when match type is not applicable. */ public static final int MATCH_TYPE_NA = 0; /** * Only the network country is known. */ public static final int NETWORK_COUNTRY_ONLY = 2; /** * Both the network county and offset were known. */ public static final int NETWORK_COUNTRY_AND_OFFSET = 3; /** * The device is running in an emulator and an NITZ signal was simulated containing an * Android extension with an explicit Olson ID. */ public static final int EMULATOR_ZONE_ID = 4; /** * The phone is most likely running in a test network not associated with a country (this is * distinct from the country just not being known yet). * Historically, Android has just picked an arbitrary time zone with the correct offset when * on a test network. */ public static final int TEST_NETWORK_OFFSET_ONLY = 5; @IntDef({ QUALITY_NA, SINGLE_ZONE, MULTIPLE_ZONES_WITH_SAME_OFFSET, MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS }) @Retention(RetentionPolicy.SOURCE) public @interface Quality {} /** Used when quality is not applicable. */ public static final int QUALITY_NA = 0; /** There is only one answer */ public static final int SINGLE_ZONE = 1; /** * There are multiple answers, but they all shared the same offset / DST state at the time * the suggestion was created. i.e. it might be the wrong zone but the user won't notice * immediately if it is wrong. */ public static final int MULTIPLE_ZONES_WITH_SAME_OFFSET = 2; /** * There are multiple answers with different offsets. The one given is just one possible. */ public static final int MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS = 3; /** * The ID of the phone this suggestion is associated with. For multiple-sim devices this * helps to establish origin so filtering / stickiness can be implemented. */ private final int mPhoneId; /** * The suggestion. {@code null} means there is no current suggestion and any previous suggestion * should be forgotten. */ private String mZoneId; /** * The type of "match" used to establish the time zone. */ @MatchType private int mMatchType; /** * A measure of the quality of the time zone suggestion, i.e. how confident one could be in * it. */ @Quality private int mQuality; /** * Free-form debug information about how the signal was derived. Used for debug only, * intentionally not used in equals(), etc. */ private List<String> mDebugInfo; public PhoneTimeZoneSuggestion(int phoneId) { this.mPhoneId = phoneId; } @SuppressWarnings("unchecked") private static PhoneTimeZoneSuggestion createFromParcel(Parcel in) { int phoneId = in.readInt(); PhoneTimeZoneSuggestion phoneTimeZoneSuggestion = new PhoneTimeZoneSuggestion(phoneId); phoneTimeZoneSuggestion.mZoneId = in.readString(); phoneTimeZoneSuggestion.mMatchType = in.readInt(); phoneTimeZoneSuggestion.mQuality = in.readInt(); phoneTimeZoneSuggestion.mDebugInfo = (List<String>) in.readArrayList(PhoneTimeZoneSuggestion.class.getClassLoader()); return phoneTimeZoneSuggestion; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mPhoneId); dest.writeString(mZoneId); dest.writeInt(mMatchType); dest.writeInt(mQuality); dest.writeList(mDebugInfo); } @Override public int describeContents() { return 0; } public int getPhoneId() { return mPhoneId; } @Nullable public String getZoneId() { return mZoneId; } public void setZoneId(@Nullable String zoneId) { this.mZoneId = zoneId; } @MatchType public int getMatchType() { return mMatchType; } public void setMatchType(@MatchType int matchType) { this.mMatchType = matchType; } @Quality public int getQuality() { return mQuality; } public void setQuality(@Quality int quality) { this.mQuality = quality; } public List<String> getDebugInfo() { return Collections.unmodifiableList(mDebugInfo); } /** * Associates information with the instance that can be useful for debugging / logging. The * information is present in {@link #toString()} but is not considered for * {@link #equals(Object)} and {@link #hashCode()}. */ public void addDebugInfo(String... debugInfos) { if (mDebugInfo == null) { mDebugInfo = new ArrayList<>(); } mDebugInfo.addAll(Arrays.asList(debugInfos)); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } PhoneTimeZoneSuggestion that = (PhoneTimeZoneSuggestion) o; return mPhoneId == that.mPhoneId && mMatchType == that.mMatchType && mQuality == that.mQuality && Objects.equals(mZoneId, that.mZoneId); } @Override public int hashCode() { return Objects.hash(mPhoneId, mZoneId, mMatchType, mQuality); } @Override public String toString() { return "PhoneTimeZoneSuggestion{" + "mPhoneId=" + mPhoneId + ", mZoneId='" + mZoneId + '\'' + ", mMatchType=" + mMatchType + ", mQuality=" + mQuality + ", mDebugInfo=" + mDebugInfo + '}'; } } Loading
src/java/com/android/internal/telephony/nitz/NewNitzStateMachineImpl.java +2 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.internal.telephony.nitz; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import android.content.Context; import android.content.Context; import android.telephony.Rlog; import android.telephony.Rlog; import android.util.TimestampedValue; import android.util.TimestampedValue; Loading @@ -28,7 +29,6 @@ import com.android.internal.telephony.NitzData; import com.android.internal.telephony.NitzStateMachine; import com.android.internal.telephony.NitzStateMachine; import com.android.internal.telephony.Phone; import com.android.internal.telephony.Phone; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.FileDescriptor; Loading Loading @@ -287,6 +287,7 @@ public final class NewNitzStateMachineImpl implements NitzStateMachine { PhoneTimeZoneSuggestion suggestion = PhoneTimeZoneSuggestion suggestion = mTimeZoneSuggester.getTimeZoneSuggestion(mPhoneId, countryIsoCode, nitzSignal); mTimeZoneSuggester.getTimeZoneSuggestion(mPhoneId, countryIsoCode, nitzSignal); suggestion.addDebugInfo("Detection reason=" + reason); suggestion.addDebugInfo("Detection reason=" + reason); if (DBG) { if (DBG) { Rlog.d(LOG_TAG, "doTimeZoneDetection: countryIsoCode=" + countryIsoCode Rlog.d(LOG_TAG, "doTimeZoneDetection: countryIsoCode=" + countryIsoCode + ", nitzSignal=" + nitzSignal + ", suggestion=" + suggestion + ", nitzSignal=" + nitzSignal + ", suggestion=" + suggestion Loading
src/java/com/android/internal/telephony/nitz/NewTimeServiceHelper.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.internal.telephony.nitz; import android.annotation.NonNull; import android.annotation.NonNull; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.TimeDetector; import android.app.timedetector.TimeDetector; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import java.io.PrintWriter; import java.io.PrintWriter; Loading
src/java/com/android/internal/telephony/nitz/NewTimeServiceHelperImpl.java +5 −8 Original line number Original line Diff line number Diff line Loading @@ -20,14 +20,14 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.PhoneTimeSuggestion; import android.app.timedetector.TimeDetector; import android.app.timedetector.TimeDetector; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import android.app.timezonedetector.TimeZoneDetector; import android.content.Context; import android.content.Context; import android.util.LocalLog; import android.util.LocalLog; import android.util.TimestampedValue; import android.util.TimestampedValue; import com.android.internal.telephony.Phone; import com.android.internal.telephony.Phone; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import com.android.internal.telephony.nitz.service.TimeZoneDetectionService; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter; import java.io.PrintWriter; import java.io.PrintWriter; Loading @@ -40,7 +40,7 @@ public final class NewTimeServiceHelperImpl implements NewTimeServiceHelper { private final int mPhoneId; private final int mPhoneId; private final TimeDetector mTimeDetector; private final TimeDetector mTimeDetector; private final TimeZoneDetectionService mTimeZoneDetector; private final TimeZoneDetector mTimeZoneDetector; private final LocalLog mTimeZoneLog = new LocalLog(30); private final LocalLog mTimeZoneLog = new LocalLog(30); private final LocalLog mTimeLog = new LocalLog(30); private final LocalLog mTimeLog = new LocalLog(30); Loading @@ -57,7 +57,8 @@ public final class NewTimeServiceHelperImpl implements NewTimeServiceHelper { mPhoneId = phone.getPhoneId(); mPhoneId = phone.getPhoneId(); Context context = Objects.requireNonNull(phone.getContext()); Context context = Objects.requireNonNull(phone.getContext()); mTimeDetector = Objects.requireNonNull(context.getSystemService(TimeDetector.class)); mTimeDetector = Objects.requireNonNull(context.getSystemService(TimeDetector.class)); mTimeZoneDetector = Objects.requireNonNull(TimeZoneDetectionService.getInstance(context)); mTimeZoneDetector = Objects.requireNonNull(context.getSystemService(TimeZoneDetector.class)); } } @Override @Override Loading Loading @@ -110,14 +111,10 @@ public final class NewTimeServiceHelperImpl implements NewTimeServiceHelper { mTimeZoneLog.dump(ipw); mTimeZoneLog.dump(ipw); ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.decreaseIndent(); ipw.decreaseIndent(); // TODO Remove this line when the service moves to the system server. mTimeZoneDetector.dumpLogs(ipw); } } @Override @Override public void dumpState(PrintWriter pw) { public void dumpState(PrintWriter pw) { pw.println(" NewTimeServiceHelperImpl.mLastSuggestedTimeZone=" + mLastSuggestedTimeZone); pw.println(" NewTimeServiceHelperImpl.mLastSuggestedTimeZone=" + mLastSuggestedTimeZone); mTimeZoneDetector.dumpState(pw); } } } }
src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java +70 −60 Original line number Original line Diff line number Diff line Loading @@ -16,14 +16,11 @@ package com.android.internal.telephony.nitz; package com.android.internal.telephony.nitz; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_DEFAULT_BOOSTED; import static android.app.timezonedetector.PhoneTimeZoneSuggestion.createEmptySuggestion; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_MULTIPLE_ZONES_DIFFERENT_OFFSETS; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_MULTIPLE_ZONES_SAME_OFFSET; import static com.android.internal.telephony.TimeZoneLookupHelper.CountryResult.QUALITY_SINGLE_ZONE; import static com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion.createEmptySuggestion; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.app.timezonedetector.PhoneTimeZoneSuggestion; import android.telephony.Rlog; import android.telephony.Rlog; import android.text.TextUtils; import android.text.TextUtils; import android.util.TimestampedValue; import android.util.TimestampedValue; Loading @@ -34,7 +31,6 @@ import com.android.internal.telephony.NitzStateMachine.DeviceState; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.TimeZoneLookupHelper; import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult; import com.android.internal.telephony.TimeZoneLookupHelper.CountryResult; import com.android.internal.telephony.nitz.NewNitzStateMachineImpl.TimeZoneSuggester; import com.android.internal.telephony.nitz.NewNitzStateMachineImpl.TimeZoneSuggester; import com.android.internal.telephony.nitz.service.PhoneTimeZoneSuggestion; import java.util.Objects; import java.util.Objects; Loading Loading @@ -66,11 +62,13 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { if (nitzSignal != null) { if (nitzSignal != null) { NitzData nitzData = nitzSignal.getValue(); NitzData nitzData = nitzSignal.getValue(); if (nitzData.getEmulatorHostTimeZone() != null) { if (nitzData.getEmulatorHostTimeZone() != null) { overridingSuggestion = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder builder = overridingSuggestion.setZoneId(nitzData.getEmulatorHostTimeZone().getID()); new PhoneTimeZoneSuggestion.Builder(phoneId) overridingSuggestion.setMatchType(PhoneTimeZoneSuggestion.EMULATOR_ZONE_ID); .setZoneId(nitzData.getEmulatorHostTimeZone().getID()) overridingSuggestion.setQuality(PhoneTimeZoneSuggestion.SINGLE_ZONE); .setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID) overridingSuggestion.addDebugInfo("Emulator time zone override: " + nitzData); .setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE) .addDebugInfo("Emulator time zone override: " + nitzData); overridingSuggestion = builder.build(); } } } } Loading Loading @@ -125,7 +123,6 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { + ", nitzSignal=" + nitzSignal + ", nitzSignal=" + nitzSignal + ", e=" + e.getMessage(); + ", e=" + e.getMessage(); PhoneTimeZoneSuggestion errorSuggestion = createEmptySuggestion(phoneId, message); PhoneTimeZoneSuggestion errorSuggestion = createEmptySuggestion(phoneId, message); errorSuggestion.addDebugInfo(message); Rlog.w(LOG_TAG, message, e); Rlog.w(LOG_TAG, message, e); return errorSuggestion; return errorSuggestion; } } Loading @@ -142,21 +139,25 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { Objects.requireNonNull(nitzSignal); Objects.requireNonNull(nitzSignal); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); PhoneTimeZoneSuggestion result = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder suggestionBuilder = result.addDebugInfo("findTimeZoneForTestNetwork: nitzSignal=" + nitzSignal); new PhoneTimeZoneSuggestion.Builder(phoneId); suggestionBuilder.addDebugInfo("findTimeZoneForTestNetwork: nitzSignal=" + nitzSignal); TimeZoneLookupHelper.OffsetResult lookupResult = TimeZoneLookupHelper.OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitz(nitzData); mTimeZoneLookupHelper.lookupByNitz(nitzData); if (lookupResult == null) { if (lookupResult == null) { result.addDebugInfo("findTimeZoneForTestNetwork: No zone found"); suggestionBuilder.addDebugInfo("findTimeZoneForTestNetwork: No zone found"); } else { } else { result.setZoneId(lookupResult.getTimeZone().getID()); suggestionBuilder.setZoneId(lookupResult.getTimeZone().getID()); result.setMatchType(PhoneTimeZoneSuggestion.TEST_NETWORK_OFFSET_ONLY); suggestionBuilder.setMatchType( int quality = lookupResult.getIsOnlyMatch() ? PhoneTimeZoneSuggestion.SINGLE_ZONE PhoneTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY); : PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_SAME_OFFSET; int quality = lookupResult.getIsOnlyMatch() result.setQuality(quality); ? PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE result.addDebugInfo("findTimeZoneForTestNetwork: lookupResult=" + lookupResult); : PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET; suggestionBuilder.setQuality(quality); suggestionBuilder.addDebugInfo( "findTimeZoneForTestNetwork: lookupResult=" + lookupResult); } } return result; return suggestionBuilder.build(); } } /** /** Loading @@ -169,27 +170,32 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { Objects.requireNonNull(countryIsoCode); Objects.requireNonNull(countryIsoCode); Objects.requireNonNull(nitzSignal); Objects.requireNonNull(nitzSignal); PhoneTimeZoneSuggestion suggestion = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder suggestionBuilder = suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: countryIsoCode=" + countryIsoCode new PhoneTimeZoneSuggestion.Builder(phoneId); suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz:" + " countryIsoCode=" + countryIsoCode + ", nitzSignal=" + nitzSignal); + ", nitzSignal=" + nitzSignal); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue()); if (isNitzSignalOffsetInfoBogus(countryIsoCode, nitzData)) { if (isNitzSignalOffsetInfoBogus(countryIsoCode, nitzData)) { suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: NITZ signal looks bogus"); suggestionBuilder.addDebugInfo( return suggestion; "findTimeZoneFromCountryAndNitz: NITZ signal looks bogus"); return suggestionBuilder.build(); } } // Try to find a match using both country + NITZ signal. // Try to find a match using both country + NITZ signal. TimeZoneLookupHelper.OffsetResult lookupResult = TimeZoneLookupHelper.OffsetResult lookupResult = mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, countryIsoCode); mTimeZoneLookupHelper.lookupByNitzCountry(nitzData, countryIsoCode); if (lookupResult != null) { if (lookupResult != null) { suggestion.setZoneId(lookupResult.getTimeZone().getID()); suggestionBuilder.setZoneId(lookupResult.getTimeZone().getID()); suggestion.setMatchType(PhoneTimeZoneSuggestion.NETWORK_COUNTRY_AND_OFFSET); suggestionBuilder.setMatchType( PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET); int quality = lookupResult.getIsOnlyMatch() int quality = lookupResult.getIsOnlyMatch() ? PhoneTimeZoneSuggestion.SINGLE_ZONE ? PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE : PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_SAME_OFFSET; : PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET; suggestion.setQuality(quality); suggestionBuilder.setQuality(quality); suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: lookupResult=" + lookupResult); suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz:" return suggestion; + " lookupResult=" + lookupResult); return suggestionBuilder.build(); } } // The country + offset provided no match, so see if the country by itself would be enough. // The country + offset provided no match, so see if the country by itself would be enough. Loading @@ -197,29 +203,29 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { countryIsoCode, nitzData.getCurrentTimeInMillis()); countryIsoCode, nitzData.getCurrentTimeInMillis()); if (countryResult == null) { if (countryResult == null) { // Country not recognized. // Country not recognized. suggestion.addDebugInfo( suggestionBuilder.addDebugInfo( "findTimeZoneFromCountryAndNitz: lookupByCountry() country not recognized"); "findTimeZoneFromCountryAndNitz: lookupByCountry() country not recognized"); return suggestion; return suggestionBuilder.build(); } } // If the country has a single zone, or it has multiple zones but the default zone is // If the country has a single zone, or it has multiple zones but the default zone is // "boosted" (i.e. the country default is considered a good suggestion in most cases) then // "boosted" (i.e. the country default is considered a good suggestion in most cases) then // use it. // use it. if (countryResult.quality == QUALITY_SINGLE_ZONE if (countryResult.quality == CountryResult.QUALITY_SINGLE_ZONE || countryResult.quality == QUALITY_DEFAULT_BOOSTED) { || countryResult.quality == CountryResult.QUALITY_DEFAULT_BOOSTED) { suggestion.setZoneId(countryResult.zoneId); suggestionBuilder.setZoneId(countryResult.zoneId); suggestion.setMatchType(PhoneTimeZoneSuggestion.NETWORK_COUNTRY_ONLY); suggestionBuilder.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY); suggestion.setQuality(PhoneTimeZoneSuggestion.SINGLE_ZONE); suggestionBuilder.setQuality(PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE); suggestion.addDebugInfo( suggestionBuilder.addDebugInfo( "findTimeZoneFromCountryAndNitz: high quality country-only suggestion:" "findTimeZoneFromCountryAndNitz: high quality country-only suggestion:" + " countryResult=" + countryResult); + " countryResult=" + countryResult); return suggestion; return suggestionBuilder.build(); } } // Quality is not high enough to set the zone using country only. // Quality is not high enough to set the zone using country only. suggestion.addDebugInfo("findTimeZoneFromCountryAndNitz: country-only suggestion quality" suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz: country-only suggestion" + " not high enough. countryResult=" + countryResult); + " quality not high enough. countryResult=" + countryResult); return suggestion; return suggestionBuilder.build(); } } /** /** Loading @@ -237,35 +243,39 @@ public class TimeZoneSuggesterImpl implements TimeZoneSuggester { throw new IllegalArgumentException("countryIsoCode must not be empty"); throw new IllegalArgumentException("countryIsoCode must not be empty"); } } PhoneTimeZoneSuggestion result = new PhoneTimeZoneSuggestion(phoneId); PhoneTimeZoneSuggestion.Builder suggestionBuilder = result.addDebugInfo("findTimeZoneFromNetworkCountryCode:" new PhoneTimeZoneSuggestion.Builder(phoneId); suggestionBuilder.addDebugInfo("findTimeZoneFromNetworkCountryCode:" + " whenMillis=" + whenMillis + ", countryIsoCode=" + countryIsoCode); + " whenMillis=" + whenMillis + ", countryIsoCode=" + countryIsoCode); CountryResult lookupResult = mTimeZoneLookupHelper.lookupByCountry( CountryResult lookupResult = mTimeZoneLookupHelper.lookupByCountry( countryIsoCode, whenMillis); countryIsoCode, whenMillis); if (lookupResult != null) { if (lookupResult != null) { result.setZoneId(lookupResult.zoneId); suggestionBuilder.setZoneId(lookupResult.zoneId); result.setMatchType(PhoneTimeZoneSuggestion.NETWORK_COUNTRY_ONLY); suggestionBuilder.setMatchType(PhoneTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY); int quality; int quality; if (lookupResult.quality == QUALITY_SINGLE_ZONE if (lookupResult.quality == CountryResult.QUALITY_SINGLE_ZONE || lookupResult.quality == QUALITY_DEFAULT_BOOSTED) { || lookupResult.quality == CountryResult.QUALITY_DEFAULT_BOOSTED) { quality = PhoneTimeZoneSuggestion.SINGLE_ZONE; quality = PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE; } else if (lookupResult.quality == QUALITY_MULTIPLE_ZONES_SAME_OFFSET) { } else if (lookupResult.quality == CountryResult.QUALITY_MULTIPLE_ZONES_SAME_OFFSET) { quality = PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_SAME_OFFSET; quality = PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET; } else if (lookupResult.quality == QUALITY_MULTIPLE_ZONES_DIFFERENT_OFFSETS) { } else if (lookupResult.quality quality = PhoneTimeZoneSuggestion.MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS; == CountryResult.QUALITY_MULTIPLE_ZONES_DIFFERENT_OFFSETS) { quality = PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS; } else { } else { // This should never happen. // This should never happen. throw new IllegalArgumentException( throw new IllegalArgumentException( "lookupResult.quality not recognized: countryIsoCode=" + countryIsoCode "lookupResult.quality not recognized: countryIsoCode=" + countryIsoCode + ", whenMillis=" + whenMillis + ", lookupResult=" + lookupResult); + ", whenMillis=" + whenMillis + ", lookupResult=" + lookupResult); } } result.setQuality(quality); suggestionBuilder.setQuality(quality); result.addDebugInfo("findTimeZoneFromNetworkCountryCode: lookupResult=" + lookupResult); suggestionBuilder.addDebugInfo( "findTimeZoneFromNetworkCountryCode: lookupResult=" + lookupResult); } else { } else { result.addDebugInfo("findTimeZoneFromNetworkCountryCode: Country not recognized?"); suggestionBuilder.addDebugInfo( "findTimeZoneFromNetworkCountryCode: Country not recognized?"); } } return result; return suggestionBuilder.build(); } } /** /** Loading
src/java/com/android/internal/telephony/nitz/service/PhoneTimeZoneSuggestion.javadeleted 100644 → 0 +0 −254 Original line number Original line Diff line number Diff line /* * 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.telephony.nitz.service; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; /** * A suggested time zone from a Phone-based signal, e.g. from MCC and NITZ information. */ public final class PhoneTimeZoneSuggestion implements Parcelable { public static final Creator<PhoneTimeZoneSuggestion> CREATOR = new Creator<PhoneTimeZoneSuggestion>() { public PhoneTimeZoneSuggestion createFromParcel(Parcel in) { return PhoneTimeZoneSuggestion.createFromParcel(in); } public PhoneTimeZoneSuggestion[] newArray(int size) { return new PhoneTimeZoneSuggestion[size]; } }; /** * Creates an empty time zone suggestion, i.e. one that will cancel previous suggestions with * the same {@code phoneId}. */ @NonNull public static PhoneTimeZoneSuggestion createEmptySuggestion( int phoneId, @NonNull String debugInfo) { PhoneTimeZoneSuggestion timeZoneSuggestion = new PhoneTimeZoneSuggestion(phoneId); timeZoneSuggestion.addDebugInfo(debugInfo); return timeZoneSuggestion; } @IntDef({ MATCH_TYPE_NA, NETWORK_COUNTRY_ONLY, NETWORK_COUNTRY_AND_OFFSET, EMULATOR_ZONE_ID, TEST_NETWORK_OFFSET_ONLY }) @Retention(RetentionPolicy.SOURCE) public @interface MatchType {} /** Used when match type is not applicable. */ public static final int MATCH_TYPE_NA = 0; /** * Only the network country is known. */ public static final int NETWORK_COUNTRY_ONLY = 2; /** * Both the network county and offset were known. */ public static final int NETWORK_COUNTRY_AND_OFFSET = 3; /** * The device is running in an emulator and an NITZ signal was simulated containing an * Android extension with an explicit Olson ID. */ public static final int EMULATOR_ZONE_ID = 4; /** * The phone is most likely running in a test network not associated with a country (this is * distinct from the country just not being known yet). * Historically, Android has just picked an arbitrary time zone with the correct offset when * on a test network. */ public static final int TEST_NETWORK_OFFSET_ONLY = 5; @IntDef({ QUALITY_NA, SINGLE_ZONE, MULTIPLE_ZONES_WITH_SAME_OFFSET, MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS }) @Retention(RetentionPolicy.SOURCE) public @interface Quality {} /** Used when quality is not applicable. */ public static final int QUALITY_NA = 0; /** There is only one answer */ public static final int SINGLE_ZONE = 1; /** * There are multiple answers, but they all shared the same offset / DST state at the time * the suggestion was created. i.e. it might be the wrong zone but the user won't notice * immediately if it is wrong. */ public static final int MULTIPLE_ZONES_WITH_SAME_OFFSET = 2; /** * There are multiple answers with different offsets. The one given is just one possible. */ public static final int MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS = 3; /** * The ID of the phone this suggestion is associated with. For multiple-sim devices this * helps to establish origin so filtering / stickiness can be implemented. */ private final int mPhoneId; /** * The suggestion. {@code null} means there is no current suggestion and any previous suggestion * should be forgotten. */ private String mZoneId; /** * The type of "match" used to establish the time zone. */ @MatchType private int mMatchType; /** * A measure of the quality of the time zone suggestion, i.e. how confident one could be in * it. */ @Quality private int mQuality; /** * Free-form debug information about how the signal was derived. Used for debug only, * intentionally not used in equals(), etc. */ private List<String> mDebugInfo; public PhoneTimeZoneSuggestion(int phoneId) { this.mPhoneId = phoneId; } @SuppressWarnings("unchecked") private static PhoneTimeZoneSuggestion createFromParcel(Parcel in) { int phoneId = in.readInt(); PhoneTimeZoneSuggestion phoneTimeZoneSuggestion = new PhoneTimeZoneSuggestion(phoneId); phoneTimeZoneSuggestion.mZoneId = in.readString(); phoneTimeZoneSuggestion.mMatchType = in.readInt(); phoneTimeZoneSuggestion.mQuality = in.readInt(); phoneTimeZoneSuggestion.mDebugInfo = (List<String>) in.readArrayList(PhoneTimeZoneSuggestion.class.getClassLoader()); return phoneTimeZoneSuggestion; } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mPhoneId); dest.writeString(mZoneId); dest.writeInt(mMatchType); dest.writeInt(mQuality); dest.writeList(mDebugInfo); } @Override public int describeContents() { return 0; } public int getPhoneId() { return mPhoneId; } @Nullable public String getZoneId() { return mZoneId; } public void setZoneId(@Nullable String zoneId) { this.mZoneId = zoneId; } @MatchType public int getMatchType() { return mMatchType; } public void setMatchType(@MatchType int matchType) { this.mMatchType = matchType; } @Quality public int getQuality() { return mQuality; } public void setQuality(@Quality int quality) { this.mQuality = quality; } public List<String> getDebugInfo() { return Collections.unmodifiableList(mDebugInfo); } /** * Associates information with the instance that can be useful for debugging / logging. The * information is present in {@link #toString()} but is not considered for * {@link #equals(Object)} and {@link #hashCode()}. */ public void addDebugInfo(String... debugInfos) { if (mDebugInfo == null) { mDebugInfo = new ArrayList<>(); } mDebugInfo.addAll(Arrays.asList(debugInfos)); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } PhoneTimeZoneSuggestion that = (PhoneTimeZoneSuggestion) o; return mPhoneId == that.mPhoneId && mMatchType == that.mMatchType && mQuality == that.mQuality && Objects.equals(mZoneId, that.mZoneId); } @Override public int hashCode() { return Objects.hash(mPhoneId, mZoneId, mMatchType, mQuality); } @Override public String toString() { return "PhoneTimeZoneSuggestion{" + "mPhoneId=" + mPhoneId + ", mZoneId='" + mZoneId + '\'' + ", mMatchType=" + mMatchType + ", mQuality=" + mQuality + ", mDebugInfo=" + mDebugInfo + '}'; } }