基于SnapDragonBoard410cNTP的理解

Android 启动SystemServer的时候,SystemServer的run中:

ActivityManagerService.self().systemReady(new Runnable() {
            public void run() {
                try {
                    if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemReady();
                } catch (Throwable e) {
                    reportWtf("making Network Time Service ready", e);
                }
...
}

再来看看NetworkTimeUpdateService中的相关代码:
systemReady

public void systemReady() {  
        registerForTelephonyIntents();  
//注册定时器广播  
        registerForAlarms();  
//注册网络连接消息广播  
        registerForConnectivityIntents();  
//创建用于接收NTP请求事件的HandlerThread  
//用于处理:  
//            EVENT_AUTO_TIME_CHANGED:  
//            EVENT_POLL_NETWORK_TIME:  
//            EVENT_NETWORK_CONNECTED:  
//三个消息  
        mThread = new HandlerThread(TAG);  
        mThread.start();  
        mHandler = new MyHandler(mThread.getLooper());  
        // Check the network time on the new thread  
//发送请求NTP时间消息          
        mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget();  
//添加一个用于监听设置中时间改变消息通知  
        mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED);  
        mSettingsObserver.observe(mContext);  
    }  

MyHandler

/** Handler to do the network accesses on */  
private class MyHandler extends Handler {  

    public MyHandler(Looper l) {  
        super(l);  
    }  

    @Override  
    public void handleMessage(Message msg) {  
        switch (msg.what) {  
            case EVENT_AUTO_TIME_CHANGED:  
            case EVENT_POLL_NETWORK_TIME:  
            case EVENT_NETWORK_CONNECTED:  
                onPollNetworkTime(msg.what);  
                break;  
        }  
    }  
}  

重点来看看onPollNetworkTime这个函数:

在看这个函数之前先来理解几个相关变量,理解了这几个变量之后,该函数就比较好理解了。
在NetworkTimeUpdateService的构造函数中:

public NetworkTimeUpdateService(Context context) {  
    mContext = context;  
    mTime = NtpTrustedTime.getInstance(context);  
    mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);  
    Intent pollIntent = new Intent(ACTION_POLL, null);  
    mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0);  

    mPollingIntervalMs = mContext.getResources().getInteger(  
            com.android.internal.R.integer.config_ntpPollingInterval);  
    mPollingIntervalShorterMs = mContext.getResources().getInteger(  
            com.android.internal.R.integer.config_ntpPollingIntervalShorter);  
    mTryAgainTimesMax = mContext.getResources().getInteger(  
            com.android.internal.R.integer.config_ntpRetry);  
    mTimeErrorThresholdMs = mContext.getResources().getInteger(  
            com.android.internal.R.integer.config_ntpThreshold);  
}  

几个关键的变量:
mPollingIntervalMs
当NTP时间获取成功后,再次请求NTP时间的间隔
mPollingIntervalShorterMs
当NTP时间获取失败后,再次请求NTP时间的间隔
mTimeErrorThresholdMs
当NTP时间和系统时间不相同时,要更新系统时间的阀值
这几个变量的值是通过资源文件里读取的,配置的地址为config.xml,来看看相关的内容:

<!-- Remote server that can provide NTP responses. -->  
0.android.pool.ntp.org<!-- Normal polling frequency in milliseconds -->864000000<!-- Try-again polling interval in milliseconds, in case the network request failed -->5000<!-- Number of times to try again with the shorter interval, before backing  
     off until the normal polling interval. A value < 0 indicates infinite. -->-1<!-- If the time difference is greater than this threshold in milliseconds,  
     then update the time. -->5000<!-- Timeout to wait for NTP server response. -->20000  

其实只要看下注释这几个变量的功能就清楚了,可见注释是多么的重要,如果要自己看代码理解的话,可能要花比较多的时间。

好,最后来看下onPollNetworkTime的代码:

private void onPollNetworkTime(int event) {  
    // If Automatic time is not set, don't bother.  
    if (!isAutomaticTimeRequested()) return;  

    final long refTime = SystemClock.elapsedRealtime();  
    // If NITZ time was received less than mPollingIntervalMs time ago,  
    // no need to sync to NTP.  
    if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) {  
        resetAlarm(mPollingIntervalMs);  
        return;  
    }  
    final long currentTime = System.currentTimeMillis();  
    if (DBG) Log.d(TAG, "System time = " + currentTime);  
    // Get the NTP time  
    if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs  
            || event == EVENT_AUTO_TIME_CHANGED) {  
        if (DBG) Log.d(TAG, "Before Ntp fetch");  
        // force refresh NTP cache when outdated  
      //如果没有获取过NTP时间或者系统时间距离最后一次获取NTP时间超过了mPollingIntervalMs,就去请求NTP时间  
        if (mTime.getCacheAge() >= mPollingIntervalMs) {  
            mTime.forceRefresh();  
        }  
        // only update when NTP time is fresh  
        if (mTime.getCacheAge() < mPollingIntervalMs) {  
            final long ntp = mTime.currentTimeMillis();  
            mTryAgainCounter = 0;  
            // If the clock is more than N seconds off or this is the first time it's been  
            // fetched since boot, set the current time.  
            if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs  
                    || mLastNtpFetchTime == NOT_SET) {  
                // Set the system time  
                if (DBG && mLastNtpFetchTime == NOT_SET  
                        && Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) {  
                    Log.d(TAG, "For initial setup, rtc = " + currentTime);  
                }  
                if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp);  
                // Make sure we don't overflow, since it's going to be converted to an int  
                if (ntp / 1000 < Integer.MAX_VALUE) {  
                    SystemClock.setCurrentTimeMillis(ntp);  
                }  
            } else {  
                if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp);  
            }  
            mLastNtpFetchTime = SystemClock.elapsedRealtime();  
        } else {  
            // Try again shortly  
            mTryAgainCounter++;  
            if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) {  
                resetAlarm(mPollingIntervalShorterMs);  
            } else {  
                // Try much later  
                mTryAgainCounter = 0;  
                resetAlarm(mPollingIntervalMs);  
            }  
            return;  
        }  
    }  
    resetAlarm(mPollingIntervalMs);  
}  

猜你喜欢

转载自blog.csdn.net/u013763766/article/details/78803611