Merge "Update QS if the content gets stale" into oc-mr1-dev

This commit is contained in:
TreeHugger Robot
2017-09-08 20:55:05 +00:00
committed by Android (Google) Code Review
22 changed files with 95 additions and 35 deletions

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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 {

View File

@@ -63,7 +63,7 @@ public class ColorInversionTile extends QSTileImpl<BooleanState> {
}
@Override
public void setListening(boolean listening) {
public void handleSetListening(boolean listening) {
mSetting.setListening(listening);
}

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -76,7 +76,7 @@ public class IntentTile extends QSTileImpl<State> {
}
@Override
public void setListening(boolean listening) {
public void handleSetListening(boolean listening) {
}
@Override

View File

@@ -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);

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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) {
}

View File

@@ -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();