1 /*
2  * Copyright (C) 2014 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 package com.android.tradefed.device;
17 
18 /**
19  * Implements the test device allocation state machine.
20  * <p/>
21  * Uses the state machine design pattern
22  */
23 interface DeviceAllocationEventHandler {
handleDeviceEvent(DeviceEvent event)24     DeviceAllocationState handleDeviceEvent(DeviceEvent event);
25 
26     /**
27      * Handles events in {@link DeviceAllocationState#Unknown} state.
28      * <p/>
29      * Transitions:
30      * <ul>
31      * <li>Unknown -> FORCE_ALLOCATE_REQUEST -> Allocated</li>
32      * <li>Unknown -> CONNECTED_ONLINE -> Checking_Availability</li>
33      * <li>Unknown -> CONNECTED_OFFLINE -> Unavailable</li>
34      * <li>Unknown -> STATE_CHANGE_ONLINE -> Checking_Availability</li>
35      * <li>Unknown -> STATE_CHANGE_OFFLINE -> Unavailable</li>
36      * <li>Unknown -> FORCE_AVAILABLE -> Available</li>
37      * </ul>
38      */
39     class UnknownHandler implements DeviceAllocationEventHandler {
40         @Override
handleDeviceEvent(DeviceEvent event)41         public DeviceAllocationState handleDeviceEvent(DeviceEvent event) {
42             switch (event) {
43                 case FORCE_ALLOCATE_REQUEST:
44                     return DeviceAllocationState.Allocated;
45                 case CONNECTED_ONLINE:
46                     return DeviceAllocationState.Checking_Availability;
47                 case CONNECTED_OFFLINE:
48                     return DeviceAllocationState.Unavailable;
49                 case STATE_CHANGE_ONLINE:
50                     return DeviceAllocationState.Checking_Availability;
51                 case STATE_CHANGE_OFFLINE:
52                     return DeviceAllocationState.Unavailable;
53                 case FORCE_AVAILABLE:
54                     return DeviceAllocationState.Available;
55                 case FASTBOOT_DETECTED:
56                     return DeviceAllocationState.Available;
57                 default:
58                     return DeviceAllocationState.Unknown;
59             }
60         }
61     }
62 
63     /**
64      * Handles events in {@link DeviceAllocationState#Checking_Availability} state.
65      * <p/>
66      * Transitions:
67      * <ul>
68      * <li>Checking_Availability -> FORCE_ALLOCATE_REQUEST -> Allocated</li>
69      * <li>Checking_Availability -> AVAILABLE_CHECK_PASSED -> Available</li>
70      * <li>Checking_Availability -> AVAILABLE_CHECK_FAILED -> Unavailable</li>
71      * <li>Checking_Availability -> AVAILABLE_CHECK_IGNORED -> Ignored</li>
72      * <li>Checking_Availability -> FORCE_AVAILABLE -> Available</li>
73      * <li>Checking_Availability -> STATE_CHANGE_OFFLINE -> Unavailable</li>
74      * <li>Checking_Availability -> DISCONNECTED -> Unavailable</li>
75      * </ul>
76      */
77     class CheckingAvailHandler implements DeviceAllocationEventHandler {
78         @Override
handleDeviceEvent(DeviceEvent event)79         public DeviceAllocationState handleDeviceEvent(DeviceEvent event) {
80             switch (event) {
81                 case FORCE_ALLOCATE_REQUEST:
82                     return DeviceAllocationState.Allocated;
83                 case AVAILABLE_CHECK_PASSED:
84                     return DeviceAllocationState.Available;
85                 case AVAILABLE_CHECK_FAILED:
86                     return DeviceAllocationState.Unavailable;
87                 case AVAILABLE_CHECK_IGNORED:
88                     return DeviceAllocationState.Ignored;
89                 case FORCE_AVAILABLE:
90                     return DeviceAllocationState.Available;
91                 case STATE_CHANGE_OFFLINE:
92                     return DeviceAllocationState.Unavailable;
93                 case DISCONNECTED:
94                     return DeviceAllocationState.Unavailable;
95                 default:
96                     return DeviceAllocationState.Checking_Availability;
97             }
98         }
99     }
100 
101     /**
102      * Handles events in {@link DeviceAllocationState#Available} state.
103      * <p/>
104      * Transitions:
105      * <ul>
106      * <li>Available -> ALLOCATE_REQUEST -> Allocated</li>
107      * <li>Available -> FORCE_ALLOCATE_REQUEST -> Allocated</li>
108      * <li>Available -> STATE_CHANGE_OFFLINE -> Unavailable</li>
109      * <li>Available -> DISCONNECTED -> Unknown</li>
110      * </ul>
111      */
112     class AvailableHandler implements DeviceAllocationEventHandler {
113         @Override
handleDeviceEvent(DeviceEvent event)114         public DeviceAllocationState handleDeviceEvent(DeviceEvent event) {
115             switch (event) {
116                 case ALLOCATE_REQUEST:
117                 case EXPLICIT_ALLOCATE_REQUEST:
118                 case FORCE_ALLOCATE_REQUEST:
119                     return DeviceAllocationState.Allocated;
120                 case STATE_CHANGE_OFFLINE:
121                     return DeviceAllocationState.Unavailable;
122                 case DISCONNECTED:
123                     return DeviceAllocationState.Unknown;
124                 default:
125                     return DeviceAllocationState.Available;
126 
127             }
128         }
129     }
130 
131     /**
132      * Handles events in {@link DeviceAllocationState#Allocated} state.
133      * <p/>
134      * Transitions:
135      * <ul>
136      * <li>Allocated -> FREE_UNAVAILABLE -> Unavailable</li>
137      * <li>Allocated -> FREE_AVAILABLE -> Available</li>
138      * <li>Allocated -> FREE_UNRESPONSIVE -> Available</li>
139      * <li>Allocated -> FREE_UNKNOWN -> Unknown</li>
140      * </ul>
141      */
142     class AllocatedHandler implements DeviceAllocationEventHandler {
143         @Override
handleDeviceEvent(DeviceEvent event)144         public DeviceAllocationState handleDeviceEvent(DeviceEvent event) {
145             switch (event) {
146                 case FREE_UNAVAILABLE:
147                     return DeviceAllocationState.Unavailable;
148                 case FREE_AVAILABLE:
149                     return DeviceAllocationState.Available;
150                 case FREE_UNRESPONSIVE:
151                     return DeviceAllocationState.Available;
152                 case FREE_UNKNOWN:
153                     return DeviceAllocationState.Unknown;
154                 default:
155                     return DeviceAllocationState.Allocated;
156             }
157         }
158     }
159 
160     /**
161      * Handles events in {@link DeviceAllocationState#Unavailable} state.
162      * <p/>
163      * Transitions:
164      * <ul>
165      * <li>Unavailable -> FORCE_ALLOCATE_REQUEST -> Allocated</li>
166      * <li>Unavailable -> DISCONNECTED -> Unknown</li>
167      * <li>Unavailable -> FORCE_AVAILABLE -> Available</li>
168      * </ul>
169      */
170     class UnavailableHandler implements DeviceAllocationEventHandler {
171         @Override
handleDeviceEvent(DeviceEvent event)172         public DeviceAllocationState handleDeviceEvent(DeviceEvent event) {
173             switch (event) {
174                 case FORCE_ALLOCATE_REQUEST:
175                     return DeviceAllocationState.Allocated;
176                 case DISCONNECTED:
177                     return DeviceAllocationState.Unknown;
178                 case FORCE_AVAILABLE:
179                     return DeviceAllocationState.Available;
180                 default:
181                     return DeviceAllocationState.Unavailable;
182             }
183         }
184     }
185 
186     /**
187      * Handles events in {@link DeviceAllocationState#Ignored} state.
188      *
189      * <p>Transitions:
190      *
191      * <ul>
192      *   <li>Ignored -> DISCONNECTED -> Unknown
193      *   <li>Ignored -> EXPLICIT_ALLOCATE_REQUEST -> Allocated
194      *   <li>Ignored -> FORCE_ALLOCATE_REQUEST -> Allocated
195      * </ul>
196      */
197     class IgnoredHandler implements DeviceAllocationEventHandler {
198         @Override
handleDeviceEvent(DeviceEvent event)199         public DeviceAllocationState handleDeviceEvent(DeviceEvent event) {
200             switch (event) {
201                 case DISCONNECTED:
202                     return DeviceAllocationState.Unknown;
203                     // Explicit and forced request can get an Ignored device
204                 case EXPLICIT_ALLOCATE_REQUEST:
205                     return DeviceAllocationState.Allocated;
206                 case FORCE_ALLOCATE_REQUEST:
207                     return DeviceAllocationState.Allocated;
208                 default:
209                     return DeviceAllocationState.Ignored;
210             }
211         }
212     }
213 }
214