1 /*
2  * Copyright (C) 2013 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.command.remote;
17 
18 import com.android.tradefed.device.ITestDevice;
19 
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Hashtable;
23 import java.util.Map;
24 import java.util.concurrent.Future;
25 
26 /**
27  * Singleton class that tracks devices that have been remotely allocated.
28  */
29 class DeviceTracker {
30 
31     /**
32     * Use on demand holder idiom
33     * @see <a href="http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh">
34     * http://en.wikipedia.org/wiki/Singleton_pattern#The_solution_of_Bill_Pugh</a>
35     */
36     private static class SingletonHolder {
37         public static final DeviceTracker cInstance = new DeviceTracker();
38     }
39 
getInstance()40     public static DeviceTracker getInstance() {
41         return SingletonHolder.cInstance;
42     }
43 
44     // private constructor - don't allow instantiation
DeviceTracker()45     private DeviceTracker() {
46     }
47 
48     // use Hashtable since its thread-safe
49     private Map<String, ITestDevice> mAllocatedDeviceMap = new Hashtable<String, ITestDevice>();
50 
51     // TODO: consider merging these maps
52     private Map<String, ExecCommandTracker> mDeviceLastCommandMap =
53             new Hashtable<String, ExecCommandTracker>();
54 
55     /**
56      * Mark given device as remotely allocated.
57      */
allocateDevice(ITestDevice d)58     public void allocateDevice(ITestDevice d) {
59         mAllocatedDeviceMap.put(d.getSerialNumber(), d);
60     }
61 
62     /**
63      * Mark given device serial as freed and clear the command result if any.
64      *
65      * @return the corresponding {@link ITestDevice} or <code>null</code> if device with given
66      *         serial cannot be found
67      */
freeDevice(String serial)68     public ITestDevice freeDevice(String serial) {
69         mDeviceLastCommandMap.remove(serial);
70         return mAllocatedDeviceMap.remove(serial);
71     }
72 
73     /**
74      * Mark all remotely allocated devices as freed.
75      *
76      * @return a {@link Collection} of all remotely allocated devices
77      */
freeAll()78     public Collection<ITestDevice> freeAll() {
79         Collection<ITestDevice> devices = new ArrayList<ITestDevice>(mAllocatedDeviceMap.values());
80         mAllocatedDeviceMap.clear();
81         mDeviceLastCommandMap.clear();
82         return devices;
83     }
84 
85     /**
86      * Return a previously allocated device that matches given serial.
87      *
88      * @param serial
89      * @return the {@link ITestDevice} or <code>null</code> if it cannot be found
90      */
getDeviceForSerial(String serial)91     public ITestDevice getDeviceForSerial(String serial) {
92         return mAllocatedDeviceMap.get(serial);
93     }
94 
95     /**
96      * Retrieve the last {@link Future} command result for given device.
97      * @param deviceSerial
98      * @return the {@link Future} or <code>null</code> if no result exists for device. Note results
99      * are cleared on {@link #freeDevice(String)}.
100      */
getLastCommandResult(String deviceSerial)101     public ExecCommandTracker getLastCommandResult(String deviceSerial) {
102         return mDeviceLastCommandMap.get(deviceSerial);
103     }
104 
105     /**
106      * Sets the command result tracker for given device.
107      *
108      * @param deviceSerial
109      * @param tracker
110      */
setCommandTracker(String deviceSerial, ExecCommandTracker tracker)111     public void setCommandTracker(String deviceSerial, ExecCommandTracker tracker) {
112         mDeviceLastCommandMap.put(deviceSerial, tracker);
113     }
114 }
115