TimeZoneDetectorService浅析--上

时间:2024-01-26 20:45:59

一:问题描述:

客户有一个关闭通话功能的需求,根据MTK的配置方法关闭了大概8个宏开关后,实现通话功能,但是导致插好sim卡开机后,时间和时区不能更新的问题。

二:问题分析:

(1).MTK的日志分析,可以确认为时间已经更新,但是时区确实是没有更新

//收到NITZ

AT      : [0] AT< +CTZEU: "+32",0,"2024/01/23,01:52:53" (RIL_URC_READER, tid:518565289216)
SST     : NITZ: 24/01/23,01:52:53+32,0,39429, ageMs=0 start=41502 delay=2073

//更新时间

NitzStateMachineImpl: doTimeZoneDetection: countryIsoCode=null, nitzSignal=NitzSignal{mReceiptElapsedMillis=PT39.429S, mNitzData=NitzData{mOriginalString=24/01/23,01:52:53+32,0, mZoneOffset=28800000, mDstOffset=0, mCurrentTimeMillis=1705974773000, mEmulatorHostTimeZone=null}, mAgeMillis=0}, suggestion=TelephonyTimeZoneSuggestion{mSlotIndex=0, mZoneId='null', mMatchType=0, mQuality=0, mDebugInfo=[getTimeZoneSuggestion: nitzSignal=NitzSignal{mReceiptElapsedMillis=PT39.429S, mNitzData=NitzData{mOriginalString=24/01/23,01:52:53+32,0, mZoneOffset=28800000, mDstOffset=0, mCurrentTimeMillis=1705974773000, mEmulatorHostTimeZone=null}, mAgeMillis=0}, countryIsoCode=null, Detection reason=handleNitzReceived(NitzSignal{mReceiptElapsedMillis=PT39.429S, mNitzData=NitzData{mOriginalString=24/01/23,01:52:53+32,0, mZoneOffset=28800000, mDstOffset=0, mCurrentTimeMillis=1705974773000, mEmulatorHostTimeZone=null}, mAgeMillis=0})]}, reason=handleNitzReceived(NitzSignal{mReceiptElapsedMillis=PT39.429S, mNitzData=NitzData{mOriginalString=24/01/23,01:52:53+32,0, mZoneOffset=28800000, mDstOffset=0, mCurrentTimeMillis=1705974773000, mEmulatorHostTimeZone=null}, mAgeMillis=0})
AlarmManagerService: Setting time of day to sec=1705974775

//detect timezone, 但是没有更新时区

NitzStateMachineImpl: doTimeZoneDetection: countryIsoCode=cn, nitzSignal=NitzSignal{mReceiptElapsedMillis=PT39.429S, mNitzData=NitzData{mOriginalString=24/01/23,01:52:53+32,0, mZoneOffset=28800000, mDstOffset=0, mCurrentTimeMillis=1705974773000, mEmulatorHostTimeZone=null}, mAgeMillis=0}, suggestion=TelephonyTimeZoneSuggestion{mSlotIndex=0, mZoneId='Asia/Shanghai', mMatchType=3, mQuality=1, mDebugInfo=[findTimeZoneFromCountryAndNitz: countryIsoCode=cn, nitzSignal=NitzSignal{mReceiptElapsedMillis=PT39.429S, mNitzData=NitzData{mOriginalString=24/01/23,01:52:53+32,0, mZoneOffset=28800000, mDstOffset=0, mCurrentTimeMillis=1705974773000, mEmulatorHostTimeZone=null}, mAgeMillis=0}, findTimeZoneFromCountryAndNitz: lookupResult=OffsetResult{mTimeZone(ID)=Asia/Shanghai, mIsOnlyMatch=true}, Detection reason=handleCountryDetected("cn")]}, reason=handleCountryDetected("cn")

(2).分析bugreport日志:

可以确定时区识别策略已经通过Telephony suggestion history成功的识别到了Asia/Shanghai,但是为什么没有更新时区,原因未知。

TimeZoneDetectorService浅析--上_framework

其实上面的数据,我们也可以看出时区的更新和三个有关:

(一):Manual

(二):Geolocation

(三):Telephony


(3).添加日志分析

我在TimeZoneDetectorStrategyImpl.doAutoTimeZoneDetection添加相关的日志,

Slog.d(LOG_TAG, "doAutoTimeZoneDetection currentUserConfig.getDetectionMode()=" + currentUserConfig.getDetectionMode());

发现其返回的识别模式为DETECTION_MODE_MANUAL:

time_zone_detector: doAutoTimeZoneDetection currentUserConfig.getDetectionMode()=1

time_zone_detector: doAutoTimeZoneDetection currentUserConfig.getDetectionMode()=1

private void doAutoTimeZoneDetection(
        @NonNull ConfigurationInternal currentUserConfig, @NonNull String detectionReason) {
    // Use the correct algorithm based on the user's current configuration. If it changes, then
    // detection will be re-run.
    Slog.d(LOG_TAG, "doAutoTimeZoneDetection currentUserConfig.getDetectionMode()=" + currentUserConfig.getDetectionMode());
    switch (currentUserConfig.getDetectionMode()) {
        case ConfigurationInternal.DETECTION_MODE_MANUAL:
            // No work to do.
            break;

那为什么明明是Telephony,返回是Manual呢?

进一步追踪代码,发现ConfigurationInternal.getDetectionMode():

应该是mTelephonyDetectionSupported为false,返回值为false,导致最后返回类型为manual,确实是我们关闭通话导致的。

public @DetectionMode int getDetectionMode() {
    if (!getAutoDetectionEnabledBehavior()) {
        return DETECTION_MODE_MANUAL;//返回为manual
    } else if (isGeoDetectionSupported() && getLocationEnabledSetting()
            && getGeoDetectionEnabledSetting()) {
        return DETECTION_MODE_GEO;
    } else {
        return DETECTION_MODE_TELEPHONY;
    }
}

public boolean getAutoDetectionEnabledBehavior() {
    return isAutoDetectionSupported() && mAutoDetectionEnabledSetting;
}

public boolean isAutoDetectionSupported() {
    return mTelephonyDetectionSupported || mGeoDetectionSupported;
    //应该是mTelephonyDetectionSupported为false,返回值为false,导致最后返回类型为manual
    //确实是我们关闭通话导致的。
}


三:问题解决

原因定位到了,那解决方案就好定了。

我们针对关闭通话的情况,进行适配处理一下,强行更新时区或强行修改返回类型都可以。