1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.slice.widget;
18 
19 import androidx.annotation.IntDef;
20 import androidx.annotation.RestrictTo;
21 
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 
25 /**
26  * Represents information associated with a logged event on {@link SliceView}.
27  */
28 public class EventInfo {
29 
30     /**
31      * @hide
32      */
33     @RestrictTo(RestrictTo.Scope.LIBRARY)
34     @IntDef({
35             ROW_TYPE_SHORTCUT,
36             ROW_TYPE_LIST,
37             ROW_TYPE_GRID,
38             ROW_TYPE_MESSAGING,
39             ROW_TYPE_TOGGLE,
40             ROW_TYPE_SLIDER,
41             ROW_TYPE_PROGRESS,
42     })
43     @Retention(RetentionPolicy.SOURCE)
44     public @interface SliceRowType {}
45 
46     /**
47      * Indicates the slice is represented as a shortcut.
48      */
49     public static final int ROW_TYPE_SHORTCUT = -1;
50     /**
51      * Indicates the row is represented in a list template.
52      */
53     public static final int ROW_TYPE_LIST = 0;
54     /**
55      * Indicates the row is represented in a grid template.
56      */
57     public static final int ROW_TYPE_GRID = 1;
58     /**
59      * Indicates the row is represented as a messaging template.
60      */
61     public static final int ROW_TYPE_MESSAGING = 2;
62     /**
63      * Indicates the row represents a toggleable item.
64      */
65     public static final int ROW_TYPE_TOGGLE = 3;
66     /**
67      * Indicates the row represents an range input slider.
68      */
69     public static final int ROW_TYPE_SLIDER = 4;
70     /**
71      * Indicates the row represents a progress indicator.
72      */
73     public static final int ROW_TYPE_PROGRESS = 5;
74 
75     /**
76      * @hide
77      */
78     @RestrictTo(RestrictTo.Scope.LIBRARY)
79     @IntDef({
80             ACTION_TYPE_TOGGLE, ACTION_TYPE_BUTTON, ACTION_TYPE_SLIDER, ACTION_TYPE_CONTENT,
81             ACTION_TYPE_SEE_MORE
82     })
83     @Retention(RetentionPolicy.SOURCE)
84     public @interface SliceActionType{}
85 
86     /**
87      * Indicates the event was an interaction with a toggle. Check {@link EventInfo#state} to
88      * see the new state of the toggle.
89      */
90     public static final int ACTION_TYPE_TOGGLE = 0;
91     /**
92      * Indicates the event was an interaction with a button. Check {@link EventInfo#actionPosition}
93      * to see where on the card the button is placed.
94      */
95     public static final int ACTION_TYPE_BUTTON = 1;
96     /**
97      * Indicates the event was an interaction with a slider. Check {@link EventInfo#state} to
98      * see the new state of the slider.
99      */
100     public static final int ACTION_TYPE_SLIDER = 2;
101     /**
102      * Indicates the event was a tap on the entire row.
103      */
104     public static final int ACTION_TYPE_CONTENT = 3;
105     /**
106      * Indicates the event was a tap on a see more button.
107      */
108     public static final int ACTION_TYPE_SEE_MORE = 4;
109 
110     /**
111      * @hide
112      */
113     @RestrictTo(RestrictTo.Scope.LIBRARY)
114     @IntDef({
115             POSITION_START, POSITION_END, POSITION_CELL
116     })
117     @Retention(RetentionPolicy.SOURCE)
118     public @interface SliceButtonPosition{}
119 
120     /**
121      * Indicates the event was an interaction with a button positioned at the start of the row.
122      */
123     public static final int POSITION_START = 0;
124     /**
125      * Indicates the event was an interaction with a button positioned at the end of the row,
126      * potentially grouped with other buttons.
127      */
128     public static final int POSITION_END = 1;
129     /**
130      * Indicates the event was an interaction with a button positioned in a grid cell.
131      */
132     public static final int POSITION_CELL = 2;
133 
134     /**
135      * Indicates the state of a toggle is off.
136      */
137     public static final int STATE_OFF = 0;
138     /**
139      * Indicates the state of a toggle is on.
140      */
141     public static final int STATE_ON = 1;
142 
143     /**
144      * The display mode of the slice being interacted with.
145      */
146     public @SliceView.SliceMode int sliceMode;
147     /**
148      * The type of action that occurred.
149      */
150     public @SliceActionType int actionType;
151     /**
152      * The template type of the row that was interacted with in the slice.
153      */
154     public @SliceRowType int rowTemplateType;
155     /**
156      * Index of the row that was interacted with in the slice.
157      */
158     public int rowIndex;
159     /**
160      * If multiple buttons are presented in this {@link #actionPosition} on the row, then this is
161      * the index of that button that was interacted with. For total number of actions
162      * see {@link #actionCount}.
163      *
164      * <p>If the {@link #actionPosition} is {@link #POSITION_CELL} the button is a cell within
165      * a grid, and this index would represent the cell position.</p>
166      * <p>If the {@link #actionPosition} is {@link #POSITION_END} there might be other buttons
167      * in the end position, and this index would represent the position.</p>
168      */
169     public int actionIndex;
170     /**
171      * Total number of actions available in this row of the slice.
172      *
173      * <p>If the {@link #actionPosition} is {@link #POSITION_CELL} the button is a cell within
174      * a grid row, and this is the number of cells in the row.</p>
175      * <p>If the {@link #actionPosition} is {@link #POSITION_END} this is the number of buttons
176      * in the end position of this row.</p>
177      */
178     public int actionCount;
179     /**
180      * Position of the button on the template.
181      *
182      * {@link #POSITION_START}
183      * {@link #POSITION_END}
184      * {@link #POSITION_CELL}
185      */
186     public @SliceButtonPosition int actionPosition;
187     /**
188      * Represents the state after the event or -1 if not applicable for the event type.
189      *
190      * <p>For {@link #ACTION_TYPE_TOGGLE} events, the state will be either {@link #STATE_OFF}
191      * or {@link #STATE_ON}.</p>
192      * <p>For {@link #ACTION_TYPE_SLIDER} events, the state will be a number representing
193      * the new position of the slider.</p>
194      */
195     public int state;
196 
197     /**
198      * Constructs an event info object with the required information for an event.
199      *
200      * @param sliceMode The display mode of the slice interacted with.
201      * @param actionType The type of action this event represents.
202      * @param rowTemplateType The template type of the row interacted with.
203      * @param rowIndex The index of the row that was interacted with in the slice.
204      */
EventInfo(@liceView.SliceMode int sliceMode, @SliceActionType int actionType, @SliceRowType int rowTemplateType, int rowIndex)205     public EventInfo(@SliceView.SliceMode int sliceMode, @SliceActionType int actionType,
206             @SliceRowType int rowTemplateType, int rowIndex) {
207         this.sliceMode = sliceMode;
208         this.actionType = actionType;
209         this.rowTemplateType = rowTemplateType;
210         this.rowIndex = rowIndex;
211 
212         this.actionPosition = -1;
213         this.actionIndex = -1;
214         this.actionCount = -1;
215         this.state = -1;
216     }
217 
218     /**
219      * Sets positional information for the event.
220      *
221      * @param actionPosition The position of the button on the template.
222      * @param actionIndex The index of that button that was interacted with.
223      * @param actionCount The number of actions available in this group of buttons on the slice.
224      */
setPosition(@liceButtonPosition int actionPosition, int actionIndex, int actionCount)225     public void setPosition(@SliceButtonPosition int actionPosition, int actionIndex,
226             int actionCount) {
227         this.actionPosition = actionPosition;
228         this.actionIndex = actionIndex;
229         this.actionCount = actionCount;
230     }
231 
232     @Override
toString()233     public String toString() {
234         StringBuilder sb = new StringBuilder();
235         sb.append("mode=").append(SliceView.modeToString(sliceMode));
236         sb.append(", actionType=").append(actionToString(actionType));
237         sb.append(", rowTemplateType=").append(rowTypeToString(rowTemplateType));
238         sb.append(", rowIndex=").append(rowIndex);
239         sb.append(", actionPosition=").append(positionToString(actionPosition));
240         sb.append(", actionIndex=").append(actionIndex);
241         sb.append(", actionCount=").append(actionCount);
242         sb.append(", state=").append(state);
243         return sb.toString();
244     }
245 
246     /**
247      * @return String representation of the provided position.
248      */
positionToString(@liceButtonPosition int position)249     private static String positionToString(@SliceButtonPosition int position) {
250         switch (position) {
251             case POSITION_START:
252                 return "START";
253             case POSITION_END:
254                 return "END";
255             case POSITION_CELL:
256                 return "CELL";
257             default:
258                 return "unknown position: " + position;
259         }
260     }
261 
262     /**
263      * @return String representation of the provided action.
264      */
actionToString(@liceActionType int action)265     private static String actionToString(@SliceActionType int action) {
266         switch (action) {
267             case ACTION_TYPE_TOGGLE:
268                 return "TOGGLE";
269             case ACTION_TYPE_BUTTON:
270                 return "BUTTON";
271             case ACTION_TYPE_SLIDER:
272                 return "SLIDER";
273             case ACTION_TYPE_CONTENT:
274                 return "CONTENT";
275             case ACTION_TYPE_SEE_MORE:
276                 return "SEE MORE";
277             default:
278                 return "unknown action: " + action;
279         }
280     }
281 
282     /**
283      * @return String representation of the provided row template type.
284      */
rowTypeToString(@liceRowType int type)285     private static String rowTypeToString(@SliceRowType int type) {
286         switch (type) {
287             case ROW_TYPE_LIST:
288                 return "LIST";
289             case ROW_TYPE_GRID:
290                 return "GRID";
291             case ROW_TYPE_MESSAGING:
292                 return "MESSAGING";
293             case ROW_TYPE_SHORTCUT:
294                 return "SHORTCUT";
295             case ROW_TYPE_TOGGLE:
296                 return "TOGGLE";
297             case ROW_TYPE_SLIDER:
298                 return "SLIDER";
299             case ROW_TYPE_PROGRESS:
300                 return "PROGRESS";
301             default:
302                 return "unknown row type: " + type;
303         }
304     }
305 }
306