1 /* 2 * Copyright (C) 2007 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 com.android.ddms; 18 19 import com.android.ddmlib.IDevice; 20 import com.android.ddmlib.DebugPortManager.IDebugPortProvider; 21 22 import org.eclipse.jface.preference.IPreferenceStore; 23 24 import java.util.HashMap; 25 import java.util.Map; 26 import java.util.Set; 27 28 /** 29 * DDMS implementation of the IDebugPortProvider interface. 30 * This class handles saving/loading the list of static debug port from 31 * the preference store and provides the port number to the Device Monitor. 32 */ 33 public class DebugPortProvider implements IDebugPortProvider { 34 35 private static DebugPortProvider sThis = new DebugPortProvider(); 36 37 /** Preference name for the static port list. */ 38 public static final String PREFS_STATIC_PORT_LIST = "android.staticPortList"; //$NON-NLS-1$ 39 40 /** 41 * Mapping device serial numbers to maps. The embedded maps are mapping application names to 42 * debugger ports. 43 */ 44 private Map<String, Map<String, Integer>> mMap; 45 46 public static DebugPortProvider getInstance() { 47 return sThis; 48 } 49 50 private DebugPortProvider() { 51 computePortList(); 52 } 53 54 /** 55 * Returns a static debug port for the specified application running on the 56 * specified {@link IDevice}. 57 * @param device The device the application is running on. 58 * @param appName The application name, as defined in the 59 * AndroidManifest.xml package attribute. 60 * @return The static debug port or {@link #NO_STATIC_PORT} if there is none setup. 61 * 62 * @see IDebugPortProvider#getPort(IDevice, String) 63 */ 64 public int getPort(IDevice device, String appName) { 65 if (mMap != null) { 66 Map<String, Integer> deviceMap = mMap.get(device.getSerialNumber()); 67 if (deviceMap != null) { 68 Integer i = deviceMap.get(appName); 69 if (i != null) { 70 return i.intValue(); 71 } 72 } 73 } 74 return IDebugPortProvider.NO_STATIC_PORT; 75 } 76 77 /** 78 * Returns the map of Static debugger ports. The map links device serial numbers to 79 * a map linking application name to debugger ports. 80 */ 81 public Map<String, Map<String, Integer>> getPortList() { 82 return mMap; 83 } 84 85 /** 86 * Create the map member from the values contained in the Preference Store. 87 */ 88 private void computePortList() { 89 mMap = new HashMap<String, Map<String, Integer>>(); 90 91 // get the prefs store 92 IPreferenceStore store = PrefsDialog.getStore(); 93 String value = store.getString(PREFS_STATIC_PORT_LIST); 94 95 if (value != null && value.length() > 0) { 96 // format is 97 // port1|port2|port3|... 98 // where port# is 99 // appPackageName:appPortNumber:device-serial-number 100 String[] portSegments = value.split("\\|"); //$NON-NLS-1$ 101 for (String seg : portSegments) { 102 String[] entry = seg.split(":"); //$NON-NLS-1$ 103 104 // backward compatibility support. if we have only 2 entry, we default 105 // to the first emulator. 106 String deviceName = null; 107 if (entry.length == 3) { 108 deviceName = entry[2]; 109 } else { 110 deviceName = IDevice.FIRST_EMULATOR_SN; 111 } 112 113 // get the device map 114 Map<String, Integer> deviceMap = mMap.get(deviceName); 115 if (deviceMap == null) { 116 deviceMap = new HashMap<String, Integer>(); 117 mMap.put(deviceName, deviceMap); 118 } 119 120 deviceMap.put(entry[0], Integer.valueOf(entry[1])); 121 } 122 } 123 } 124 125 /** 126 * Sets new [device, app, port] values. 127 * The values are also sync'ed in the preference store. 128 * @param map The map containing the new values. 129 */ 130 public void setPortList(Map<String, Map<String,Integer>> map) { 131 // update the member map. 132 mMap.clear(); 133 mMap.putAll(map); 134 135 // create the value to store in the preference store. 136 // see format definition in getPortList 137 StringBuilder sb = new StringBuilder(); 138 139 Set<String> deviceKeys = map.keySet(); 140 for (String deviceKey : deviceKeys) { 141 Map<String, Integer> deviceMap = map.get(deviceKey); 142 if (deviceMap != null) { 143 Set<String> appKeys = deviceMap.keySet(); 144 145 for (String appKey : appKeys) { 146 Integer port = deviceMap.get(appKey); 147 if (port != null) { 148 sb.append(appKey).append(':').append(port.intValue()).append(':'). 149 append(deviceKey).append('|'); 150 } 151 } 152 } 153 } 154 155 String value = sb.toString(); 156 157 // get the prefs store. 158 IPreferenceStore store = PrefsDialog.getStore(); 159 160 // and give it the new value. 161 store.setValue(PREFS_STATIC_PORT_LIST, value); 162 } 163 } 164