From 572230b7a993faa4c5b3b3d3cad73502840200ff Mon Sep 17 00:00:00 2001 From: Amin Shaikh Date: Tue, 20 Mar 2018 17:24:57 -0400 Subject: [PATCH] Make QSTileImpl#mListeners thread safe. Only add/remove/access mListeners on the background thread. Fixes: 69549729 Test: manually using customizer Change-Id: Ic7822d665acfe5d7899950a6e73c36e1ddc548e1 --- .../systemui/qs/tileimpl/QSTileImpl.java | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index 40b8d78073cf4..834feb7781eab 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -85,6 +85,7 @@ public abstract class QSTileImpl implements QSTile { private String mTileSpec; private EnforcedAdmin mEnforcedAdmin; private boolean mShowingDetail; + private int mIsFullQs; public abstract TState newTileState(); @@ -110,18 +111,7 @@ public abstract class QSTileImpl implements QSTile { * listening client it will go into the listening state. */ public void setListening(Object listener, boolean listening) { - if (listening) { - if (mListeners.add(listener) && mListeners.size() == 1) { - if (DEBUG) Log.d(TAG, "setListening " + true); - mHandler.obtainMessage(H.SET_LISTENING, 1, 0).sendToTarget(); - refreshState(); // Ensure we get at least one refresh after listening. - } - } else { - if (mListeners.remove(listener) && mListeners.size() == 0) { - if (DEBUG) Log.d(TAG, "setListening " + false); - mHandler.obtainMessage(H.SET_LISTENING, 0, 0).sendToTarget(); - } - } + mHandler.obtainMessage(H.SET_LISTENING, listening ? 1 : 0, 0, listener).sendToTarget(); } protected long getStaleTimeout() { @@ -205,19 +195,10 @@ public abstract class QSTileImpl implements QSTile { logMaker.addTaggedData(FIELD_QS_VALUE, ((BooleanState) mState).value ? 1 : 0); } return logMaker.setSubtype(getMetricsCategory()) - .addTaggedData(FIELD_CONTEXT, isFullQs()) + .addTaggedData(FIELD_CONTEXT, mIsFullQs) .addTaggedData(FIELD_QS_POSITION, mHost.indexOf(mTileSpec)); } - private int isFullQs() { - for (Object listener : mListeners) { - if (TilePage.class.equals(listener.getClass())) { - return 1; - } - } - return 0; - } - public void showDetail(boolean show) { mHandler.obtainMessage(H.SHOW_DETAIL, show ? 1 : 0, 0).sendToTarget(); } @@ -352,6 +333,32 @@ public abstract class QSTileImpl implements QSTile { handleRefreshState(null); } + private void handleSetListeningInternal(Object listener, boolean listening) { + if (listening) { + if (mListeners.add(listener) && mListeners.size() == 1) { + if (DEBUG) Log.d(TAG, "handleSetListening true"); + handleSetListening(listening); + refreshState(); // Ensure we get at least one refresh after listening. + } + } else { + if (mListeners.remove(listener) && mListeners.size() == 0) { + if (DEBUG) Log.d(TAG, "handleSetListening false"); + handleSetListening(listening); + } + } + updateIsFullQs(); + } + + private void updateIsFullQs() { + for (Object listener : mListeners) { + if (TilePage.class.equals(listener.getClass())) { + mIsFullQs = 1; + return; + } + } + mIsFullQs = 0; + } + protected abstract void handleSetListening(boolean listening); protected void handleDestroy() { @@ -464,8 +471,8 @@ public abstract class QSTileImpl implements QSTile { name = "handleClearState"; handleClearState(); } else if (msg.what == SET_LISTENING) { - name = "handleSetListening"; - handleSetListening(msg.arg1 != 0); + name = "handleSetListeningInternal"; + handleSetListeningInternal(msg.obj, msg.arg1 != 0); } else if (msg.what == STALE) { name = "handleStale"; handleStale();