1702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk/*
2702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * Copyright (C) 2017 The Android Open Source Project
3702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk *
4702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * except in compliance with the License. You may obtain a copy of the License at
6702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk *
7702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk *      http://www.apache.org/licenses/LICENSE-2.0
8702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk *
9702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * Unless required by applicable law or agreed to in writing, software distributed under the
10702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * KIND, either express or implied. See the License for the specific language governing
12702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk * permissions and limitations under the License.
13702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk */
14702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
15702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkpackage com.android.systemui.plugins.qs;
16702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
17702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport android.content.Context;
18702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport android.graphics.drawable.Drawable;
19cb4b31d396df49bd55db64b1c40122656c6ec534Jason Monkimport android.metrics.LogMaker;
20702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport android.service.quicksettings.Tile;
21702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
22702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.annotations.DependsOn;
23702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.annotations.ProvidesInterface;
24702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.qs.QSTile.Callback;
25702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.qs.QSTile.Icon;
26702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport com.android.systemui.plugins.qs.QSTile.State;
27702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
28702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkimport java.util.Objects;
29702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
30702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk@ProvidesInterface(version = QSTile.VERSION)
31702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk@DependsOn(target = QSIconView.class)
32702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk@DependsOn(target = DetailAdapter.class)
33702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk@DependsOn(target = Callback.class)
34702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk@DependsOn(target = Icon.class)
35702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk@DependsOn(target = State.class)
36702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monkpublic interface QSTile {
37702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    int VERSION = 1;
38702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
39702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    DetailAdapter getDetailAdapter();
40702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    String getTileSpec();
41702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
42702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    boolean isAvailable();
43702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void setTileSpec(String tileSpec);
44702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
45702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void clearState();
46702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void refreshState();
47702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
48702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void addCallback(Callback callback);
49702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void removeCallback(Callback callback);
50702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void removeCallbacks();
51702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
52702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    QSIconView createTileView(Context context);
53702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
54702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void click();
55702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void secondaryClick();
56702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void longClick();
57702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
58702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void userSwitch(int currentUser);
59702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    int getMetricsCategory();
60702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
61702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void setListening(Object client, boolean listening);
62702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void setDetailListening(boolean show);
63702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
64702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    void destroy();
65702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
66702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    CharSequence getTileLabel();
67702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
68702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    State getState();
69702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
70cb4b31d396df49bd55db64b1c40122656c6ec534Jason Monk    default LogMaker populate(LogMaker logMaker) {
71cb4b31d396df49bd55db64b1c40122656c6ec534Jason Monk        return logMaker;
72cb4b31d396df49bd55db64b1c40122656c6ec534Jason Monk    }
73cb4b31d396df49bd55db64b1c40122656c6ec534Jason Monk
74702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    @ProvidesInterface(version = Callback.VERSION)
75702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    public interface Callback {
76702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public static final int VERSION = 1;
77702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        void onStateChanged(State state);
78702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        void onShowDetail(boolean show);
79702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        void onToggleStateChanged(boolean state);
80702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        void onScanStateChanged(boolean state);
81702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        void onAnnouncementRequested(CharSequence announcement);
82702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    }
83702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
84702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    @ProvidesInterface(version = Icon.VERSION)
85702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    public static abstract class Icon {
86702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public static final int VERSION = 1;
87702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        abstract public Drawable getDrawable(Context context);
88702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
89702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public Drawable getInvisibleDrawable(Context context) {
90702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return getDrawable(context);
91702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
92702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
93702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
94702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public int hashCode() {
95702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return Icon.class.hashCode();
96702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
97702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
98702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public int getPadding() {
99702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return 0;
100702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
101702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    }
102702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
103702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    @ProvidesInterface(version = State.VERSION)
104702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    public static class State {
105702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public static final int VERSION = 1;
106702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public Icon icon;
107702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public int state = Tile.STATE_ACTIVE;
108702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public CharSequence label;
109702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public CharSequence contentDescription;
110702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public CharSequence dualLabelContentDescription;
111702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean disabledByPolicy;
112702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean dualTarget = false;
113e645aee45a7784d772e4bdf846dd2e77335f30f2Jason Monk        public boolean isTransient = false;
114702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public String expandedAccessibilityClassName;
115702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
116702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean copyTo(State other) {
117702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            if (other == null) throw new IllegalArgumentException();
118702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
119702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final boolean changed = !Objects.equals(other.icon, icon)
120702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                    || !Objects.equals(other.label, label)
121702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                    || !Objects.equals(other.contentDescription, contentDescription)
122702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                    || !Objects.equals(other.dualLabelContentDescription,
123702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                            dualLabelContentDescription)
124702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                    || !Objects.equals(other.expandedAccessibilityClassName,
125702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                            expandedAccessibilityClassName)
126702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                    || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
127702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                    || !Objects.equals(other.state, state)
128e645aee45a7784d772e4bdf846dd2e77335f30f2Jason Monk                    || !Objects.equals(other.isTransient, isTransient)
129702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk                    || !Objects.equals(other.dualTarget, dualTarget);
130702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.icon = icon;
131702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.label = label;
132702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.contentDescription = contentDescription;
133702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.dualLabelContentDescription = dualLabelContentDescription;
134702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.expandedAccessibilityClassName = expandedAccessibilityClassName;
135702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.disabledByPolicy = disabledByPolicy;
136702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.state = state;
137702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            other.dualTarget = dualTarget;
138e645aee45a7784d772e4bdf846dd2e77335f30f2Jason Monk            other.isTransient = isTransient;
139702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return changed;
140702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
141702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
142702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
143702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public String toString() {
144702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return toStringBuilder().toString();
145702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
146702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
147702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        protected StringBuilder toStringBuilder() {
148702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
149702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",icon=").append(icon);
150702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",label=").append(label);
151702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",contentDescription=").append(contentDescription);
152702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
153702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
154702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",disabledByPolicy=").append(disabledByPolicy);
155702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",dualTarget=").append(dualTarget);
156e645aee45a7784d772e4bdf846dd2e77335f30f2Jason Monk            sb.append(",isTransient=").append(isTransient);
157702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            sb.append(",state=").append(state);
158702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return sb.append(']');
159702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
160702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
161702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public State copy() {
162702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            State state = new State();
163702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            copyTo(state);
164702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return state;
165702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
166702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    }
167702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
168702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    @ProvidesInterface(version = BooleanState.VERSION)
169702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    public static class BooleanState extends State {
170702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public static final int VERSION = 1;
171702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean value;
172702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
173702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
174702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean copyTo(State other) {
175702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final BooleanState o = (BooleanState) other;
176702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final boolean changed = super.copyTo(other) || o.value != value;
177702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            o.value = value;
178702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return changed;
179702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
180702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
181702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
182702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        protected StringBuilder toStringBuilder() {
183702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final StringBuilder rt = super.toStringBuilder();
184702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            rt.insert(rt.length() - 1, ",value=" + value);
185702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return rt;
186702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
187702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
188702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
189702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public State copy() {
190702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            BooleanState state = new BooleanState();
191702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            copyTo(state);
192702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return state;
193702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
194702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    }
195702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
196702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    @ProvidesInterface(version = SignalState.VERSION)
197702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    public static final class SignalState extends BooleanState {
198702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public static final int VERSION = 1;
199702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean activityIn;
200702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean activityOut;
20101df36f37fc470d3fd8c120b09cc4e7943cfacfbJason Monk        public boolean isOverlayIconWide;
20201df36f37fc470d3fd8c120b09cc4e7943cfacfbJason Monk        public int overlayIconId;
203702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
204702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
205702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean copyTo(State other) {
206702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final SignalState o = (SignalState) other;
207702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final boolean changed = o.activityIn != activityIn
20801df36f37fc470d3fd8c120b09cc4e7943cfacfbJason Monk                    || o.activityOut != activityOut
20901df36f37fc470d3fd8c120b09cc4e7943cfacfbJason Monk                    || o.isOverlayIconWide != isOverlayIconWide
21001df36f37fc470d3fd8c120b09cc4e7943cfacfbJason Monk                    || o.overlayIconId != overlayIconId;
211702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            o.activityIn = activityIn;
212702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            o.activityOut = activityOut;
21301df36f37fc470d3fd8c120b09cc4e7943cfacfbJason Monk            o.isOverlayIconWide = isOverlayIconWide;
21401df36f37fc470d3fd8c120b09cc4e7943cfacfbJason Monk            o.overlayIconId = overlayIconId;
215702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return super.copyTo(other) || changed;
216702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
217702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
218702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
219702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        protected StringBuilder toStringBuilder() {
220702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final StringBuilder rt = super.toStringBuilder();
221702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            rt.insert(rt.length() - 1, ",activityIn=" + activityIn);
222702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
223702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return rt;
224702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
225702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
226702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
227702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public State copy() {
228702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            SignalState state = new SignalState();
229702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            copyTo(state);
230702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return state;
231702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
232702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    }
233702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
234702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
235702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    @ProvidesInterface(version = AirplaneBooleanState.VERSION)
236702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    public static class AirplaneBooleanState extends BooleanState {
237702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public static final int VERSION = 1;
238702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean isAirplaneMode;
239702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
240702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        @Override
241702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public boolean copyTo(State other) {
242702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final AirplaneBooleanState o = (AirplaneBooleanState) other;
243702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            final boolean changed = super.copyTo(other) || o.isAirplaneMode != isAirplaneMode;
244702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            o.isAirplaneMode = isAirplaneMode;
245702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return changed;
246702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
247702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
248702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        public State copy() {
249702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            AirplaneBooleanState state = new AirplaneBooleanState();
250702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            copyTo(state);
251702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk            return state;
252702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk        }
253702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk    }
254702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk
255702e2ebf9fbfb715c1d9b716683c9e4d182b575eJason Monk}
256