diff options
author | Danny Baumann <dannybaumann@web.de> | 2013-04-30 13:06:04 +0200 |
---|---|---|
committer | Danny Baumann <dannybaumann@web.de> | 2013-04-30 13:08:34 +0200 |
commit | 9975780f073b29fbb85b0ee1cd700f1828f783c7 (patch) | |
tree | 6f35b734cc50ed9843b5fb4983d66b3746665e3d /packages/SystemUI/src/com/android/systemui/statusbar | |
parent | c926976008af16ab5e3a0bb532aeeb69565e3429 (diff) | |
download | frameworks_base-9975780f073b29fbb85b0ee1cd700f1828f783c7.zip frameworks_base-9975780f073b29fbb85b0ee1cd700f1828f783c7.tar.gz frameworks_base-9975780f073b29fbb85b0ee1cd700f1828f783c7.tar.bz2 |
Fix SystemUI memory leaks on theme changes.
ContentObserver and BroadcastReceiver instances were dangling after the
status bar was recreated.
Change-Id: I0ef7ef134029e5deec066d405545b8d9ec58d76b
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui/statusbar')
10 files changed, 88 insertions, 35 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java index 8d9dcfd..b4e3572 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterTextView.java @@ -39,7 +39,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; -import com.android.systemui.statusbar.SignalClusterView.SettingsObserver; import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.R; @@ -62,6 +61,7 @@ public class SignalClusterTextView TextView mMobileSignalText; Handler mHandler; + SettingsObserver mObserver; int dBm = 0; @@ -76,6 +76,10 @@ public class SignalClusterTextView Settings.System.STATUS_BAR_SIGNAL_TEXT), false, this); } + void unobserve() { + mContext.getContentResolver().unregisterContentObserver(this); + } + @Override public void onChange(boolean selfChange) { updateSettings(); } @@ -93,9 +97,7 @@ public class SignalClusterTextView super(context, attrs, defStyle); mHandler = new Handler(); - - SettingsObserver settingsObserver = new SettingsObserver(mHandler); - settingsObserver.observe(); + mObserver = new SettingsObserver(mHandler); } @Override @@ -111,6 +113,7 @@ public class SignalClusterTextView mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + mObserver.observe(); updateSettings(); } } @@ -118,6 +121,7 @@ public class SignalClusterTextView @Override protected void onDetachedFromWindow() { if (mAttached) { + mObserver.unobserve(); mAttached = false; } super.onDetachedFromWindow(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index 01815a6..f59f2ce 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -42,6 +42,7 @@ public class SignalClusterView static final String TAG = "SignalClusterView"; NetworkController mNC; + private SettingsObserver mObserver; private static final int SIGNAL_CLUSTER_STYLE_NORMAL = 0; @@ -71,6 +72,10 @@ public class SignalClusterView Settings.System.STATUS_BAR_SIGNAL_TEXT), false, this); } + void unobserve() { + mContext.getContentResolver().unregisterContentObserver(this); + } + @Override public void onChange(boolean selfChange) { updateSettings(); @@ -90,8 +95,7 @@ public class SignalClusterView mHandler = new Handler(); - SettingsObserver settingsObserver = new SettingsObserver(mHandler); - settingsObserver.observe(); + mObserver = new SettingsObserver(mHandler); } public void setNetworkController(NetworkController nc) { @@ -103,6 +107,8 @@ public class SignalClusterView protected void onAttachedToWindow() { super.onAttachedToWindow(); + mObserver.observe(); + mWifiGroup = (ViewGroup) findViewById(R.id.wifi_combo); mWifi = (ImageView) findViewById(R.id.wifi_signal); mWifiActivity = (ImageView) findViewById(R.id.wifi_inout); @@ -118,6 +124,8 @@ public class SignalClusterView @Override protected void onDetachedFromWindow() { + mObserver.unobserve(); + mWifiGroup = null; mWifi = null; mWifiActivity = null; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index a620f61..b3c1f07 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -695,6 +695,11 @@ public class PhoneStatusBar extends BaseStatusBar { } } + if (mQS != null) { + mQS.shutdown(); + mQS = null; + } + // wherever you find it, Quick Settings needs a container to survive mSettingsContainer = (QuickSettingsContainerView) mStatusBarWindow.findViewById(R.id.quick_settings_container); @@ -713,11 +718,10 @@ public class PhoneStatusBar extends BaseStatusBar { mQS.setupQuickSettings(); // Start observing for changes - mTilesChangedObserver = new TilesChangedObserver(mHandler); - mTilesChangedObserver.startObserving(); - - } else { - mQS = null; // fly away, be free + if (mTilesChangedObserver == null) { + mTilesChangedObserver = new TilesChangedObserver(mHandler); + mTilesChangedObserver.startObserving(); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java index 15860c9..834dfd4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsController.java @@ -188,15 +188,15 @@ public class QuickSettingsController { if (tile.equals(TILE_USER)) { qs = new UserTile(mContext, this); } else if (tile.equals(TILE_BATTERY)) { - qs = new BatteryTile(mContext, this); + qs = new BatteryTile(mContext, this, mStatusBarService.mBatteryController); } else if (tile.equals(TILE_SETTINGS)) { qs = new PreferencesTile(mContext, this); } else if (tile.equals(TILE_WIFI)) { - qs = new WiFiTile(mContext, this); + qs = new WiFiTile(mContext, this, mStatusBarService.mNetworkController); } else if (tile.equals(TILE_GPS)) { qs = new GPSTile(mContext, this); } else if (tile.equals(TILE_BLUETOOTH) && bluetoothSupported) { - qs = new BluetoothTile(mContext, this); + qs = new BluetoothTile(mContext, this, mStatusBarService.mBluetoothController); } else if (tile.equals(TILE_BRIGHTNESS)) { qs = new BrightnessTile(mContext, this, mHandler); } else if (tile.equals(TILE_RINGER)) { @@ -208,15 +208,15 @@ public class QuickSettingsController { } else if (tile.equals(TILE_SCREENTIMEOUT)) { qs = new ScreenTimeoutTile(mContext, this); } else if (tile.equals(TILE_MOBILEDATA) && mobileDataSupported) { - qs = new MobileNetworkTile(mContext, this); + qs = new MobileNetworkTile(mContext, this, mStatusBarService.mNetworkController); } else if (tile.equals(TILE_LOCKSCREEN)) { qs = new ToggleLockscreenTile(mContext, this); } else if (tile.equals(TILE_NETWORKMODE) && mobileDataSupported) { - qs = new MobileNetworkTypeTile(mContext, this); + qs = new MobileNetworkTypeTile(mContext, this, mStatusBarService.mNetworkController); } else if (tile.equals(TILE_AUTOROTATE)) { qs = new AutoRotateTile(mContext, this, mHandler); } else if (tile.equals(TILE_AIRPLANE)) { - qs = new AirplaneModeTile(mContext, this); + qs = new AirplaneModeTile(mContext, this, mStatusBarService.mNetworkController); } else if (tile.equals(TILE_TORCH)) { qs = new TorchTile(mContext, this, mHandler); } else if (tile.equals(TILE_SLEEP)) { @@ -291,27 +291,36 @@ public class QuickSettingsController { } private void loadDockBatteryTile(final ContentResolver resolver, final LayoutInflater inflater) { - if (deviceSupportsDockBattery(mContext) && Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_DOCK_BATTERY, 1) == 1) { - QuickSettingsTile qs = new DockBatteryTile(mContext, this); - qs.setupQuickSettingsTile(inflater, mContainerView); - mQuickSettingsTiles.add(qs); + if (!deviceSupportsDockBattery(mContext)) { + return; + } + if (Settings.System.getInt(resolver, Settings.System.QS_DYNAMIC_DOCK_BATTERY, 1) == 0) { + return; } + + QuickSettingsTile qs = new DockBatteryTile(mContext, this, mStatusBarService.mDockBatteryController); + qs.setupQuickSettingsTile(inflater, mContainerView); + mQuickSettingsTiles.add(qs); } - protected void setupQuickSettings() { - mQuickSettingsTiles.clear(); - mContainerView.removeAllViews(); - // Clear out old receiver + public void shutdown() { + if (mObserver != null) { + mContext.getContentResolver().unregisterContentObserver(mObserver); + } if (mReceiver != null) { mContext.unregisterReceiver(mReceiver); } + for (QuickSettingsTile qs : mQuickSettingsTiles) { + qs.onDestroy(); + } + mQuickSettingsTiles.clear(); + mContainerView.removeAllViews(); + } + + protected void setupQuickSettings() { + shutdown(); mReceiver = new QSBroadcastReceiver(); mReceiverMap.clear(); - ContentResolver resolver = mContext.getContentResolver(); - // Clear out old observer - if (mObserver != null) { - resolver.unregisterContentObserver(mObserver); - } mObserver = new QuickSettingsObserver(mHandler); mObserverMap.clear(); mTileStatusUris.clear(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java index a2b425b..6cb5adb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryController.java @@ -120,6 +120,10 @@ public class BatteryController extends BroadcastReceiver { mChangeCallbacks.add(cb); } + public void removeStateChangedCallback(BatteryStateChangeCallback cb) { + mChangeCallbacks.remove(cb); + } + // Allow override battery icons public int getIconStyleUnknown() { return R.drawable.stat_sys_battery; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java index fece57e..4d5383d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothController.java @@ -73,6 +73,10 @@ public class BluetoothController extends BroadcastReceiver { mChangeCallbacks.add(cb); } + public void removeStateChangedCallback(BluetoothStateChangeCallback cb) { + mChangeCallbacks.remove(cb); + } + public Set<BluetoothDevice> getBondedBluetoothDevices() { return mBondedDevices; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java index 01178c0..9aeb200 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CircleBattery.java @@ -54,6 +54,7 @@ public class CircleBattery extends ImageView { private Handler mHandler; private Context mContext; private BatteryReceiver mBatteryReceiver = null; + private SettingsObserver mObserver; // state variables private boolean mAttached; // whether or not attached to a window @@ -100,6 +101,10 @@ public class CircleBattery extends ImageView { onChange(true); } + public void unobserve() { + mContext.getContentResolver().unregisterContentObserver(this); + } + @Override public void onChange(boolean selfChange) { int batteryStyle = (Settings.System.getInt(mContext.getContentResolver(), @@ -190,8 +195,7 @@ public class CircleBattery extends ImageView { mContext = context; mHandler = new Handler(); - SettingsObserver settingsObserver = new SettingsObserver(mHandler); - settingsObserver.observe(); + mObserver = new SettingsObserver(mHandler); mBatteryReceiver = new BatteryReceiver(mContext); // initialize and setup all paint variables @@ -260,6 +264,7 @@ public class CircleBattery extends ImageView { super.onAttachedToWindow(); if (!mAttached) { mAttached = true; + mObserver.observe(); mBatteryReceiver.updateRegistration(); mHandler.postDelayed(mInvalidate, 250); } @@ -270,6 +275,7 @@ public class CircleBattery extends ImageView { super.onDetachedFromWindow(); if (mAttached) { mAttached = false; + mObserver.unobserve(); mBatteryReceiver.updateRegistration(); mRectLeft = null; // makes sure, size based variables get // recalculated on next attach diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index 2b7360c..7779b1f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -55,6 +55,7 @@ public class Clock extends TextView implements OnClickListener, OnLongClickListe private String mClockFormatString; private SimpleDateFormat mClockFormat; private Locale mLocale; + private SettingsObserver mObserver; private static final int AM_PM_STYLE_NORMAL = 0; private static final int AM_PM_STYLE_SMALL = 1; @@ -78,6 +79,10 @@ public class Clock extends TextView implements OnClickListener, OnLongClickListe Settings.System.STATUS_BAR_CLOCK), false, this); } + void unobserve() { + mContext.getContentResolver().unregisterContentObserver(this); + } + @Override public void onChange(boolean selfChange) { updateSettings(); } @@ -95,9 +100,8 @@ public class Clock extends TextView implements OnClickListener, OnLongClickListe super(context, attrs, defStyle); mHandler = new Handler(); - SettingsObserver settingsObserver = new SettingsObserver(mHandler); - settingsObserver.observe(); - if(isClickable()){ + mObserver = new SettingsObserver(mHandler); + if (isClickable()) { setOnClickListener(this); setOnLongClickListener(this); } @@ -119,6 +123,7 @@ public class Clock extends TextView implements OnClickListener, OnLongClickListe filter.addAction(Intent.ACTION_USER_SWITCHED); getContext().registerReceiver(mIntentReceiver, filter, null, getHandler()); + mObserver.observe(); } // NOTE: It's safe to do these after registering the receiver since the receiver always runs @@ -136,6 +141,7 @@ public class Clock extends TextView implements OnClickListener, OnLongClickListe super.onDetachedFromWindow(); if (mAttached) { getContext().unregisterReceiver(mIntentReceiver); + mObserver.unobserve(); mAttached = false; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java index 83639ee..cf0a3bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DockBatteryController.java @@ -76,6 +76,10 @@ public class DockBatteryController extends BatteryController { mChangeCallbacks.add(cb); } + public void removeStateChangedCallback(DockBatteryStateChangeCallback cb) { + mChangeCallbacks.remove(cb); + } + @Override public int getIconStyleUnknown() { return R.drawable.stat_sys_kb_battery_unknown; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java index 19d9f8c..1a4718e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -314,6 +314,10 @@ public class NetworkController extends BroadcastReceiver { notifySignalsChangedCallbacks(cb); } + public void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) { + mSignalsChangedCallbacks.remove(cb); + } + public void refreshSignalCluster(SignalCluster cluster) { cluster.setWifiIndicators( // only show wifi in the cluster if connected or if wifi-only |