Merge "Update QS if the content gets stale" into oc-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b98eeb2552
@@ -31,6 +31,7 @@ import android.provider.Settings;
|
||||
import android.service.quicksettings.IQSTileService;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.service.quicksettings.TileService;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.WindowManagerGlobal;
|
||||
@@ -51,6 +52,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
|
||||
public class CustomTile extends QSTileImpl<State> implements TileChangeListener {
|
||||
public static final String PREFIX = "custom(";
|
||||
|
||||
private static final long CUSTOM_STALE_TIMEOUT = DateUtils.HOUR_IN_MILLIS;
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
// We don't want to thrash binding and unbinding if the user opens and closes the panel a lot.
|
||||
@@ -83,6 +86,11 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
|
||||
mUser = ActivityManager.getCurrentUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected long getStaleTimeout() {
|
||||
return CUSTOM_STALE_TIMEOUT + DateUtils.MINUTE_IN_MILLIS * mHost.indexOf(getTileSpec());
|
||||
}
|
||||
|
||||
private void setTileIcon() {
|
||||
try {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
@@ -186,7 +194,7 @@ public class CustomTile extends QSTileImpl<State> implements TileChangeListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (mListening == listening) return;
|
||||
mListening = listening;
|
||||
try {
|
||||
|
||||
@@ -32,10 +32,12 @@ import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.Utils;
|
||||
@@ -45,7 +47,6 @@ import com.android.systemui.plugins.qs.DetailAdapter;
|
||||
import com.android.systemui.plugins.qs.QSIconView;
|
||||
import com.android.systemui.plugins.qs.QSTile;
|
||||
import com.android.systemui.plugins.qs.QSTile.State;
|
||||
import com.android.systemui.qs.PagedTileLayout;
|
||||
import com.android.systemui.qs.PagedTileLayout.TilePage;
|
||||
import com.android.systemui.qs.QSHost;
|
||||
|
||||
@@ -62,14 +63,18 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
protected final String TAG = "Tile." + getClass().getSimpleName();
|
||||
protected static final boolean DEBUG = Log.isLoggable("Tile", Log.DEBUG);
|
||||
|
||||
private static final long DEFAULT_STALE_TIMEOUT = 10 * DateUtils.MINUTE_IN_MILLIS;
|
||||
|
||||
protected final QSHost mHost;
|
||||
protected final Context mContext;
|
||||
protected final H mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
|
||||
// @NonFinalForTesting
|
||||
protected H mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
|
||||
protected final Handler mUiHandler = new Handler(Looper.getMainLooper());
|
||||
private final ArraySet<Object> mListeners = new ArraySet<>();
|
||||
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
|
||||
|
||||
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
|
||||
private final Object mStaleListener = new Object();
|
||||
protected TState mState = newTileState();
|
||||
private TState mTmpState = newTileState();
|
||||
private boolean mAnnounceNextStateChange;
|
||||
@@ -95,6 +100,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
protected QSTileImpl(QSHost host) {
|
||||
mHost = host;
|
||||
mContext = host.getContext();
|
||||
handleStale(); // Tile was just created, must be stale.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,6 +112,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
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) {
|
||||
@@ -115,6 +122,15 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
}
|
||||
}
|
||||
|
||||
protected long getStaleTimeout() {
|
||||
return DEFAULT_STALE_TIMEOUT;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void handleStale() {
|
||||
setListening(mStaleListener, true);
|
||||
}
|
||||
|
||||
public String getTileSpec() {
|
||||
return mTileSpec;
|
||||
}
|
||||
@@ -273,6 +289,9 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
if (changed) {
|
||||
handleStateChanged();
|
||||
}
|
||||
mHandler.removeMessages(H.STALE);
|
||||
mHandler.sendEmptyMessageDelayed(H.STALE, getStaleTimeout());
|
||||
setListening(mStaleListener, false);
|
||||
}
|
||||
|
||||
private void handleStateChanged() {
|
||||
@@ -326,11 +345,11 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
handleRefreshState(null);
|
||||
}
|
||||
|
||||
protected abstract void setListening(boolean listening);
|
||||
protected abstract void handleSetListening(boolean listening);
|
||||
|
||||
protected void handleDestroy() {
|
||||
if (mListeners.size() != 0) {
|
||||
setListening(false);
|
||||
handleSetListening(false);
|
||||
}
|
||||
mCallbacks.clear();
|
||||
}
|
||||
@@ -380,8 +399,10 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
private static final int REMOVE_CALLBACKS = 12;
|
||||
private static final int REMOVE_CALLBACK = 13;
|
||||
private static final int SET_LISTENING = 14;
|
||||
private static final int STALE = 15;
|
||||
|
||||
private H(Looper looper) {
|
||||
@VisibleForTesting
|
||||
protected H(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
@@ -436,8 +457,11 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
name = "handleClearState";
|
||||
handleClearState();
|
||||
} else if (msg.what == SET_LISTENING) {
|
||||
name = "setListening";
|
||||
setListening(msg.arg1 != 0);
|
||||
name = "handleSetListening";
|
||||
handleSetListening(msg.arg1 != 0);
|
||||
} else if (msg.what == STALE) {
|
||||
name = "handleStale";
|
||||
handleStale();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown msg: " + msg.what);
|
||||
}
|
||||
@@ -515,7 +539,7 @@ public abstract class QSTileImpl<TState extends State> implements QSTile {
|
||||
}
|
||||
}
|
||||
|
||||
protected class AnimationIcon extends ResourceIcon {
|
||||
protected static class AnimationIcon extends ResourceIcon {
|
||||
private final int mAnimatedResId;
|
||||
|
||||
public AnimationIcon(int resId, int staticResId) {
|
||||
|
||||
@@ -110,7 +110,7 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (mListening == listening) return;
|
||||
mListening = listening;
|
||||
if (listening) {
|
||||
|
||||
@@ -55,7 +55,7 @@ public class BatterySaverTile extends QSTileImpl<BooleanState> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mBatteryController.addCallback(this);
|
||||
} else {
|
||||
|
||||
@@ -76,7 +76,7 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mController.addCallback(mCallback);
|
||||
} else {
|
||||
|
||||
@@ -91,9 +91,9 @@ public class CastTile extends QSTileImpl<BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (mController == null) return;
|
||||
if (DEBUG) Log.d(TAG, "setListening " + listening);
|
||||
if (DEBUG) Log.d(TAG, "handleSetListening " + listening);
|
||||
if (listening) {
|
||||
mController.addCallback(mCallback);
|
||||
mKeyguard.addCallback(mCallback);
|
||||
|
||||
@@ -92,7 +92,7 @@ public class CellularTile extends QSTileImpl<SignalState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mController.addCallback(mSignalCallback);
|
||||
} else {
|
||||
|
||||
@@ -63,7 +63,7 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
mSetting.setListening(listening);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class DataSaverTile extends QSTileImpl<BooleanState> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mDataSaverController.addCallback(this);
|
||||
} else {
|
||||
|
||||
@@ -232,7 +232,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (mListening == listening) return;
|
||||
mListening = listening;
|
||||
if (mListening) {
|
||||
|
||||
@@ -54,7 +54,7 @@ public class FlashlightTile extends QSTileImpl<BooleanState> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mFlashlightController.addCallback(this);
|
||||
} else {
|
||||
|
||||
@@ -74,7 +74,7 @@ public class HotspotTile extends QSTileImpl<AirplaneBooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (mListening == listening) return;
|
||||
mListening = listening;
|
||||
if (listening) {
|
||||
|
||||
@@ -76,7 +76,7 @@ public class IntentTile extends QSTileImpl<State> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -55,7 +55,7 @@ public class LocationTile extends QSTileImpl<BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mController.addCallback(mCallback);
|
||||
mKeyguard.addCallback(mCallback);
|
||||
|
||||
@@ -51,7 +51,7 @@ public class NfcTile extends QSTileImpl<BooleanState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
mListening = listening;
|
||||
if (mListening) {
|
||||
mContext.registerReceiver(mNfcReceiver,
|
||||
|
||||
@@ -95,7 +95,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setListening(boolean listening) {
|
||||
protected void handleSetListening(boolean listening) {
|
||||
mIsListening = listening;
|
||||
if (listening) {
|
||||
mController.setListener(this);
|
||||
|
||||
@@ -62,7 +62,7 @@ public class RotationLockTile extends QSTileImpl<BooleanState> {
|
||||
return new BooleanState();
|
||||
}
|
||||
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (mController == null) return;
|
||||
if (listening) {
|
||||
mController.addCallback(mCallback);
|
||||
|
||||
@@ -69,7 +69,7 @@ public class UserTile extends QSTileImpl<State> implements UserInfoController.On
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mUserInfoController.addCallback(this);
|
||||
} else {
|
||||
|
||||
@@ -75,7 +75,7 @@ public class WifiTile extends QSTileImpl<SignalState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mController.addCallback(mSignalCallback);
|
||||
} else {
|
||||
|
||||
@@ -48,7 +48,7 @@ public class WorkModeTile extends QSTileImpl<BooleanState> implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
public void handleSetListening(boolean listening) {
|
||||
if (listening) {
|
||||
mProfileController.addCallback(this);
|
||||
} else {
|
||||
|
||||
@@ -25,10 +25,15 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static java.lang.Thread.sleep;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.metrics.LogMaker;
|
||||
import android.support.test.filters.SmallTest;
|
||||
@@ -67,10 +72,10 @@ public class QSTileImplTest extends SysuiTestCase {
|
||||
mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class);
|
||||
mHost = mock(QSTileHost.class);
|
||||
when(mHost.indexOf(spec)).thenReturn(POSITION);
|
||||
mTestableLooper.runWithLooper(() -> {
|
||||
mTile = new TileImpl(mHost);
|
||||
mTile.setTileSpec(spec);
|
||||
});
|
||||
|
||||
mTile = spy(new TileImpl(mHost));
|
||||
mTile.mHandler = mTile.new H(mTestableLooper.getLooper());
|
||||
mTile.setTileSpec(spec);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,6 +107,31 @@ public class QSTileImplTest extends SysuiTestCase {
|
||||
verify(maker).addTaggedData(eq(FIELD_QS_POSITION), eq(POSITION));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaleTimeout() throws InterruptedException {
|
||||
when(mTile.getStaleTimeout()).thenReturn(5l);
|
||||
clearInvocations(mTile);
|
||||
|
||||
mTile.handleRefreshState(null);
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mTile, never()).handleStale();
|
||||
|
||||
sleep(10);
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mTile).handleStale();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaleListening() {
|
||||
mTile.handleStale();
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mTile).handleSetListening(eq(true));
|
||||
|
||||
mTile.handleRefreshState(null);
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mTile).handleSetListening(eq(false));
|
||||
}
|
||||
|
||||
private class TileLogMatcher implements ArgumentMatcher<LogMaker> {
|
||||
|
||||
private final int mCategory;
|
||||
@@ -166,7 +196,7 @@ public class QSTileImplTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setListening(boolean listening) {
|
||||
protected void handleSetListening(boolean listening) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.support.test.filters.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
@@ -145,7 +144,6 @@ public class ExtensionControllerImplTest extends SysuiTestCase {
|
||||
@Test
|
||||
@RunWithLooper
|
||||
public void testSortOrder() {
|
||||
Log.d("TestTest", "Config " + mContext.getResources().getConfiguration().uiMode);
|
||||
Object def = new Object();
|
||||
Object uiMode = new Object();
|
||||
Object tuner = new Object();
|
||||
|
||||
Reference in New Issue
Block a user