1af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock/* 2af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Copyright (C) 2014 The Android Open Source Project 3af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 4af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * you may not use this file except in compliance with the License. 6af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * You may obtain a copy of the License at 7af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 8af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 10af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Unless required by applicable law or agreed to in writing, software 11af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * See the License for the specific language governing permissions and 14af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * limitations under the License. 15af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock */ 16af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 17af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockpackage com.android.systemui.qs; 18af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 19af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.content.Context; 20af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.content.Intent; 212d695813b44690ca146f95939acb00f0c14dac29John Spurlockimport android.graphics.drawable.AnimatedVectorDrawable; 22444eb2e13032c78b23b4a371ce6164faf1a3512bJohn Spurlockimport android.graphics.drawable.Drawable; 23af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.Handler; 24af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.Looper; 25af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.os.Message; 26af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.util.Log; 272d695813b44690ca146f95939acb00f0c14dac29John Spurlockimport android.util.SparseArray; 28af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.view.View; 29af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport android.view.ViewGroup; 30af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 31af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.qs.QSTile.State; 32af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.BluetoothController; 33af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.CastController; 34b83777ba5c12295224cd566bba59a44b8860e449Adrian Roosimport com.android.systemui.statusbar.policy.FlashlightController; 35657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlockimport com.android.systemui.statusbar.policy.KeyguardMonitor; 36ccb6b9a90f228cc4e31a9442ed28756ff474c080John Spurlockimport com.android.systemui.statusbar.policy.Listenable; 37af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.LocationController; 38af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.NetworkController; 39af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.RotationLockController; 4051e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monkimport com.android.systemui.statusbar.policy.HotspotController; 41af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport com.android.systemui.statusbar.policy.ZenModeController; 42af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 43bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport java.util.Collection; 44af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlockimport java.util.Objects; 45af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 46af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock/** 47af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * Base quick-settings tile, extend this to create a new tile. 48af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * 49af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * State management done on a looper provided by the host. Tiles should update state in 50af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * handleUpdateState. Callbacks affecting state should use refreshState to trigger another 51af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock * state update pass on tile looper. 52af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock */ 53ccb6b9a90f228cc4e31a9442ed28756ff474c080John Spurlockpublic abstract class QSTile<TState extends State> implements Listenable { 54ccb6b9a90f228cc4e31a9442ed28756ff474c080John Spurlock protected final String TAG = "QSTile." + getClass().getSimpleName(); 55486b78e42652466f6241eb87d5bed60040db7a25John Spurlock protected static final boolean DEBUG = Log.isLoggable("QSTile", Log.DEBUG); 56af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 57af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final Host mHost; 58af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final Context mContext; 59af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final H mHandler; 6076c43b9ee1fb91016265b3758d3d635105091fbeJohn Spurlock protected final Handler mUiHandler = new Handler(Looper.getMainLooper()); 61af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 62af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private Callback mCallback; 63af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final TState mState = newTileState(); 64af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private final TState mTmpState = newTileState(); 654fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek private boolean mAnnounceNextStateChange; 66af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 67af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock abstract protected TState newTileState(); 68af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock abstract protected void handleClick(); 69af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock abstract protected void handleUpdateState(TState state, Object arg); 70af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 71af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected QSTile(Host host) { 72af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHost = host; 73af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mContext = host.getContext(); 74af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHandler = new H(host.getLooper()); 75af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 76af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 77ccb6b9a90f228cc4e31a9442ed28756ff474c080John Spurlock public boolean supportsDualTargets() { 78ccb6b9a90f228cc4e31a9442ed28756ff474c080John Spurlock return false; 79ccb6b9a90f228cc4e31a9442ed28756ff474c080John Spurlock } 80ccb6b9a90f228cc4e31a9442ed28756ff474c080John Spurlock 81af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public Host getHost() { 82af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return mHost; 83af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 84af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 85af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public QSTileView createTileView(Context context) { 86af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return new QSTileView(context); 87af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 88af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 897f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock public DetailAdapter getDetailAdapter() { 90af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return null; // optional 91af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 92af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 937f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock public interface DetailAdapter { 947f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock int getTitle(); 957f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock Boolean getToggleState(); 967f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock View createDetailView(Context context, View convertView, ViewGroup parent); 977f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock Intent getSettingsIntent(); 987f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock void setToggleState(boolean state); 997f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock } 1007f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock 101af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock // safe to call from any thread 102af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 103af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void setCallback(Callback callback) { 104af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHandler.obtainMessage(H.SET_CALLBACK, callback).sendToTarget(); 105af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 106af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 107af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void click() { 108af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHandler.sendEmptyMessage(H.CLICK); 109af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 110af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 111af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void secondaryClick() { 112af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHandler.sendEmptyMessage(H.SECONDARY_CLICK); 113af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 114af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 115c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock public void longClick() { 116c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock mHandler.sendEmptyMessage(H.LONG_CLICK); 117c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock } 118c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock 119af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void showDetail(boolean show) { 120af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHandler.obtainMessage(H.SHOW_DETAIL, show ? 1 : 0, 0).sendToTarget(); 121af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 122af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 123af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final void refreshState() { 124af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock refreshState(null); 125af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 126af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 127af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final void refreshState(Object arg) { 128af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHandler.obtainMessage(H.REFRESH_STATE, arg).sendToTarget(); 129af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 130af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 131af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void userSwitch(int newUserId) { 13232d88e8ead4ccf6b698cac343461cfe12ef168b8Adrian Roos mHandler.obtainMessage(H.USER_SWITCH, newUserId, 0).sendToTarget(); 133af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 134af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 1357f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock public void fireToggleStateChanged(boolean state) { 1367f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock mHandler.obtainMessage(H.TOGGLE_STATE_CHANGED, state ? 1 : 0, 0).sendToTarget(); 1377f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock } 1387f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock 139486b78e42652466f6241eb87d5bed60040db7a25John Spurlock public void fireScanStateChanged(boolean state) { 140486b78e42652466f6241eb87d5bed60040db7a25John Spurlock mHandler.obtainMessage(H.SCAN_STATE_CHANGED, state ? 1 : 0, 0).sendToTarget(); 141486b78e42652466f6241eb87d5bed60040db7a25John Spurlock } 142486b78e42652466f6241eb87d5bed60040db7a25John Spurlock 143bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public void destroy() { 144bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mHandler.sendEmptyMessage(H.DESTROY); 145bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 146bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 147bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public TState getState() { 148bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock return mState; 149bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 150bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 151af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock // call only on tile worker looper 152af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 153af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private void handleSetCallback(Callback callback) { 154af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mCallback = callback; 155af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleRefreshState(null); 156af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 157af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 158af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected void handleSecondaryClick() { 159af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock // optional 160af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 161af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 162c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock protected void handleLongClick() { 163c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock // optional 164c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock } 165c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock 166af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected void handleRefreshState(Object arg) { 167af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleUpdateState(mTmpState, arg); 168af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final boolean changed = mTmpState.copyTo(mState); 169af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (changed) { 170af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleStateChanged(); 171af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 172af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 173af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 174af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private void handleStateChanged() { 1754fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek boolean delayAnnouncement = shouldAnnouncementBeDelayed(); 176af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (mCallback != null) { 177af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mCallback.onStateChanged(mState); 1784fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek if (mAnnounceNextStateChange && !delayAnnouncement) { 1794fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek String announcement = composeChangeAnnouncement(); 1804fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek if (announcement != null) { 1814fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek mCallback.onAnnouncementRequested(announcement); 1824fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek } 1834fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek } 184af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 1854fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek mAnnounceNextStateChange = mAnnounceNextStateChange && delayAnnouncement; 1864fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek } 1874fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek 1884fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek protected boolean shouldAnnouncementBeDelayed() { 1894fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek return false; 1904fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek } 1914fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek 1924fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek protected String composeChangeAnnouncement() { 1934fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek return null; 194af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 195af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 196af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private void handleShowDetail(boolean show) { 197af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (mCallback != null) { 198af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mCallback.onShowDetail(show); 199af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 200af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 201af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 2027f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock private void handleToggleStateChanged(boolean state) { 2037f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock if (mCallback != null) { 2047f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock mCallback.onToggleStateChanged(state); 2057f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock } 2067f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock } 2077f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock 208486b78e42652466f6241eb87d5bed60040db7a25John Spurlock private void handleScanStateChanged(boolean state) { 209486b78e42652466f6241eb87d5bed60040db7a25John Spurlock if (mCallback != null) { 210486b78e42652466f6241eb87d5bed60040db7a25John Spurlock mCallback.onScanStateChanged(state); 211486b78e42652466f6241eb87d5bed60040db7a25John Spurlock } 212486b78e42652466f6241eb87d5bed60040db7a25John Spurlock } 213486b78e42652466f6241eb87d5bed60040db7a25John Spurlock 214af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected void handleUserSwitch(int newUserId) { 215af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleRefreshState(null); 216af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 217af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 218bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock protected void handleDestroy() { 219bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock setListening(false); 220bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mCallback = null; 221bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 222bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 223af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected final class H extends Handler { 224af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private static final int SET_CALLBACK = 1; 225af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private static final int CLICK = 2; 226af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private static final int SECONDARY_CLICK = 3; 227c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private static final int LONG_CLICK = 4; 228c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private static final int REFRESH_STATE = 5; 229c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private static final int SHOW_DETAIL = 6; 230c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private static final int USER_SWITCH = 7; 231c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private static final int TOGGLE_STATE_CHANGED = 8; 232c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private static final int SCAN_STATE_CHANGED = 9; 233c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock private static final int DESTROY = 10; 234af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 235af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock private H(Looper looper) { 236af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock super(looper); 237af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 238af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 239af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 240af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public void handleMessage(Message msg) { 241af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock String name = null; 242af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock try { 243af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (msg.what == SET_CALLBACK) { 244af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock name = "handleSetCallback"; 245af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleSetCallback((QSTile.Callback)msg.obj); 246af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } else if (msg.what == CLICK) { 247af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock name = "handleClick"; 2484fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek mAnnounceNextStateChange = true; 249af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleClick(); 250af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } else if (msg.what == SECONDARY_CLICK) { 251af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock name = "handleSecondaryClick"; 252af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleSecondaryClick(); 253c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock } else if (msg.what == LONG_CLICK) { 254c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock name = "handleLongClick"; 255c247b8f7270dd70ecc36977fcc0530217879f665John Spurlock handleLongClick(); 256af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } else if (msg.what == REFRESH_STATE) { 257af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock name = "handleRefreshState"; 258af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleRefreshState(msg.obj); 259af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } else if (msg.what == SHOW_DETAIL) { 260af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock name = "handleShowDetail"; 261af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleShowDetail(msg.arg1 != 0); 262af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } else if (msg.what == USER_SWITCH) { 263af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock name = "handleUserSwitch"; 264af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock handleUserSwitch(msg.arg1); 2657f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock } else if (msg.what == TOGGLE_STATE_CHANGED) { 2667f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock name = "handleToggleStateChanged"; 2677f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock handleToggleStateChanged(msg.arg1 != 0); 268486b78e42652466f6241eb87d5bed60040db7a25John Spurlock } else if (msg.what == SCAN_STATE_CHANGED) { 269486b78e42652466f6241eb87d5bed60040db7a25John Spurlock name = "handleScanStateChanged"; 270486b78e42652466f6241eb87d5bed60040db7a25John Spurlock handleScanStateChanged(msg.arg1 != 0); 271bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } else if (msg.what == DESTROY) { 272bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock name = "handleDestroy"; 273bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock handleDestroy(); 274bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } else { 275bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock throw new IllegalArgumentException("Unknown msg: " + msg.what); 276af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 277af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } catch (Throwable t) { 278af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final String error = "Error in " + name; 279af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock Log.w(TAG, error, t); 280af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock mHost.warn(error, t); 281af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 282af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 283af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 284af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 285af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public interface Callback { 286af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock void onStateChanged(State state); 287af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock void onShowDetail(boolean show); 2887f8f22a53005f776c8ee4d299e748e74b077ffd9John Spurlock void onToggleStateChanged(boolean state); 289486b78e42652466f6241eb87d5bed60040db7a25John Spurlock void onScanStateChanged(boolean state); 2904fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek void onAnnouncementRequested(CharSequence announcement); 291af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 292af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 293af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public interface Host { 294af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock void startSettingsActivity(Intent intent); 295af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock void warn(String message, Throwable t); 296af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock void collapsePanels(); 297af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock Looper getLooper(); 298af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock Context getContext(); 299bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock Collection<QSTile<?>> getTiles(); 300bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock void setCallback(Callback callback); 301af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock BluetoothController getBluetoothController(); 302af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock LocationController getLocationController(); 303af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock RotationLockController getRotationLockController(); 304af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock NetworkController getNetworkController(); 305af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock ZenModeController getZenModeController(); 30651e4dc0a153bd0da197728ce6fe34df662b1cea2Jason Monk HotspotController getHotspotController(); 307af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock CastController getCastController(); 308b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos FlashlightController getFlashlightController(); 309657c62c31ecdade22f67f13102c2fb19765cbe13John Spurlock KeyguardMonitor getKeyguardMonitor(); 310bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 311bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock public interface Callback { 312bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock void onTilesChanged(); 313bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 314af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 315af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 3162d695813b44690ca146f95939acb00f0c14dac29John Spurlock public static abstract class Icon { 3172d695813b44690ca146f95939acb00f0c14dac29John Spurlock abstract public Drawable getDrawable(Context context); 3182d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3192d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 3202d695813b44690ca146f95939acb00f0c14dac29John Spurlock public int hashCode() { 3212d695813b44690ca146f95939acb00f0c14dac29John Spurlock return Icon.class.hashCode(); 3222d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3232d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3242d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3252d695813b44690ca146f95939acb00f0c14dac29John Spurlock public static class ResourceIcon extends Icon { 3262d695813b44690ca146f95939acb00f0c14dac29John Spurlock private static final SparseArray<Icon> ICONS = new SparseArray<Icon>(); 3272d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3282d695813b44690ca146f95939acb00f0c14dac29John Spurlock private final int mResId; 3292d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3302d695813b44690ca146f95939acb00f0c14dac29John Spurlock private ResourceIcon(int resId) { 3312d695813b44690ca146f95939acb00f0c14dac29John Spurlock mResId = resId; 3322d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3332d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3342d695813b44690ca146f95939acb00f0c14dac29John Spurlock public static Icon get(int resId) { 3352d695813b44690ca146f95939acb00f0c14dac29John Spurlock Icon icon = ICONS.get(resId); 3362d695813b44690ca146f95939acb00f0c14dac29John Spurlock if (icon == null) { 3372d695813b44690ca146f95939acb00f0c14dac29John Spurlock icon = new ResourceIcon(resId); 3382d695813b44690ca146f95939acb00f0c14dac29John Spurlock ICONS.put(resId, icon); 3392d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3402d695813b44690ca146f95939acb00f0c14dac29John Spurlock return icon; 3412d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3422d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3432d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 3442d695813b44690ca146f95939acb00f0c14dac29John Spurlock public Drawable getDrawable(Context context) { 3452d695813b44690ca146f95939acb00f0c14dac29John Spurlock return context.getDrawable(mResId); 3462d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3472d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3482d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 3492d695813b44690ca146f95939acb00f0c14dac29John Spurlock public boolean equals(Object o) { 3502d695813b44690ca146f95939acb00f0c14dac29John Spurlock return o instanceof ResourceIcon && ((ResourceIcon) o).mResId == mResId; 3512d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3522d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3532d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 3542d695813b44690ca146f95939acb00f0c14dac29John Spurlock public String toString() { 3552d695813b44690ca146f95939acb00f0c14dac29John Spurlock return String.format("ResourceIcon[resId=0x%08x]", mResId); 3562d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3572d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3582d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3592d695813b44690ca146f95939acb00f0c14dac29John Spurlock protected class AnimationIcon extends ResourceIcon { 3602d695813b44690ca146f95939acb00f0c14dac29John Spurlock private boolean mAllowAnimation; 3612d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3622d695813b44690ca146f95939acb00f0c14dac29John Spurlock public AnimationIcon(int resId) { 3632d695813b44690ca146f95939acb00f0c14dac29John Spurlock super(resId); 3642d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3652d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3662d695813b44690ca146f95939acb00f0c14dac29John Spurlock public void setAllowAnimation(boolean allowAnimation) { 3672d695813b44690ca146f95939acb00f0c14dac29John Spurlock mAllowAnimation = allowAnimation; 3682d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3692d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3702d695813b44690ca146f95939acb00f0c14dac29John Spurlock @Override 3712d695813b44690ca146f95939acb00f0c14dac29John Spurlock public Drawable getDrawable(Context context) { 3722d695813b44690ca146f95939acb00f0c14dac29John Spurlock // workaround: get a clean state for every new AVD 3732d695813b44690ca146f95939acb00f0c14dac29John Spurlock final AnimatedVectorDrawable d = (AnimatedVectorDrawable) super.getDrawable(context) 3742d695813b44690ca146f95939acb00f0c14dac29John Spurlock .getConstantState().newDrawable(); 3752d695813b44690ca146f95939acb00f0c14dac29John Spurlock d.start(); 3762d695813b44690ca146f95939acb00f0c14dac29John Spurlock if (mAllowAnimation) { 3772d695813b44690ca146f95939acb00f0c14dac29John Spurlock mAllowAnimation = false; 3782d695813b44690ca146f95939acb00f0c14dac29John Spurlock } else { 3792d695813b44690ca146f95939acb00f0c14dac29John Spurlock d.stop(); // skip directly to end state 3802d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3812d695813b44690ca146f95939acb00f0c14dac29John Spurlock return d; 3822d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3832d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3842d695813b44690ca146f95939acb00f0c14dac29John Spurlock 3852d695813b44690ca146f95939acb00f0c14dac29John Spurlock protected enum UserBoolean { 3862d695813b44690ca146f95939acb00f0c14dac29John Spurlock USER_TRUE(true, true), 3872d695813b44690ca146f95939acb00f0c14dac29John Spurlock USER_FALSE(true, false), 3882d695813b44690ca146f95939acb00f0c14dac29John Spurlock BACKGROUND_TRUE(false, true), 3892d695813b44690ca146f95939acb00f0c14dac29John Spurlock BACKGROUND_FALSE(false, false); 3902d695813b44690ca146f95939acb00f0c14dac29John Spurlock public final boolean value; 3912d695813b44690ca146f95939acb00f0c14dac29John Spurlock public final boolean userInitiated; 3922d695813b44690ca146f95939acb00f0c14dac29John Spurlock private UserBoolean(boolean userInitiated, boolean value) { 3932d695813b44690ca146f95939acb00f0c14dac29John Spurlock this.value = value; 3942d695813b44690ca146f95939acb00f0c14dac29John Spurlock this.userInitiated = userInitiated; 3952d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3962d695813b44690ca146f95939acb00f0c14dac29John Spurlock } 3972d695813b44690ca146f95939acb00f0c14dac29John Spurlock 398af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public static class State { 399af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean visible; 4002d695813b44690ca146f95939acb00f0c14dac29John Spurlock public Icon icon; 401af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public String label; 402af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public String contentDescription; 403e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek public String dualLabelContentDescription; 40406d3bca095aecbb7542ebf4bdaa56b368261dd9dSelim Cinek public boolean autoMirrorDrawable = true; 405af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 406af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean copyTo(State other) { 407af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (other == null) throw new IllegalArgumentException(); 408af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock if (!other.getClass().equals(getClass())) throw new IllegalArgumentException(); 409af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final boolean changed = other.visible != visible 410af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock || !Objects.equals(other.icon, icon) 411af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock || !Objects.equals(other.label, label) 412e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek || !Objects.equals(other.contentDescription, contentDescription) 41306d3bca095aecbb7542ebf4bdaa56b368261dd9dSelim Cinek || !Objects.equals(other.autoMirrorDrawable, autoMirrorDrawable) 414e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek || !Objects.equals(other.dualLabelContentDescription, 415e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek dualLabelContentDescription); 416af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock other.visible = visible; 417af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock other.icon = icon; 418af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock other.label = label; 419af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock other.contentDescription = contentDescription; 420e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek other.dualLabelContentDescription = dualLabelContentDescription; 42106d3bca095aecbb7542ebf4bdaa56b368261dd9dSelim Cinek other.autoMirrorDrawable = autoMirrorDrawable; 422af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return changed; 423af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 424af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 425af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 426af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public String toString() { 427af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return toStringBuilder().toString(); 428af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 429af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 430af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected StringBuilder toStringBuilder() { 4312d695813b44690ca146f95939acb00f0c14dac29John Spurlock final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('['); 432af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock sb.append("visible=").append(visible); 433af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock sb.append(",icon=").append(icon); 434af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock sb.append(",label=").append(label); 435af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock sb.append(",contentDescription=").append(contentDescription); 436e5557a972ca190cb82026a5dd0c53f4d119fa05aSelim Cinek sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription); 43706d3bca095aecbb7542ebf4bdaa56b368261dd9dSelim Cinek sb.append(",autoMirrorDrawable=").append(autoMirrorDrawable); 438af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return sb.append(']'); 439af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 440af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 441af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 442af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public static class BooleanState extends State { 443af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean value; 444af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 445af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 446af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean copyTo(State other) { 447af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final BooleanState o = (BooleanState) other; 448af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final boolean changed = super.copyTo(other) || o.value != value; 449af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock o.value = value; 450af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return changed; 451af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 452af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 453af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 454af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected StringBuilder toStringBuilder() { 455af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final StringBuilder rt = super.toStringBuilder(); 456af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock rt.insert(rt.length() - 1, ",value=" + value); 457af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return rt; 458af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 459af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 460af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 461af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public static final class SignalState extends State { 462af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean enabled; 463af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean connected; 464af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean activityIn; 465af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean activityOut; 466af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public int overlayIconId; 467899f439a29ab1e609e7ba2aea3e9de3afef35c50John Spurlock public boolean filter; 468c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi public boolean isOverlayIconWide; 469af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 470af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 471af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock public boolean copyTo(State other) { 472af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final SignalState o = (SignalState) other; 473af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final boolean changed = o.enabled != enabled 474af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock || o.connected != connected || o.activityIn != activityIn 475af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock || o.activityOut != activityOut 476c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi || o.overlayIconId != overlayIconId 477c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi || o.isOverlayIconWide != isOverlayIconWide; 478af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock o.enabled = enabled; 479af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock o.connected = connected; 480af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock o.activityIn = activityIn; 481af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock o.activityOut = activityOut; 482af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock o.overlayIconId = overlayIconId; 483899f439a29ab1e609e7ba2aea3e9de3afef35c50John Spurlock o.filter = filter; 484c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi o.isOverlayIconWide = isOverlayIconWide; 485af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return super.copyTo(other) || changed; 486af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 487af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock 488af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock @Override 489af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock protected StringBuilder toStringBuilder() { 490af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock final StringBuilder rt = super.toStringBuilder(); 491af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock rt.insert(rt.length() - 1, ",enabled=" + enabled); 492af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock rt.insert(rt.length() - 1, ",connected=" + connected); 493af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock rt.insert(rt.length() - 1, ",activityIn=" + activityIn); 494af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock rt.insert(rt.length() - 1, ",activityOut=" + activityOut); 495af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock rt.insert(rt.length() - 1, ",overlayIconId=" + overlayIconId); 496899f439a29ab1e609e7ba2aea3e9de3afef35c50John Spurlock rt.insert(rt.length() - 1, ",filter=" + filter); 497c737b9bd5a0bc60fd92150d55f8ddb530697b987Jorim Jaggi rt.insert(rt.length() - 1, ",wideOverlayIcon=" + isOverlayIconWide); 498af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock return rt; 499af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 500af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock } 501af8d6c44f06d2f8baac2c5774a9efdae3fc36797John Spurlock} 502