From 99fd277a4737e4369246fc3d210c14c83d1fbce7 Mon Sep 17 00:00:00 2001 From: Yuta Yamada Date: Thu, 6 Oct 2016 17:40:19 +0900 Subject: [PATCH] Fix memory leak of Dnd tile The instance of Dnd tile leaks when user taps the edit button of Quick Settings. To fix this issue, QSTile#destroy should be called when the tile is no longer needed. Bug: 32103239 Test: manual - go to Quick Settings -> Edit repeatedly Change-Id: I9bc9ee836be5c8e46eb1ccd202bd5cc50070ef47 --- .../systemui/qs/customize/TileQueryHelper.java | 6 +++++- .../src/com/android/systemui/qs/tiles/DndTile.java | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java index 1431b22b654e5..590f54e6ba337 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java @@ -65,7 +65,10 @@ public class TileQueryHelper { for (int i = 0; i < possibleTiles.length; i++) { final String spec = possibleTiles[i]; final QSTile tile = host.createTile(spec); - if (tile == null || !tile.isAvailable()) { + if (tile == null) { + continue; + } else if (!tile.isAvailable()) { + tile.destroy(); continue; } tile.setListening(this, true); @@ -79,6 +82,7 @@ public class TileQueryHelper { tile.getState().copyTo(state); // Ignore the current state and get the generic label instead. state.label = tile.getTileLabel(); + tile.destroy(); mainHandler.post(new Runnable() { @Override public void run() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java index 04cb55331554d..4a3fea838dacc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java @@ -68,12 +68,23 @@ public class DndTile extends QSTile { private boolean mListening; private boolean mShowingDetail; + private boolean mReceiverRegistered; public DndTile(Host host) { super(host); mController = host.getZenModeController(); mDetailAdapter = new DndDetailAdapter(); mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_SET_VISIBLE)); + mReceiverRegistered = true; + } + + @Override + protected void handleDestroy() { + super.handleDestroy(); + if (mReceiverRegistered) { + mContext.unregisterReceiver(mReceiver); + mReceiverRegistered = false; + } } public static void setVisible(Context context, boolean visible) {