Home | History | Annotate | Download | only in audioflinger
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 // <IMPORTANT_WARNING>
     18 // Design rules for threadLoop() are given in the comments at section "Fast mixer thread" of
     19 // StateQueue.h.  In particular, avoid library and system calls except at well-known points.
     20 // The design rules are only for threadLoop(), and don't apply to FastMixerDumpState methods.
     21 // </IMPORTANT_WARNING>
     22 
     23 #define LOG_TAG "FastMixer"
     24 //#define LOG_NDEBUG 0
     25 
     26 #define ATRACE_TAG ATRACE_TAG_AUDIO
     27 
     28 #include "Configuration.h"
     29 #include <time.h>
     30 #include <utils/Debug.h>
     31 #include <utils/Log.h>
     32 #include <utils/Trace.h>
     33 #include <system/audio.h>
     34 #ifdef FAST_THREAD_STATISTICS
     35 #include <cpustats/CentralTendencyStatistics.h>
     36 #ifdef CPU_FREQUENCY_STATISTICS
     37 #include <cpustats/ThreadCpuUsage.h>
     38 #endif
     39 #endif
     40 #include <audio_utils/mono_blend.h>
     41 #include <audio_utils/format.h>
     42 #include <media/AudioMixer.h>
     43 #include "FastMixer.h"
     44 #include "TypedLogger.h"
     45 
     46 namespace android {
     47 
     48 /*static*/ const FastMixerState FastMixer::sInitial;
     49 
     50 FastMixer::FastMixer() : FastThread("cycle_ms", "load_us"),
     51     // mFastTrackNames
     52     // mGenerations
     53     mOutputSink(NULL),
     54     mOutputSinkGen(0),
     55     mMixer(NULL),
     56     mSinkBuffer(NULL),
     57     mSinkBufferSize(0),
     58     mSinkChannelCount(FCC_2),
     59     mMixerBuffer(NULL),
     60     mMixerBufferSize(0),
     61     mMixerBufferFormat(AUDIO_FORMAT_PCM_16_BIT),
     62     mMixerBufferState(UNDEFINED),
     63     mFormat(Format_Invalid),
     64     mSampleRate(0),
     65     mFastTracksGen(0),
     66     mTotalNativeFramesWritten(0),
     67     // timestamp
     68     mNativeFramesWrittenButNotPresented(0),   // the = 0 is to silence the compiler
     69     mMasterMono(false)
     70 {
     71     // FIXME pass sInitial as parameter to base class constructor, and make it static local
     72     mPrevious = &sInitial;
     73     mCurrent = &sInitial;
     74 
     75     mDummyDumpState = &mDummyFastMixerDumpState;
     76     // TODO: Add channel mask to NBAIO_Format.
     77     // We assume that the channel mask must be a valid positional channel mask.
     78     mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
     79 
     80     unsigned i;
     81     for (i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
     82         mFastTrackNames[i] = -1;
     83         mGenerations[i] = 0;
     84     }
     85 #ifdef FAST_THREAD_STATISTICS
     86     mOldLoad.tv_sec = 0;
     87     mOldLoad.tv_nsec = 0;
     88 #endif
     89 }
     90 
     91 FastMixer::~FastMixer()
     92 {
     93 }
     94 
     95 FastMixerStateQueue* FastMixer::sq()
     96 {
     97     return &mSQ;
     98 }
     99 
    100 const FastThreadState *FastMixer::poll()
    101 {
    102     return mSQ.poll();
    103 }
    104 
    105 void FastMixer::setNBLogWriter(NBLog::Writer *logWriter)
    106 {
    107     // FIXME If mMixer is set or changed prior to this, we don't inform correctly.
    108     //       Should cache logWriter and re-apply it at the assignment to mMixer.
    109     if (mMixer != NULL) {
    110         mMixer->setNBLogWriter(logWriter);
    111     }
    112 }
    113 
    114 void FastMixer::onIdle()
    115 {
    116     mPreIdle = *(const FastMixerState *)mCurrent;
    117     mCurrent = &mPreIdle;
    118 }
    119 
    120 void FastMixer::onExit()
    121 {
    122     delete mMixer;
    123     free(mMixerBuffer);
    124     free(mSinkBuffer);
    125 }
    126 
    127 bool FastMixer::isSubClassCommand(FastThreadState::Command command)
    128 {
    129     switch ((FastMixerState::Command) command) {
    130     case FastMixerState::MIX:
    131     case FastMixerState::WRITE:
    132     case FastMixerState::MIX_WRITE:
    133         return true;
    134     default:
    135         return false;
    136     }
    137 }
    138 
    139 void FastMixer::onStateChange()
    140 {
    141     // log that audio was turned on/off
    142     LOG_AUDIO_STATE();
    143     const FastMixerState * const current = (const FastMixerState *) mCurrent;
    144     const FastMixerState * const previous = (const FastMixerState *) mPrevious;
    145     FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
    146     const size_t frameCount = current->mFrameCount;
    147 
    148     // update boottime offset, in case it has changed
    149     mTimestamp.mTimebaseOffset[ExtendedTimestamp::TIMEBASE_BOOTTIME] =
    150             mBoottimeOffset.load();
    151 
    152     // handle state change here, but since we want to diff the state,
    153     // we're prepared for previous == &sInitial the first time through
    154     unsigned previousTrackMask;
    155 
    156     // check for change in output HAL configuration
    157     NBAIO_Format previousFormat = mFormat;
    158     if (current->mOutputSinkGen != mOutputSinkGen) {
    159         mOutputSink = current->mOutputSink;
    160         mOutputSinkGen = current->mOutputSinkGen;
    161         if (mOutputSink == NULL) {
    162             mFormat = Format_Invalid;
    163             mSampleRate = 0;
    164             mSinkChannelCount = 0;
    165             mSinkChannelMask = AUDIO_CHANNEL_NONE;
    166         } else {
    167             mFormat = mOutputSink->format();
    168             mSampleRate = Format_sampleRate(mFormat);
    169             mSinkChannelCount = Format_channelCount(mFormat);
    170             LOG_ALWAYS_FATAL_IF(mSinkChannelCount > AudioMixer::MAX_NUM_CHANNELS);
    171 
    172             // TODO: Add channel mask to NBAIO_Format
    173             // We assume that the channel mask must be a valid positional channel mask.
    174             mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
    175         }
    176         dumpState->mSampleRate = mSampleRate;
    177     }
    178 
    179     if ((!Format_isEqual(mFormat, previousFormat)) || (frameCount != previous->mFrameCount)) {
    180         // FIXME to avoid priority inversion, don't delete here
    181         delete mMixer;
    182         mMixer = NULL;
    183         free(mMixerBuffer);
    184         mMixerBuffer = NULL;
    185         free(mSinkBuffer);
    186         mSinkBuffer = NULL;
    187         if (frameCount > 0 && mSampleRate > 0) {
    188             // The mixer produces either 16 bit PCM or float output, select
    189             // float output if the HAL supports higher than 16 bit precision.
    190             mMixerBufferFormat = mFormat.mFormat == AUDIO_FORMAT_PCM_16_BIT ?
    191                     AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_FLOAT;
    192             // FIXME new may block for unbounded time at internal mutex of the heap
    193             //       implementation; it would be better to have normal mixer allocate for us
    194             //       to avoid blocking here and to prevent possible priority inversion
    195             mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::sMaxFastTracks);
    196             // FIXME See the other FIXME at FastMixer::setNBLogWriter()
    197             const size_t mixerFrameSize = mSinkChannelCount
    198                     * audio_bytes_per_sample(mMixerBufferFormat);
    199             mMixerBufferSize = mixerFrameSize * frameCount;
    200             (void)posix_memalign(&mMixerBuffer, 32, mMixerBufferSize);
    201             const size_t sinkFrameSize = mSinkChannelCount
    202                     * audio_bytes_per_sample(mFormat.mFormat);
    203             if (sinkFrameSize > mixerFrameSize) { // need a sink buffer
    204                 mSinkBufferSize = sinkFrameSize * frameCount;
    205                 (void)posix_memalign(&mSinkBuffer, 32, mSinkBufferSize);
    206             }
    207             mPeriodNs = (frameCount * 1000000000LL) / mSampleRate;    // 1.00
    208             mUnderrunNs = (frameCount * 1750000000LL) / mSampleRate;  // 1.75
    209             mOverrunNs = (frameCount * 500000000LL) / mSampleRate;    // 0.50
    210             mForceNs = (frameCount * 950000000LL) / mSampleRate;      // 0.95
    211             mWarmupNsMin = (frameCount * 750000000LL) / mSampleRate;  // 0.75
    212             mWarmupNsMax = (frameCount * 1250000000LL) / mSampleRate; // 1.25
    213         } else {
    214             mPeriodNs = 0;
    215             mUnderrunNs = 0;
    216             mOverrunNs = 0;
    217             mForceNs = 0;
    218             mWarmupNsMin = 0;
    219             mWarmupNsMax = LONG_MAX;
    220         }
    221         mMixerBufferState = UNDEFINED;
    222 #if !LOG_NDEBUG
    223         for (unsigned i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
    224             mFastTrackNames[i] = -1;
    225         }
    226 #endif
    227         // we need to reconfigure all active tracks
    228         previousTrackMask = 0;
    229         mFastTracksGen = current->mFastTracksGen - 1;
    230         dumpState->mFrameCount = frameCount;
    231     } else {
    232         previousTrackMask = previous->mTrackMask;
    233     }
    234 
    235     // check for change in active track set
    236     const unsigned currentTrackMask = current->mTrackMask;
    237     dumpState->mTrackMask = currentTrackMask;
    238     if (current->mFastTracksGen != mFastTracksGen) {
    239         ALOG_ASSERT(mMixerBuffer != NULL);
    240         int name;
    241 
    242         // process removed tracks first to avoid running out of track names
    243         unsigned removedTracks = previousTrackMask & ~currentTrackMask;
    244         while (removedTracks != 0) {
    245             int i = __builtin_ctz(removedTracks);
    246             removedTracks &= ~(1 << i);
    247             const FastTrack* fastTrack = &current->mFastTracks[i];
    248             ALOG_ASSERT(fastTrack->mBufferProvider == NULL);
    249             if (mMixer != NULL) {
    250                 name = mFastTrackNames[i];
    251                 ALOG_ASSERT(name >= 0);
    252                 mMixer->deleteTrackName(name);
    253             }
    254 #if !LOG_NDEBUG
    255             mFastTrackNames[i] = -1;
    256 #endif
    257             // don't reset track dump state, since other side is ignoring it
    258             mGenerations[i] = fastTrack->mGeneration;
    259         }
    260 
    261         // now process added tracks
    262         unsigned addedTracks = currentTrackMask & ~previousTrackMask;
    263         while (addedTracks != 0) {
    264             int i = __builtin_ctz(addedTracks);
    265             addedTracks &= ~(1 << i);
    266             const FastTrack* fastTrack = &current->mFastTracks[i];
    267             AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
    268             ALOG_ASSERT(bufferProvider != NULL && mFastTrackNames[i] == -1);
    269             if (mMixer != NULL) {
    270                 name = mMixer->getTrackName(fastTrack->mChannelMask,
    271                         fastTrack->mFormat, AUDIO_SESSION_OUTPUT_MIX);
    272                 ALOG_ASSERT(name >= 0);
    273                 mFastTrackNames[i] = name;
    274                 mMixer->setBufferProvider(name, bufferProvider);
    275                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
    276                         (void *)mMixerBuffer);
    277                 // newly allocated track names default to full scale volume
    278                 mMixer->setParameter(
    279                         name,
    280                         AudioMixer::TRACK,
    281                         AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
    282                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
    283                         (void *)(uintptr_t)fastTrack->mFormat);
    284                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
    285                         (void *)(uintptr_t)fastTrack->mChannelMask);
    286                 mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
    287                         (void *)(uintptr_t)mSinkChannelMask);
    288                 mMixer->enable(name);
    289             }
    290             mGenerations[i] = fastTrack->mGeneration;
    291         }
    292 
    293         // finally process (potentially) modified tracks; these use the same slot
    294         // but may have a different buffer provider or volume provider
    295         unsigned modifiedTracks = currentTrackMask & previousTrackMask;
    296         while (modifiedTracks != 0) {
    297             int i = __builtin_ctz(modifiedTracks);
    298             modifiedTracks &= ~(1 << i);
    299             const FastTrack* fastTrack = &current->mFastTracks[i];
    300             if (fastTrack->mGeneration != mGenerations[i]) {
    301                 // this track was actually modified
    302                 AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
    303                 ALOG_ASSERT(bufferProvider != NULL);
    304                 if (mMixer != NULL) {
    305                     name = mFastTrackNames[i];
    306                     ALOG_ASSERT(name >= 0);
    307                     mMixer->setBufferProvider(name, bufferProvider);
    308                     if (fastTrack->mVolumeProvider == NULL) {
    309                         float f = AudioMixer::UNITY_GAIN_FLOAT;
    310                         mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &f);
    311                         mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &f);
    312                     }
    313                     mMixer->setParameter(name, AudioMixer::RESAMPLE,
    314                             AudioMixer::REMOVE, NULL);
    315                     mMixer->setParameter(
    316                             name,
    317                             AudioMixer::TRACK,
    318                             AudioMixer::MIXER_FORMAT, (void *)mMixerBufferFormat);
    319                     mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FORMAT,
    320                             (void *)(uintptr_t)fastTrack->mFormat);
    321                     mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
    322                             (void *)(uintptr_t)fastTrack->mChannelMask);
    323                     mMixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MIXER_CHANNEL_MASK,
    324                             (void *)(uintptr_t)mSinkChannelMask);
    325                     // already enabled
    326                 }
    327                 mGenerations[i] = fastTrack->mGeneration;
    328             }
    329         }
    330 
    331         mFastTracksGen = current->mFastTracksGen;
    332 
    333         dumpState->mNumTracks = popcount(currentTrackMask);
    334     }
    335 }
    336 
    337 void FastMixer::onWork()
    338 {
    339     LOG_HIST_TS();
    340     const FastMixerState * const current = (const FastMixerState *) mCurrent;
    341     FastMixerDumpState * const dumpState = (FastMixerDumpState *) mDumpState;
    342     const FastMixerState::Command command = mCommand;
    343     const size_t frameCount = current->mFrameCount;
    344 
    345     if ((command & FastMixerState::MIX) && (mMixer != NULL) && mIsWarm) {
    346         ALOG_ASSERT(mMixerBuffer != NULL);
    347 
    348         // AudioMixer::mState.enabledTracks is undefined if mState.hook == process__validate,
    349         // so we keep a side copy of enabledTracks
    350         bool anyEnabledTracks = false;
    351 
    352         // for each track, update volume and check for underrun
    353         unsigned currentTrackMask = current->mTrackMask;
    354         while (currentTrackMask != 0) {
    355             int i = __builtin_ctz(currentTrackMask);
    356             currentTrackMask &= ~(1 << i);
    357             const FastTrack* fastTrack = &current->mFastTracks[i];
    358 
    359             const int64_t trackFramesWrittenButNotPresented =
    360                 mNativeFramesWrittenButNotPresented;
    361             const int64_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
    362             ExtendedTimestamp perTrackTimestamp(mTimestamp);
    363 
    364             // Can't provide an ExtendedTimestamp before first frame presented.
    365             // Also, timestamp may not go to very last frame on stop().
    366             if (trackFramesWritten >= trackFramesWrittenButNotPresented &&
    367                     perTrackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] > 0) {
    368                 perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
    369                         trackFramesWritten - trackFramesWrittenButNotPresented;
    370             } else {
    371                 perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
    372                 perTrackTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
    373             }
    374             perTrackTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = trackFramesWritten;
    375             fastTrack->mBufferProvider->onTimestamp(perTrackTimestamp);
    376 
    377             int name = mFastTrackNames[i];
    378             ALOG_ASSERT(name >= 0);
    379             if (fastTrack->mVolumeProvider != NULL) {
    380                 gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
    381                 float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
    382                 float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
    383 
    384                 mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &vlf);
    385                 mMixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &vrf);
    386             }
    387             // FIXME The current implementation of framesReady() for fast tracks
    388             // takes a tryLock, which can block
    389             // up to 1 ms.  If enough active tracks all blocked in sequence, this would result
    390             // in the overall fast mix cycle being delayed.  Should use a non-blocking FIFO.
    391             size_t framesReady = fastTrack->mBufferProvider->framesReady();
    392             if (ATRACE_ENABLED()) {
    393                 // I wish we had formatted trace names
    394                 char traceName[16];
    395                 strcpy(traceName, "fRdy");
    396                 traceName[4] = i + (i < 10 ? '0' : 'A' - 10);
    397                 traceName[5] = '\0';
    398                 ATRACE_INT(traceName, framesReady);
    399             }
    400             FastTrackDump *ftDump = &dumpState->mTracks[i];
    401             FastTrackUnderruns underruns = ftDump->mUnderruns;
    402             if (framesReady < frameCount) {
    403                 if (framesReady == 0) {
    404                     underruns.mBitFields.mEmpty++;
    405                     underruns.mBitFields.mMostRecent = UNDERRUN_EMPTY;
    406                     mMixer->disable(name);
    407                 } else {
    408                     // allow mixing partial buffer
    409                     underruns.mBitFields.mPartial++;
    410                     underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
    411                     mMixer->enable(name);
    412                     anyEnabledTracks = true;
    413                 }
    414             } else {
    415                 underruns.mBitFields.mFull++;
    416                 underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
    417                 mMixer->enable(name);
    418                 anyEnabledTracks = true;
    419             }
    420             ftDump->mUnderruns = underruns;
    421             ftDump->mFramesReady = framesReady;
    422             ftDump->mFramesWritten = trackFramesWritten;
    423         }
    424 
    425         if (anyEnabledTracks) {
    426             // process() is CPU-bound
    427             mMixer->process();
    428             mMixerBufferState = MIXED;
    429         } else if (mMixerBufferState != ZEROED) {
    430             mMixerBufferState = UNDEFINED;
    431         }
    432 
    433     } else if (mMixerBufferState == MIXED) {
    434         mMixerBufferState = UNDEFINED;
    435     }
    436     //bool didFullWrite = false;    // dumpsys could display a count of partial writes
    437     if ((command & FastMixerState::WRITE) && (mOutputSink != NULL) && (mMixerBuffer != NULL)) {
    438         if (mMixerBufferState == UNDEFINED) {
    439             memset(mMixerBuffer, 0, mMixerBufferSize);
    440             mMixerBufferState = ZEROED;
    441         }
    442 
    443         if (mMasterMono.load()) {  // memory_order_seq_cst
    444             mono_blend(mMixerBuffer, mMixerBufferFormat, Format_channelCount(mFormat), frameCount,
    445                     true /*limit*/);
    446         }
    447         // prepare the buffer used to write to sink
    448         void *buffer = mSinkBuffer != NULL ? mSinkBuffer : mMixerBuffer;
    449         if (mFormat.mFormat != mMixerBufferFormat) { // sink format not the same as mixer format
    450             memcpy_by_audio_format(buffer, mFormat.mFormat, mMixerBuffer, mMixerBufferFormat,
    451                     frameCount * Format_channelCount(mFormat));
    452         }
    453         // if non-NULL, then duplicate write() to this non-blocking sink
    454         NBAIO_Sink* teeSink;
    455         if ((teeSink = current->mTeeSink) != NULL) {
    456             (void) teeSink->write(buffer, frameCount);
    457         }
    458         // FIXME write() is non-blocking and lock-free for a properly implemented NBAIO sink,
    459         //       but this code should be modified to handle both non-blocking and blocking sinks
    460         dumpState->mWriteSequence++;
    461         ATRACE_BEGIN("write");
    462         ssize_t framesWritten = mOutputSink->write(buffer, frameCount);
    463         ATRACE_END();
    464         dumpState->mWriteSequence++;
    465         if (framesWritten >= 0) {
    466             ALOG_ASSERT((size_t) framesWritten <= frameCount);
    467             mTotalNativeFramesWritten += framesWritten;
    468             dumpState->mFramesWritten = mTotalNativeFramesWritten;
    469             //if ((size_t) framesWritten == frameCount) {
    470             //    didFullWrite = true;
    471             //}
    472         } else {
    473             dumpState->mWriteErrors++;
    474         }
    475         mAttemptedWrite = true;
    476         // FIXME count # of writes blocked excessively, CPU usage, etc. for dump
    477 
    478         ExtendedTimestamp timestamp; // local
    479         status_t status = mOutputSink->getTimestamp(timestamp);
    480         if (status == NO_ERROR) {
    481             const int64_t totalNativeFramesPresented =
    482                     timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
    483             if (totalNativeFramesPresented <= mTotalNativeFramesWritten) {
    484                 mNativeFramesWrittenButNotPresented =
    485                     mTotalNativeFramesWritten - totalNativeFramesPresented;
    486                 mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] =
    487                         timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL];
    488                 mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] =
    489                         timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
    490             } else {
    491                 // HAL reported that more frames were presented than were written
    492                 mNativeFramesWrittenButNotPresented = 0;
    493                 status = INVALID_OPERATION;
    494             }
    495         }
    496         if (status == NO_ERROR) {
    497             mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
    498                     mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL];
    499         } else {
    500             // fetch server time if we can't get timestamp
    501             mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] =
    502                     systemTime(SYSTEM_TIME_MONOTONIC);
    503             // clear out kernel cached position as this may get rapidly stale
    504             // if we never get a new valid timestamp
    505             mTimestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL] = 0;
    506             mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = -1;
    507         }
    508     }
    509 }
    510 
    511 }   // namespace android
    512