diff options
author | Andrew Lee <anwlee@google.com> | 2015-06-05 15:13:38 -0700 |
---|---|---|
committer | Andrew Lee <anwlee@google.com> | 2015-06-05 18:34:37 -0700 |
commit | 46e7fbc485dd15a6c627497f121f60798d62cf80 (patch) | |
tree | 704c3c2918246e806ff66cbeef1a36ba42a2c896 /src/com/android/dialer | |
parent | 6406d98f10d6e74492e7cc47bd6f5c6c5fbb6fdf (diff) |
Handle FetchResultHandler race condition.
Previously, the voicemail only needed to be looked up once, but now
a single presenter may load multiple voicemails. As such, destroy
the old FetchResultHandler if one already exists.
Bug: 21663448
Change-Id: Ibdb08f03760b770d0800bd44d4cdcf0ca7c57fc9
Diffstat (limited to 'src/com/android/dialer')
-rw-r--r-- | src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java index 1a1547692..f06840139 100644 --- a/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java +++ b/src/com/android/dialer/voicemail/VoicemailPlaybackPresenter.java @@ -141,6 +141,7 @@ public class VoicemailPlaybackPresenter * This variable is thread-contained, accessed only on the ui thread. */ private FetchResultHandler mFetchResultHandler; + private Handler mHandler = new Handler(); private PowerManager.WakeLock mProximityWakeLock; private AudioManager mAudioManager; @@ -298,13 +299,12 @@ public class VoicemailPlaybackPresenter * was not available. */ private void requestContent() { - Preconditions.checkState(mFetchResultHandler == null, "mFetchResultHandler should be null"); + if (mFetchResultHandler != null) { + mFetchResultHandler.destroy(); + } - Handler handler = new Handler(); - mFetchResultHandler = new FetchResultHandler(handler); - mContext.getContentResolver().registerContentObserver( - mVoicemailUri, false, mFetchResultHandler); - handler.postDelayed(mFetchResultHandler.getTimeoutRunnable(), FETCH_CONTENT_TIMEOUT_MS); + mFetchResultHandler = new FetchResultHandler(new Handler()); + mFetchResultHandler.registerContentObserver(mVoicemailUri); // Send voicemail fetch request. Intent intent = new Intent(VoicemailContract.ACTION_FETCH_VOICEMAIL, mVoicemailUri); @@ -313,30 +313,37 @@ public class VoicemailPlaybackPresenter @ThreadSafe private class FetchResultHandler extends ContentObserver implements Runnable { - private AtomicBoolean mResultStillPending = new AtomicBoolean(true); - private final Handler mHandler; + private AtomicBoolean mIsWaitingForResult = new AtomicBoolean(true); + private final Handler mFetchResultHandler; public FetchResultHandler(Handler handler) { super(handler); - mHandler = handler; + mFetchResultHandler = handler; } - public Runnable getTimeoutRunnable() { - return this; + public void registerContentObserver(Uri voicemailUri) { + if (mIsWaitingForResult.get()) { + mContext.getContentResolver().registerContentObserver( + voicemailUri, false, this); + mFetchResultHandler.postDelayed(this, FETCH_CONTENT_TIMEOUT_MS); + } } + /** + * Stop waiting for content and notify UI if {@link FETCH_CONTENT_TIMEOUT_MS} has elapsed. + */ @Override public void run() { - if (mResultStillPending.getAndSet(false)) { - mContext.getContentResolver().unregisterContentObserver(FetchResultHandler.this); + if (mIsWaitingForResult.getAndSet(false)) { + mContext.getContentResolver().unregisterContentObserver(this); mView.setFetchContentTimeout(); } } public void destroy() { - if (mResultStillPending.getAndSet(false)) { - mContext.getContentResolver().unregisterContentObserver(FetchResultHandler.this); - mHandler.removeCallbacks(this); + if (mIsWaitingForResult.getAndSet(false)) { + mContext.getContentResolver().unregisterContentObserver(this); + mFetchResultHandler.removeCallbacks(this); } } @@ -352,7 +359,7 @@ public class VoicemailPlaybackPresenter @Override public void onPostExecute(Boolean hasContent) { if (hasContent) { - if (mResultStillPending.getAndSet(false)) { + if (mIsWaitingForResult.getAndSet(false)) { mContext.getContentResolver().unregisterContentObserver( FetchResultHandler.this); prepareToPlayContent(); |