Merge "Fix 3106227: use WeakReferences for receivers in DigitalClock class" into gingerbread
This commit is contained in:
@@ -22,7 +22,6 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -33,6 +32,7 @@ import android.view.View;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.text.DateFormatSymbols;
|
import java.text.DateFormatSymbols;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
@@ -49,26 +49,41 @@ public class DigitalClock extends LinearLayout {
|
|||||||
private TextView mTimeDisplay;
|
private TextView mTimeDisplay;
|
||||||
private AmPm mAmPm;
|
private AmPm mAmPm;
|
||||||
private ContentObserver mFormatChangeObserver;
|
private ContentObserver mFormatChangeObserver;
|
||||||
private boolean mLive = true;
|
private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
|
||||||
private boolean mAttached;
|
|
||||||
|
|
||||||
/* called by system on minute ticks */
|
/* called by system on minute ticks */
|
||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mIntentReceiver;
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
private static class TimeChangedReceiver extends BroadcastReceiver {
|
||||||
if (mLive && intent.getAction().equals(
|
private WeakReference<DigitalClock> mClock;
|
||||||
Intent.ACTION_TIMEZONE_CHANGED)) {
|
private Context mContext;
|
||||||
mCalendar = Calendar.getInstance();
|
|
||||||
}
|
public TimeChangedReceiver(DigitalClock clock) {
|
||||||
// Post a runnable to avoid blocking the broadcast.
|
mClock = new WeakReference<DigitalClock>(clock);
|
||||||
mHandler.post(new Runnable() {
|
mContext = clock.getContext();
|
||||||
public void run() {
|
}
|
||||||
updateTime();
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
// Post a runnable to avoid blocking the broadcast.
|
||||||
|
final boolean timezoneChanged =
|
||||||
|
intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
|
||||||
|
final DigitalClock clock = mClock.get();
|
||||||
|
if (clock != null) {
|
||||||
|
clock.mHandler.post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (timezoneChanged) {
|
||||||
|
clock.mCalendar = Calendar.getInstance();
|
||||||
}
|
}
|
||||||
|
clock.updateTime();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
mContext.unregisterReceiver(this);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static class AmPm {
|
static class AmPm {
|
||||||
private TextView mAmPm;
|
private TextView mAmPm;
|
||||||
@@ -94,14 +109,23 @@ public class DigitalClock extends LinearLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FormatChangeObserver extends ContentObserver {
|
private static class FormatChangeObserver extends ContentObserver {
|
||||||
public FormatChangeObserver() {
|
private WeakReference<DigitalClock> mClock;
|
||||||
|
private Context mContext;
|
||||||
|
public FormatChangeObserver(DigitalClock clock) {
|
||||||
super(new Handler());
|
super(new Handler());
|
||||||
|
mClock = new WeakReference<DigitalClock>(clock);
|
||||||
|
mContext = clock.getContext();
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
setDateFormat();
|
DigitalClock digitalClock = mClock.get();
|
||||||
updateTime();
|
if (digitalClock != null) {
|
||||||
|
digitalClock.setDateFormat();
|
||||||
|
digitalClock.updateTime();
|
||||||
|
} else {
|
||||||
|
mContext.getContentResolver().unregisterContentObserver(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,11 +153,11 @@ public class DigitalClock extends LinearLayout {
|
|||||||
protected void onAttachedToWindow() {
|
protected void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
|
|
||||||
if (mAttached) return;
|
mAttached++;
|
||||||
mAttached = true;
|
|
||||||
|
|
||||||
if (mLive) {
|
/* monitor time ticks, time changed, timezone */
|
||||||
/* monitor time ticks, time changed, timezone */
|
if (mIntentReceiver == null) {
|
||||||
|
mIntentReceiver = new TimeChangedReceiver(this);
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(Intent.ACTION_TIME_TICK);
|
filter.addAction(Intent.ACTION_TIME_TICK);
|
||||||
filter.addAction(Intent.ACTION_TIME_CHANGED);
|
filter.addAction(Intent.ACTION_TIME_CHANGED);
|
||||||
@@ -142,9 +166,11 @@ public class DigitalClock extends LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* monitor 12/24-hour display preference */
|
/* monitor 12/24-hour display preference */
|
||||||
mFormatChangeObserver = new FormatChangeObserver();
|
if (mFormatChangeObserver == null) {
|
||||||
mContext.getContentResolver().registerContentObserver(
|
mFormatChangeObserver = new FormatChangeObserver(this);
|
||||||
Settings.System.CONTENT_URI, true, mFormatChangeObserver);
|
mContext.getContentResolver().registerContentObserver(
|
||||||
|
Settings.System.CONTENT_URI, true, mFormatChangeObserver);
|
||||||
|
}
|
||||||
|
|
||||||
updateTime();
|
updateTime();
|
||||||
}
|
}
|
||||||
@@ -153,16 +179,19 @@ public class DigitalClock extends LinearLayout {
|
|||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
|
|
||||||
if (!mAttached) return;
|
mAttached--;
|
||||||
mAttached = false;
|
|
||||||
|
|
||||||
if (mLive) {
|
if (mIntentReceiver != null) {
|
||||||
mContext.unregisterReceiver(mIntentReceiver);
|
mContext.unregisterReceiver(mIntentReceiver);
|
||||||
}
|
}
|
||||||
mContext.getContentResolver().unregisterContentObserver(
|
if (mFormatChangeObserver != null) {
|
||||||
mFormatChangeObserver);
|
mContext.getContentResolver().unregisterContentObserver(
|
||||||
}
|
mFormatChangeObserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFormatChangeObserver = null;
|
||||||
|
mIntentReceiver = null;
|
||||||
|
}
|
||||||
|
|
||||||
void updateTime(Calendar c) {
|
void updateTime(Calendar c) {
|
||||||
mCalendar = c;
|
mCalendar = c;
|
||||||
@@ -170,9 +199,7 @@ public class DigitalClock extends LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateTime() {
|
private void updateTime() {
|
||||||
if (mLive) {
|
mCalendar.setTimeInMillis(System.currentTimeMillis());
|
||||||
mCalendar.setTimeInMillis(System.currentTimeMillis());
|
|
||||||
}
|
|
||||||
|
|
||||||
CharSequence newTime = DateFormat.format(mFormat, mCalendar);
|
CharSequence newTime = DateFormat.format(mFormat, mCalendar);
|
||||||
mTimeDisplay.setText(newTime);
|
mTimeDisplay.setText(newTime);
|
||||||
@@ -180,12 +207,8 @@ public class DigitalClock extends LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setDateFormat() {
|
private void setDateFormat() {
|
||||||
mFormat = android.text.format.DateFormat.is24HourFormat(getContext())
|
mFormat = android.text.format.DateFormat.is24HourFormat(getContext())
|
||||||
? M24 : M12;
|
? M24 : M12;
|
||||||
mAmPm.setShowAmPm(mFormat.equals(M12));
|
mAmPm.setShowAmPm(mFormat.equals(M12));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLive(boolean live) {
|
|
||||||
mLive = live;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
|
|||||||
*/
|
*/
|
||||||
private static final int AWAKE_POKE_MILLIS = 30000;
|
private static final int AWAKE_POKE_MILLIS = 30000;
|
||||||
|
|
||||||
private final KeyguardScreenCallback mCallback;
|
private KeyguardScreenCallback mCallback;
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private KeyguardUpdateMonitor mUpdateMonitor;
|
private KeyguardUpdateMonitor mUpdateMonitor;
|
||||||
|
|
||||||
private TextView mTopHeader;
|
private TextView mTopHeader;
|
||||||
@@ -159,7 +159,10 @@ public class AccountUnlockScreen extends RelativeLayout implements KeyguardScree
|
|||||||
if (mCheckingDialog != null) {
|
if (mCheckingDialog != null) {
|
||||||
mCheckingDialog.hide();
|
mCheckingDialog.hide();
|
||||||
}
|
}
|
||||||
mUpdateMonitor.removeCallback(this);
|
mUpdateMonitor.removeCallback(this); // this must be first
|
||||||
|
mCallback = null;
|
||||||
|
mLockPatternUtils = null;
|
||||||
|
mUpdateMonitor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
|||||||
@@ -223,8 +223,8 @@ public class KeyguardViewManager implements KeyguardWindowController {
|
|||||||
mKeyguardHost.postDelayed(new Runnable() {
|
mKeyguardHost.postDelayed(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (KeyguardViewManager.this) {
|
synchronized (KeyguardViewManager.this) {
|
||||||
mKeyguardHost.removeView(lastView);
|
|
||||||
lastView.cleanUp();
|
lastView.cleanUp();
|
||||||
|
mKeyguardHost.removeView(lastView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|||||||
@@ -495,8 +495,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase {
|
|||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
((KeyguardScreen) mLockScreen).onPause();
|
((KeyguardScreen) mLockScreen).onPause();
|
||||||
((KeyguardScreen) mLockScreen).cleanUp();
|
((KeyguardScreen) mLockScreen).cleanUp();
|
||||||
|
this.removeView(mLockScreen);
|
||||||
((KeyguardScreen) mUnlockScreen).onPause();
|
((KeyguardScreen) mUnlockScreen).onPause();
|
||||||
((KeyguardScreen) mUnlockScreen).cleanUp();
|
((KeyguardScreen) mUnlockScreen).cleanUp();
|
||||||
|
this.removeView(mUnlockScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSecure() {
|
private boolean isSecure() {
|
||||||
|
|||||||
@@ -55,9 +55,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
|
|||||||
|
|
||||||
private Status mStatus = Status.Normal;
|
private Status mStatus = Status.Normal;
|
||||||
|
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private final KeyguardUpdateMonitor mUpdateMonitor;
|
private KeyguardUpdateMonitor mUpdateMonitor;
|
||||||
private final KeyguardScreenCallback mCallback;
|
private KeyguardScreenCallback mCallback;
|
||||||
|
|
||||||
private TextView mCarrier;
|
private TextView mCarrier;
|
||||||
private SlidingTab mSelector;
|
private SlidingTab mSelector;
|
||||||
@@ -225,8 +225,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
|
|||||||
setFocusableInTouchMode(true);
|
setFocusableInTouchMode(true);
|
||||||
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
|
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
|
||||||
|
|
||||||
updateMonitor.registerInfoCallback(this);
|
mUpdateMonitor.registerInfoCallback(this);
|
||||||
updateMonitor.registerSimStateCallback(this);
|
mUpdateMonitor.registerSimStateCallback(this);
|
||||||
|
|
||||||
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
||||||
mSilentMode = isSilentMode();
|
mSilentMode = isSilentMode();
|
||||||
@@ -668,7 +668,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateM
|
|||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
mUpdateMonitor.removeCallback(this);
|
mUpdateMonitor.removeCallback(this); // this must be first
|
||||||
|
mLockPatternUtils = null;
|
||||||
|
mUpdateMonitor = null;
|
||||||
|
mCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
|||||||
@@ -66,9 +66,9 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
|
|||||||
private int mTotalFailedPatternAttempts = 0;
|
private int mTotalFailedPatternAttempts = 0;
|
||||||
private CountDownTimer mCountdownTimer = null;
|
private CountDownTimer mCountdownTimer = null;
|
||||||
|
|
||||||
private final LockPatternUtils mLockPatternUtils;
|
private LockPatternUtils mLockPatternUtils;
|
||||||
private final KeyguardUpdateMonitor mUpdateMonitor;
|
private KeyguardUpdateMonitor mUpdateMonitor;
|
||||||
private final KeyguardScreenCallback mCallback;
|
private KeyguardScreenCallback mCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* whether there is a fallback option available when the pattern is forgotten.
|
* whether there is a fallback option available when the pattern is forgotten.
|
||||||
@@ -478,6 +478,9 @@ class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
|
|||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
mUpdateMonitor.removeCallback(this);
|
mUpdateMonitor.removeCallback(this);
|
||||||
|
mLockPatternUtils = null;
|
||||||
|
mUpdateMonitor = null;
|
||||||
|
mCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user