package interdroid.swan; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import android.content.ComponentName; import android.content.Intent; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Log; /** * Stores and keeps tracks of sensor service information. */ public class SensorInfo { private static final String TAG = "Sensor Info"; /** * The name of the component the sensor runs in.. */ private final ComponentName component; /** * The entity Id for this service. */ private final String entityId; /** * The authority for this sensors database. */ private final String authority; /** * The value paths this sensor supports. */ private final ArrayList<String> valuePaths = new ArrayList<String>(); /** * The units the valuepath returns. */ private final ArrayList<String> units = new ArrayList<String>(); /** * The Drawable icon for this sensor. */ private Drawable icon; /** * The configuration for this sensor. */ private final Bundle configuration; /** * Construct information about a sensor. * * @param sensorComponent * The component the sensor lives in * @param metaData * metadata bundle for the service from the package manager */ public SensorInfo(final ComponentName sensorComponent, final Bundle metaData, Drawable icon) { this.component = sensorComponent; this.icon = icon; // strip out the entityId if (metaData == null) { throw new IllegalArgumentException("no metadata!"); } entityId = metaData.getString("entityId"); metaData.remove("entityId"); authority = metaData.getString("authority"); metaData.remove("authority"); // and the units units.addAll(Arrays.asList(metaData.getString("units").split(",", -1))); metaData.remove("units"); // and the value paths valuePaths.addAll(Arrays.asList(metaData.getString("valuePaths").split( ","))); metaData.remove("valuePaths"); // all other items in the bundle are supposed to be configurable (values // are default values) configuration = metaData; Set<String> keys = new HashSet<String>(); keys.addAll(metaData.keySet()); for (String key : keys) { if (metaData.get(key).toString().endsWith("L")) { try { long longValue = Long .parseLong(metaData.getString(key).substring(0, metaData.getString(key).length() - 1)); metaData.remove(key); metaData.putLong(key, longValue); } catch (NumberFormatException e) { Log.d(TAG, "Can't convert number. Using string."); } } if (metaData.get(key).toString().endsWith("D")) { try { double doubleValue = Double.parseDouble(metaData.getString( key).substring(0, metaData.getString(key).length() - 1)); metaData.remove(key); metaData.putDouble(key, doubleValue); } catch (NumberFormatException e) { Log.d(TAG, "Can't convert number. Using string."); } } } } /** * * @return icon of the sensor */ public Drawable getIcon() { return icon; } /** * @return the entity Id for this sensor. */ public final String getEntity() { return entityId; } /** * @return the value paths this sensor supports. */ public final ArrayList<String> getValuePaths() { return valuePaths; } /** * @return the units this sensor supports. */ public final ArrayList<String> getUnits() { return units; } /** * @return the authority for this sensors database if appropriate. */ public final String getAuthority() { return authority; } /** * Checks if this sensor accepts the given configuration. * * @param b * the bundle to check * @return true if this sensor supports the given bundle * @throws SensorConfigurationException * if the sensor is not configured */ public final boolean acceptsConfiguration(final Bundle b) throws SensorConfigurationException { if (b != null) { Set<String> keys = new HashSet<String>(); keys.addAll(b.keySet()); for (String key : keys) { if (configuration.containsKey(key)) { if (!b.get(key).getClass() .isInstance(configuration.get(key))) { try { String value = b.getString(key); b.remove(key); if (configuration.get(key).getClass() == Integer.class) { b.putInt(key, Integer.parseInt(value)); } else if (configuration.get(key).getClass() == Long.class) { b.putLong(key, Long.parseLong(value)); } else if (configuration.get(key).getClass() == Float.class) { b.putFloat(key, Float.parseFloat(value)); } else if (configuration.get(key).getClass() == Double.class) { b.putDouble(key, Double.parseDouble(value)); } else if (configuration.get(key).getClass() == Boolean.class) { b.putBoolean(key, Boolean.parseBoolean(value)); } } catch (NumberFormatException e) { throw new SensorConfigurationException( "Unable to parse value for configuration '" + key + "' in entity " + entityId + " to type " + configuration.get(key).getClass()); } } } else { throw new SensorConfigurationException( "Unsupported configuration key '" + key + "' for " + entityId); } } for (String key : configuration.keySet()) { if ("required".equals(configuration.get(key))) { if (b.containsKey(key)) { continue; } else { throw new SensorConfigurationException( "Missing required configuration key '" + key + "' for " + entityId + " value: " + configuration.get(key)); } } } } return true; } /** * Returns an intent to launch this sensor. * * @return new Intent().setComponent(getComponent()) */ public final Intent getIntent() { ComponentName serviceComponent = new ComponentName( component.getPackageName(), component.getClassName().replace( "$ConfigurationActivity", "")); return new Intent().setComponent(serviceComponent); } /** * Returns an intent with component.getClassName() + * "$ConfigurationActivity" for launching the sensors configuration * activity. * * @return an intent for launching the configuration activity */ public final Intent getConfigurationIntent() { Intent result = new Intent().setComponent(component); result.putExtra("entityId", entityId); return result; } @Override public String toString() { return entityId; } }