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 40 public static DeviceTracker getInstance() { 41 return SingletonHolder.cInstance; 42 } 43 44 // private constructor - don't allow instantiation 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 111 public void setCommandTracker(String deviceSerial, ExecCommandTracker tracker) { 112 mDeviceLastCommandMap.put(deviceSerial, tracker); 113 } 114 } 115