• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.systemui.plugins.qs;
16 
17 import android.annotation.NonNull;
18 import android.content.Context;
19 import android.graphics.drawable.Drawable;
20 import android.metrics.LogMaker;
21 import android.service.quicksettings.Tile;
22 import android.view.View;
23 
24 import androidx.annotation.Nullable;
25 
26 import com.android.internal.logging.InstanceId;
27 import com.android.systemui.plugins.annotations.DependsOn;
28 import com.android.systemui.plugins.annotations.ProvidesInterface;
29 import com.android.systemui.plugins.qs.QSTile.Callback;
30 import com.android.systemui.plugins.qs.QSTile.Icon;
31 import com.android.systemui.plugins.qs.QSTile.State;
32 
33 import java.util.Objects;
34 import java.util.function.Supplier;
35 
36 @ProvidesInterface(version = QSTile.VERSION)
37 @DependsOn(target = QSIconView.class)
38 @DependsOn(target = DetailAdapter.class)
39 @DependsOn(target = Callback.class)
40 @DependsOn(target = Icon.class)
41 @DependsOn(target = State.class)
42 public interface QSTile {
43     int VERSION = 1;
44 
getDetailAdapter()45     DetailAdapter getDetailAdapter();
getTileSpec()46     String getTileSpec();
47 
isAvailable()48     boolean isAvailable();
setTileSpec(String tileSpec)49     void setTileSpec(String tileSpec);
50 
clearState()51     @Deprecated default void clearState() {}
refreshState()52     void refreshState();
53 
addCallback(Callback callback)54     void addCallback(Callback callback);
removeCallback(Callback callback)55     void removeCallback(Callback callback);
removeCallbacks()56     void removeCallbacks();
57 
createTileView(Context context)58     QSIconView createTileView(Context context);
59 
60     /**
61      * The tile was clicked.
62      *
63      * @param view The view that was clicked.
64      */
click(@ullable View view)65     void click(@Nullable View view);
66 
67     /**
68      * The tile secondary click was triggered.
69      *
70      * @param view The view that was clicked.
71      */
secondaryClick(@ullable View view)72     void secondaryClick(@Nullable View view);
73 
74     /**
75      * The tile was long clicked.
76      *
77      * @param view The view that was clicked.
78      */
longClick(@ullable View view)79     void longClick(@Nullable View view);
80 
userSwitch(int currentUser)81     void userSwitch(int currentUser);
getMetricsCategory()82     int getMetricsCategory();
83 
setListening(Object client, boolean listening)84     void setListening(Object client, boolean listening);
setDetailListening(boolean show)85     void setDetailListening(boolean show);
86 
destroy()87     void destroy();
88 
getTileLabel()89     CharSequence getTileLabel();
90 
getState()91     State getState();
92 
populate(LogMaker logMaker)93     default LogMaker populate(LogMaker logMaker) {
94         return logMaker;
95     }
96 
97     /**
98      * Return a string to be used to identify the tile in UiEvents.
99      */
getMetricsSpec()100     default String getMetricsSpec() {
101         return getClass().getSimpleName();
102     }
103 
104     /**
105      * Return an {@link InstanceId} to be used to identify the tile in UiEvents.
106      */
getInstanceId()107     InstanceId getInstanceId();
108 
isTileReady()109     default boolean isTileReady() {
110         return false;
111     }
112 
113     @ProvidesInterface(version = Callback.VERSION)
114     public interface Callback {
115         public static final int VERSION = 1;
onStateChanged(State state)116         void onStateChanged(State state);
onShowDetail(boolean show)117         void onShowDetail(boolean show);
onToggleStateChanged(boolean state)118         void onToggleStateChanged(boolean state);
onScanStateChanged(boolean state)119         void onScanStateChanged(boolean state);
onAnnouncementRequested(CharSequence announcement)120         void onAnnouncementRequested(CharSequence announcement);
121     }
122 
123     @ProvidesInterface(version = Icon.VERSION)
124     public static abstract class Icon {
125         public static final int VERSION = 1;
getDrawable(Context context)126         abstract public Drawable getDrawable(Context context);
127 
getInvisibleDrawable(Context context)128         public Drawable getInvisibleDrawable(Context context) {
129             return getDrawable(context);
130         }
131 
132         @Override
hashCode()133         public int hashCode() {
134             return Icon.class.hashCode();
135         }
136 
getPadding()137         public int getPadding() {
138             return 0;
139         }
140 
141         @Override
142         @NonNull
toString()143         public String toString() {
144             return "Icon";
145         }
146     }
147 
148     @ProvidesInterface(version = State.VERSION)
149     public static class State {
150         public static final int VERSION = 1;
151         public static final int DEFAULT_STATE = Tile.STATE_ACTIVE;
152 
153         public Icon icon;
154         public Supplier<Icon> iconSupplier;
155         public int state = DEFAULT_STATE;
156         public CharSequence label;
157         public CharSequence secondaryLabel;
158         public CharSequence contentDescription;
159         public CharSequence stateDescription;
160         public CharSequence dualLabelContentDescription;
161         public boolean disabledByPolicy;
162         public boolean dualTarget = false;
163         public boolean isTransient = false;
164         public String expandedAccessibilityClassName;
165         public SlashState slash;
166         public boolean handlesLongClick = true;
167         public boolean showRippleEffect = true;
168         public Drawable sideViewCustomDrawable;
169         public String spec;
170 
copyTo(State other)171         public boolean copyTo(State other) {
172             if (other == null) throw new IllegalArgumentException();
173             if (!other.getClass().equals(getClass())) throw new IllegalArgumentException();
174             final boolean changed = !Objects.equals(other.spec, spec)
175                     || !Objects.equals(other.icon, icon)
176                     || !Objects.equals(other.iconSupplier, iconSupplier)
177                     || !Objects.equals(other.label, label)
178                     || !Objects.equals(other.secondaryLabel, secondaryLabel)
179                     || !Objects.equals(other.contentDescription, contentDescription)
180                     || !Objects.equals(other.stateDescription, stateDescription)
181                     || !Objects.equals(other.dualLabelContentDescription,
182                             dualLabelContentDescription)
183                     || !Objects.equals(other.expandedAccessibilityClassName,
184                             expandedAccessibilityClassName)
185                     || !Objects.equals(other.disabledByPolicy, disabledByPolicy)
186                     || !Objects.equals(other.state, state)
187                     || !Objects.equals(other.isTransient, isTransient)
188                     || !Objects.equals(other.dualTarget, dualTarget)
189                     || !Objects.equals(other.slash, slash)
190                     || !Objects.equals(other.handlesLongClick, handlesLongClick)
191                     || !Objects.equals(other.showRippleEffect, showRippleEffect)
192                     || !Objects.equals(other.sideViewCustomDrawable, sideViewCustomDrawable);
193             other.spec = spec;
194             other.icon = icon;
195             other.iconSupplier = iconSupplier;
196             other.label = label;
197             other.secondaryLabel = secondaryLabel;
198             other.contentDescription = contentDescription;
199             other.stateDescription = stateDescription;
200             other.dualLabelContentDescription = dualLabelContentDescription;
201             other.expandedAccessibilityClassName = expandedAccessibilityClassName;
202             other.disabledByPolicy = disabledByPolicy;
203             other.state = state;
204             other.dualTarget = dualTarget;
205             other.isTransient = isTransient;
206             other.slash = slash != null ? slash.copy() : null;
207             other.handlesLongClick = handlesLongClick;
208             other.showRippleEffect = showRippleEffect;
209             other.sideViewCustomDrawable = sideViewCustomDrawable;
210             return changed;
211         }
212 
213         @Override
toString()214         public String toString() {
215             return toStringBuilder().toString();
216         }
217 
218         // Used in dumps to determine current state of a tile.
219         // This string may be used for CTS testing of tiles, so removing elements is discouraged.
toStringBuilder()220         protected StringBuilder toStringBuilder() {
221             final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).append('[');
222             sb.append("spec=").append(spec);
223             sb.append(",icon=").append(icon);
224             sb.append(",iconSupplier=").append(iconSupplier);
225             sb.append(",label=").append(label);
226             sb.append(",secondaryLabel=").append(secondaryLabel);
227             sb.append(",contentDescription=").append(contentDescription);
228             sb.append(",stateDescription=").append(stateDescription);
229             sb.append(",dualLabelContentDescription=").append(dualLabelContentDescription);
230             sb.append(",expandedAccessibilityClassName=").append(expandedAccessibilityClassName);
231             sb.append(",disabledByPolicy=").append(disabledByPolicy);
232             sb.append(",dualTarget=").append(dualTarget);
233             sb.append(",isTransient=").append(isTransient);
234             sb.append(",state=").append(state);
235             sb.append(",slash=\"").append(slash).append("\"");
236             sb.append(",sideViewCustomDrawable=").append(sideViewCustomDrawable);
237             return sb.append(']');
238         }
239 
copy()240         public State copy() {
241             State state = new State();
242             copyTo(state);
243             return state;
244         }
245     }
246 
247     @ProvidesInterface(version = BooleanState.VERSION)
248     public static class BooleanState extends State {
249         public static final int VERSION = 1;
250         public boolean value;
251         public boolean forceExpandIcon;
252 
253         @Override
copyTo(State other)254         public boolean copyTo(State other) {
255             final BooleanState o = (BooleanState) other;
256             final boolean changed = super.copyTo(other)
257                     || o.value != value
258                     || o.forceExpandIcon != forceExpandIcon;
259             o.value = value;
260             o.forceExpandIcon = forceExpandIcon;
261             return changed;
262         }
263 
264         @Override
toStringBuilder()265         protected StringBuilder toStringBuilder() {
266             final StringBuilder rt = super.toStringBuilder();
267             rt.insert(rt.length() - 1, ",value=" + value);
268             rt.insert(rt.length() - 1, ",forceExpandIcon=" + forceExpandIcon);
269             return rt;
270         }
271 
272         @Override
copy()273         public State copy() {
274             BooleanState state = new BooleanState();
275             copyTo(state);
276             return state;
277         }
278     }
279 
280     @ProvidesInterface(version = SignalState.VERSION)
281     public static final class SignalState extends BooleanState {
282         public static final int VERSION = 1;
283         public boolean activityIn;
284         public boolean activityOut;
285         public boolean isOverlayIconWide;
286         public int overlayIconId;
287 
288         @Override
copyTo(State other)289         public boolean copyTo(State other) {
290             final SignalState o = (SignalState) other;
291             final boolean changed = o.activityIn != activityIn
292                     || o.activityOut != activityOut
293                     || o.isOverlayIconWide != isOverlayIconWide
294                     || o.overlayIconId != overlayIconId;
295             o.activityIn = activityIn;
296             o.activityOut = activityOut;
297             o.isOverlayIconWide = isOverlayIconWide;
298             o.overlayIconId = overlayIconId;
299             return super.copyTo(other) || changed;
300         }
301 
302         @Override
toStringBuilder()303         protected StringBuilder toStringBuilder() {
304             final StringBuilder rt = super.toStringBuilder();
305             rt.insert(rt.length() - 1, ",activityIn=" + activityIn);
306             rt.insert(rt.length() - 1, ",activityOut=" + activityOut);
307             return rt;
308         }
309 
310         @Override
copy()311         public State copy() {
312             SignalState state = new SignalState();
313             copyTo(state);
314             return state;
315         }
316     }
317 
318     @ProvidesInterface(version = SlashState.VERSION)
319     public static class SlashState {
320         public static final int VERSION = 2;
321 
322         public boolean isSlashed;
323         public float rotation;
324 
325         @Override
toString()326         public String toString() {
327             return "isSlashed=" + isSlashed + ",rotation=" + rotation;
328         }
329 
330         @Override
equals(Object o)331         public boolean equals(Object o) {
332             if (o == null) return false;
333             try {
334                 return (((SlashState) o).rotation == rotation)
335                         && (((SlashState) o).isSlashed == isSlashed);
336             } catch (ClassCastException e) {
337                 return false;
338             }
339         }
340 
copy()341         public SlashState copy() {
342             SlashState state = new SlashState();
343             state.rotation = rotation;
344             state.isSlashed = isSlashed;
345             return state;
346         }
347     }
348 }
349