diff --git a/MyTracks/libs/README.txt b/MyTracks/libs/README.txt index 033ec8f9e..3e7f84219 100644 --- a/MyTracks/libs/README.txt +++ b/MyTracks/libs/README.txt @@ -7,6 +7,9 @@ Android Support Package: android-support-v4-r7-googlemaps.jar - see https://github.com/petedoyle/android-support-v4-googlemaps +Ant+: +antlib.jar - see http://www.thisisant.com/pages/developer-zone/android-api + Google APIs Client Library for Java: commons-codec-1.3.jar commons-logging-1.1.1.jar diff --git a/MyTracks/libs/antlib.jar b/MyTracks/libs/antlib.jar new file mode 100644 index 000000000..b4ff8fe04 Binary files /dev/null and b/MyTracks/libs/antlib.jar differ diff --git a/MyTracks/res/values/arrays_do_not_translate.xml b/MyTracks/res/values/arrays_do_not_translate.xml index 4ca399897..f2fc910ab 100644 --- a/MyTracks/res/values/arrays_do_not_translate.xml +++ b/MyTracks/res/values/arrays_do_not_translate.xml @@ -161,14 +161,12 @@ limitations under the License. @string/settings_sensor_type_none @string/settings_sensor_type_ant - @string/settings_sensor_type_srm @string/settings_sensor_type_polar @string/settings_sensor_type_zephyr @string/sensor_type_value_none @string/sensor_type_value_ant - @string/sensor_type_value_srm_ant_bridge @string/sensor_type_value_polar @string/sensor_type_value_zephyr diff --git a/MyTracks/res/values/do_not_translate.xml b/MyTracks/res/values/do_not_translate.xml index 3bad2cdf7..06045fb5c 100644 --- a/MyTracks/res/values/do_not_translate.xml +++ b/MyTracks/res/values/do_not_translate.xml @@ -30,7 +30,6 @@ limitations under the License. ANT NONE POLAR - SRM_ANT_BRIDGE ZEPHYR DYNAMIC FIXED diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml index 64e356e48..f7fa8a154 100644 --- a/MyTracks/res/values/keys.xml +++ b/MyTracks/res/values/keys.xml @@ -18,10 +18,8 @@ limitations under the License. allowAccess announcementFrequency - antCadenceSensorId - antCadenceSpeedSensorId - antHeartRateSensorId - antSrmBridgeSensorId + antHeartRateMonitorId + antSpeedDistanceMonitorId autoResumeTrackCurrentRetry autoResumeTrackTimeout bluetoothSensor @@ -72,6 +70,8 @@ limitations under the License. settingsReset settingsSensor settingsSensorAnt + settingsSensorAntResetHeartRateMonitor + settingsSensorAntResetSpeedDistanceMonitor settingsSensorBluetooth settingsSensorBluetoothPairing settingsSensorRoot diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index c8e70d00c..dbc46784a 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -1726,11 +1726,6 @@ limitations under the License. Character limit: ~26 (1 line)"> Sensor - - Not paired. - + %1$d: device id number. E.g., '1'."> Paired with: %1$d. - - Connected to %1$s + + Reset heart rate monitor + + + Reset speed distance monitor The Bluetooth sensor to connect to. + + Connected to %1$s + + + Not connected. + - ANT+ heart rate + ANT+ Polar Bluetooth - - SRM ANT+ bridge - @@ -1833,21 +1838,6 @@ limitations under the License. Character limit: ~21 (1 line)"> Zephyr Bluetooth - - Unpair ANT+ heart rate - - - Unpair SRM ANT+ bridge - - - + + \ No newline at end of file diff --git a/MyTracks/src/com/dsi/ant/AntDefine.java b/MyTracks/src/com/dsi/ant/AntDefine.java deleted file mode 100644 index bda615df9..000000000 --- a/MyTracks/src/com/dsi/ant/AntDefine.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2010 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - - - -/** - * The Android Ant API is not finalized, and *will* change. Use at your - * own risk. - * - * Public API for controlling the Ant Service. - * AntDefines contains definitions commonly used in ANT messaging. - * - * @hide - */ -public class AntDefine { - - ////////////////////////////////////////////// - // Valid Configuration Values - ////////////////////////////////////////////// - public static final byte MIN_BIN = 0; - public static final byte MAX_BIN = 10; - - public static final short MIN_DEVICE_ID = 0; - public static final short MAX_DEVICE_ID = (short)65535; - - public static final short MIN_BUFFER_THRESHOLD = 0; - public static final short MAX_BUFFER_THRESHOLD = 996; - - ////////////////////////////////////////////// - // ANT Message Payload Size - ////////////////////////////////////////////// - public static final byte ANT_STANDARD_DATA_PAYLOAD_SIZE =((byte)8); - - ////////////////////////////////////////////// - // ANT LIBRARY Extended Data Message Fields - // NOTE: You must check the extended message - // bitfield first to find out which fields - // are present before accessing them! - ////////////////////////////////////////////// - public static final byte ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE =((byte)4); - //public static final byte ANT_EXT_STRING_SIZE =((byte)19); // this is the additional buffer space required required for setting USB Descriptor strings - public static final byte ANT_EXT_STRING_SIZE =((byte)0); // changed to 0 as we will not be dealing with ANT USB parts. - - ////////////////////////////////////////////// - // ANT Extended Data Message Bifield Definitions - ////////////////////////////////////////////// - public static final byte ANT_EXT_MESG_BITFIELD_DEVICE_ID =((byte)0x80); // first field after bitfield - public static final byte ANT_EXT_MESG_BITFIELD_RSSI =((byte)0x40); // next field after ID, if there is one - public static final byte ANT_EXT_MESG_BITFIELD_TIME_STAMP =((byte)0x20); // next field after RSSI, if there is one - - // 4 bits free reserved set to 0 - public static final byte ANT_EXT_MESG_BIFIELD_EXTENSION =((byte)0x01); - - // extended message input bitfield defines - public static final byte ANT_EXT_MESG_BITFIELD_OVERWRITE_SHARED_ADR =((byte)0x10); - public static final byte ANT_EXT_MESG_BITFIELD_TRANSMISSION_TYPE =((byte)0x08); - - ////////////////////////////////////////////// - // ID Definitions - ////////////////////////////////////////////// - public static final byte ANT_ID_SIZE =((byte)4); - public static final byte ANT_ID_TRANS_TYPE_OFFSET =((byte)3); - public static final byte ANT_ID_DEVICE_TYPE_OFFSET =((byte)2); - public static final byte ANT_ID_DEVICE_NUMBER_HIGH_OFFSET =((byte)1); - public static final byte ANT_ID_DEVICE_NUMBER_LOW_OFFSET =((byte)0); - public static final byte ANT_ID_DEVICE_TYPE_PAIRING_FLAG =((byte)0x80); - - public static final byte ANT_TRANS_TYPE_SHARED_ADDR_MASK =((byte)0x03); - public static final byte ANT_TRANS_TYPE_1_BYTE_SHARED_ADDRESS =((byte)0x02); - public static final byte ANT_TRANS_TYPE_2_BYTE_SHARED_ADDRESS =((byte)0x03); - - ////////////////////////////////////////////// - // Assign Channel Parameters - ////////////////////////////////////////////// - public static final byte PARAMETER_RX_NOT_TX =((byte)0x00); - public static final byte PARAMETER_TX_NOT_RX =((byte)0x10); - public static final byte PARAMETER_SHARED_CHANNEL =((byte)0x20); - public static final byte PARAMETER_NO_TX_GUARD_BAND =((byte)0x40); - public static final byte PARAMETER_ALWAYS_RX_WILD_CARD_SEARCH_ID =((byte)0x40); //Pre-AP2 - public static final byte PARAMETER_RX_ONLY =((byte)0x40); - - ////////////////////////////////////////////// - // Ext. Assign Channel Parameters - ////////////////////////////////////////////// - public static final byte EXT_PARAM_ALWAYS_SEARCH =((byte)0x01); - public static final byte EXT_PARAM_FREQUENCY_AGILITY =((byte)0x04); - - ////////////////////////////////////////////// - // Radio TX Power Definitions - ////////////////////////////////////////////// - public static final byte RADIO_TX_POWER_LVL_MASK =((byte)0x03); - - public static final byte RADIO_TX_POWER_LVL_0 =((byte)0x00); //(formerly: RADIO_TX_POWER_MINUS20DB); lowest - public static final byte RADIO_TX_POWER_LVL_1 =((byte)0x01); //(formerly: RADIO_TX_POWER_MINUS10DB); - public static final byte RADIO_TX_POWER_LVL_2 =((byte)0x02); //(formerly: RADIO_TX_POWER_MINUS5DB); - public static final byte RADIO_TX_POWER_LVL_3 =((byte)0x03); //(formerly: RADIO_TX_POWER_0DB); highest - - ////////////////////////////////////////////// - // Channel Status - ////////////////////////////////////////////// - public static final byte STATUS_CHANNEL_STATE_MASK =((byte)0x03); - public static final byte STATUS_UNASSIGNED_CHANNEL =((byte)0x00); - public static final byte STATUS_ASSIGNED_CHANNEL =((byte)0x01); - public static final byte STATUS_SEARCHING_CHANNEL =((byte)0x02); - public static final byte STATUS_TRACKING_CHANNEL =((byte)0x03); - - ////////////////////////////////////////////// - // Standard capabilities defines - ////////////////////////////////////////////// - public static final byte CAPABILITIES_NO_RX_CHANNELS =((byte)0x01); - public static final byte CAPABILITIES_NO_TX_CHANNELS =((byte)0x02); - public static final byte CAPABILITIES_NO_RX_MESSAGES =((byte)0x04); - public static final byte CAPABILITIES_NO_TX_MESSAGES =((byte)0x08); - public static final byte CAPABILITIES_NO_ACKD_MESSAGES =((byte)0x10); - public static final byte CAPABILITIES_NO_BURST_TRANSFER =((byte)0x20); - - ////////////////////////////////////////////// - // Advanced capabilities defines - ////////////////////////////////////////////// - public static final byte CAPABILITIES_OVERUN_UNDERRUN =((byte)0x01); // Support for this functionality has been dropped - public static final byte CAPABILITIES_NETWORK_ENABLED =((byte)0x02); - public static final byte CAPABILITIES_AP1_VERSION_2 =((byte)0x04); // This Version of the AP1 does not support transmit and only had a limited release - public static final byte CAPABILITIES_SERIAL_NUMBER_ENABLED =((byte)0x08); - public static final byte CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED =((byte)0x10); - public static final byte CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED =((byte)0x20); - public static final byte CAPABILITIES_SCRIPT_ENABLED =((byte)0x40); - public static final byte CAPABILITIES_SEARCH_LIST_ENABLED =((byte)0x80); - - ////////////////////////////////////////////// - // Advanced capabilities 2 defines - ////////////////////////////////////////////// - public static final byte CAPABILITIES_LED_ENABLED =((byte)0x01); - public static final byte CAPABILITIES_EXT_MESSAGE_ENABLED =((byte)0x02); - public static final byte CAPABILITIES_SCAN_MODE_ENABLED =((byte)0x04); - public static final byte CAPABILITIES_RESERVED =((byte)0x08); - public static final byte CAPABILITIES_PROX_SEARCH_ENABLED =((byte)0x10); - public static final byte CAPABILITIES_EXT_ASSIGN_ENABLED =((byte)0x20); - public static final byte CAPABILITIES_FREE_1 =((byte)0x40); - public static final byte CAPABILITIES_FIT1_ENABLED =((byte)0x80); - - ////////////////////////////////////////////// - // Advanced capabilities 3 defines - ////////////////////////////////////////////// - public static final byte CAPABILITIES_SENSRCORE_ENABLED =((byte)0x01); - public static final byte CAPABILITIES_RESERVED_1 =((byte)0x02); - public static final byte CAPABILITIES_RESERVED_2 =((byte)0x04); - public static final byte CAPABILITIES_RESERVED_3 =((byte)0x08); - - - ////////////////////////////////////////////// - // Burst Message Sequence - ////////////////////////////////////////////// - public static final byte CHANNEL_NUMBER_MASK =((byte)0x1F); - public static final byte SEQUENCE_NUMBER_MASK =((byte)0xE0); - public static final byte SEQUENCE_NUMBER_ROLLOVER =((byte)0x60); - public static final byte SEQUENCE_FIRST_MESSAGE =((byte)0x00); - public static final byte SEQUENCE_LAST_MESSAGE =((byte)0x80); - public static final byte SEQUENCE_NUMBER_INC =((byte)0x20); - - ////////////////////////////////////////////// - // Control Message Flags - ////////////////////////////////////////////// - public static final byte BROADCAST_CONTROL_BYTE =((byte)0x00); - public static final byte ACKNOWLEDGED_CONTROL_BYTE =((byte)0xA0); - - ////////////////////////////////////////////// - // Response / Event Codes - ////////////////////////////////////////////// - public static final byte RESPONSE_NO_ERROR =((byte)0x00); - public static final byte NO_EVENT =((byte)0x00); - - public static final byte EVENT_RX_SEARCH_TIMEOUT =((byte)0x01); - public static final byte EVENT_RX_FAIL =((byte)0x02); - public static final byte EVENT_TX =((byte)0x03); - public static final byte EVENT_TRANSFER_RX_FAILED =((byte)0x04); - public static final byte EVENT_TRANSFER_TX_COMPLETED =((byte)0x05); - public static final byte EVENT_TRANSFER_TX_FAILED =((byte)0x06); - public static final byte EVENT_CHANNEL_CLOSED =((byte)0x07); - public static final byte EVENT_RX_FAIL_GO_TO_SEARCH =((byte)0x08); - public static final byte EVENT_CHANNEL_COLLISION =((byte)0x09); - public static final byte EVENT_TRANSFER_TX_START =((byte)0x0A); // a pending transmit transfer has begun - - public static final byte EVENT_CHANNEL_ACTIVE =((byte)0x0F); - - public static final byte EVENT_TRANSFER_TX_NEXT_MESSAGE =((byte)0x11); // only enabled in FIT1 - - public static final byte CHANNEL_IN_WRONG_STATE =((byte)0x15); // returned on attempt to perform an action from the wrong channel state - public static final byte CHANNEL_NOT_OPENED =((byte)0x16); // returned on attempt to communicate on a channel that is not open - public static final byte CHANNEL_ID_NOT_SET =((byte)0x18); // returned on attempt to open a channel without setting the channel ID - public static final byte CLOSE_ALL_CHANNELS =((byte)0x19); // returned when attempting to start scanning mode, when channels are still open - - public static final byte TRANSFER_IN_PROGRESS =((byte)0x1F); // returned on attempt to communicate on a channel with a TX transfer in progress - public static final byte TRANSFER_SEQUENCE_NUMBER_ERROR =((byte)0x20); // returned when sequence number is out of order on a Burst transfer - public static final byte TRANSFER_IN_ERROR =((byte)0x21); - public static final byte TRANSFER_BUSY =((byte)0x22); - - public static final byte INVALID_MESSAGE_CRC =((byte)0x26); // returned if there is a framing error on an incomming message - public static final byte MESSAGE_SIZE_EXCEEDS_LIMIT =((byte)0x27); // returned if a data message is provided that is too large - public static final byte INVALID_MESSAGE =((byte)0x28); // returned when the message has an invalid parameter - public static final byte INVALID_NETWORK_NUMBER =((byte)0x29); // returned when an invalid network number is provided - public static final byte INVALID_LIST_ID =((byte)0x30); // returned when the provided list ID or size exceeds the limit - public static final byte INVALID_SCAN_TX_CHANNEL =((byte)0x31); // returned when attempting to transmit on channel 0 when in scan mode - - public static final byte INVALID_PARAMETER_PROVIDED =((byte)0x33); // returned when an invalid parameter is specified in a configuration message - - public static final byte EVENT_SERIAL_QUE_OVERFLOW =((byte)0x34); - public static final byte EVENT_QUE_OVERFLOW =((byte)0x35); // ANT event que has overflowed and lost 1 or more events - - public static final byte EVENT_CLK_ERROR =((byte)0x36); // debug event for XOSC16M on LE1 - - public static final byte SCRIPT_FULL_ERROR =((byte)0x40); // error writing to script, memory is full - public static final byte SCRIPT_WRITE_ERROR =((byte)0x41); // error writing to script, bytes not written correctly - public static final byte SCRIPT_INVALID_PAGE_ERROR =((byte)0x42); // error accessing script page - public static final byte SCRIPT_LOCKED_ERROR =((byte)0x43); // the scripts are locked and can't be dumped - - public static final byte NO_RESPONSE_MESSAGE =((byte)0x50); // returned to the Command_SerialMessageProcess function, so no reply message is generated - public static final byte RETURN_TO_MFG =((byte)0x51); // default return to any mesg when the module determines that the mfg procedure has not been fully completed - - public static final byte FIT_ACTIVE_SEARCH_TIMEOUT =((byte)0x60); // Fit1 only event added for timeout of the pairing state after the Fit module becomes active - public static final byte FIT_WATCH_PAIR =((byte)0x61); // Fit1 only - public static final byte FIT_WATCH_UNPAIR =((byte)0x62); // Fit1 only - - public static final byte USB_STRING_WRITE_FAIL =((byte)0x70); - - // Internal only events below this point - public static final byte INTERNAL_ONLY_EVENTS =((byte)0x80); - public static final byte EVENT_RX =((byte)0x80); // INTERNAL: Event for a receive message - public static final byte EVENT_NEW_CHANNEL =((byte)0x81); // INTERNAL: EVENT for a new active channel - public static final byte EVENT_PASS_THRU =((byte)0x82); // INTERNAL: Event to allow an upper stack events to pass through lower stacks - - public static final byte EVENT_BLOCKED =((byte)0xFF); // INTERNAL: Event to replace any event we do not wish to go out, will also zero the size of the Tx message - - /////////////////////////////////////////////////////// - // Script Command Codes - /////////////////////////////////////////////////////// - public static final byte SCRIPT_CMD_FORMAT =((byte)0x00); - public static final byte SCRIPT_CMD_DUMP =((byte)0x01); - public static final byte SCRIPT_CMD_SET_DEFAULT_SECTOR =((byte)0x02); - public static final byte SCRIPT_CMD_END_SECTOR =((byte)0x03); - public static final byte SCRIPT_CMD_END_DUMP =((byte)0x04); - public static final byte SCRIPT_CMD_LOCK =((byte)0x05); - - /////////////////////////////////////////////////////// - // Reset Mesg Codes - /////////////////////////////////////////////////////// - public static final byte RESET_FLAGS_MASK =((byte)0xE0); - public static final byte RESET_SUSPEND =((byte)0x80); // this must follow bitfield def - public static final byte RESET_SYNC =((byte)0x40); // this must follow bitfield def - public static final byte RESET_CMD =((byte)0x20); // this must follow bitfield def - public static final byte RESET_WDT =((byte)0x02); - public static final byte RESET_RST =((byte)0x01); - public static final byte RESET_POR =((byte)0x00); - -} \ No newline at end of file diff --git a/MyTracks/src/com/dsi/ant/AntInterface.java b/MyTracks/src/com/dsi/ant/AntInterface.java deleted file mode 100644 index e8c6a0b67..000000000 --- a/MyTracks/src/com/dsi/ant/AntInterface.java +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * Copyright 2010 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - -import com.dsi.ant.exception.AntInterfaceException; -import com.dsi.ant.exception.AntRemoteException; -import com.dsi.ant.exception.AntServiceNotConnectedException; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.net.Uri; -import android.os.IBinder; -import android.os.RemoteException; -import android.util.Log; - -import java.util.Arrays; - -/** - * Public API for controlling the Ant Service. AntInterface is a proxy - * object for controlling the Ant Service via IPC. Creating a AntInterface - * object will create a binding with the Ant service. - * - * @hide - */ -public class AntInterface { - - /** The Log Tag. */ - public static final String TAG = "ANTInterface"; - - /** Enable debug logging. */ - public static boolean DEBUG = false; - - /** Search string to find ANT Radio Proxy Service in the Android Marketplace */ - private static final String MARKET_SEARCH_TEXT_DEFAULT = "ANT Radio Service Dynastream Innovations Inc"; - - /** Name of the ANT Radio shared library */ - private static final String ANT_LIBRARY_NAME = "com.dsi.ant.antradio_library"; - - /** Inter-process communication with the ANT Radio Proxy Service. */ - private static IAnt_6 sAntReceiver = null; - - /** Singleton instance of this class. */ - private static AntInterface INSTANCE; - - /** Used when obtaining a reference to the singleton instance. */ - private static Object INSTANCE_LOCK = new Object(); - - /** The context to use. */ - private Context sContext = null; - - /** Listens to changes to service connection status. */ - private ServiceListener sServiceListener; - - /** Is the ANT Radio Proxy Service connected. */ - private static boolean sServiceConnected = false; - - /** The version code (eg. 1) of ANTLib used by the ANT application service */ - private static int mServiceLibraryVersionCode = 0; - - /** Has support for ANT already been checked */ - private static boolean mCheckedAntSupported = false; - - /** Is ANT supported on this device */ - private static boolean mAntSupported = false; - - /** - * An interface for notifying AntInterface IPC clients when they have been - * connected to the ANT service. - */ - public interface ServiceListener - { - /** - * Called to notify the client when this proxy object has been - * connected to the ANT service. Clients must wait for - * this callback before making IPC calls on the ANT - * service. - */ - public void onServiceConnected(); - - /** - * Called to notify the client that this proxy object has been - * disconnected from the ANT service. Clients must not - * make IPC calls on the ANT service after this callback. - * This callback will currently only occur if the application hosting - * the BluetoothAg service, but may be called more often in future. - */ - public void onServiceDisconnected(); - } - - - //Constructor - /** - * Instantiates a new ant interface. - * - * @param context the context - * @param listener the listener - * @since 1.0 - */ - private AntInterface(Context context, ServiceListener listener) - { - // This will be around as long as this process is - sContext = context; - sServiceListener = listener; - } - - /** - * Gets the single instance of AntInterface, creating it if it doesn't exist. - * Only the initial request for an instance will have context and listener set to the requested objects. - * - * @param context the context used to bind to the remote service. - * @param listener the listener to be notified of status changes. - * @return the AntInterface instance. - * @since 1.0 - */ - public static AntInterface getInstance(Context context,ServiceListener listener) - { - if(DEBUG) Log.d(TAG, "getInstance"); - - synchronized (INSTANCE_LOCK) - { - if(!hasAntSupport(context)) - { - if(DEBUG) Log.d(TAG, "getInstance: ANT not supported"); - - return null; - } - - if (INSTANCE == null) - { - if(DEBUG) Log.d(TAG, "getInstance: Creating new instance"); - - INSTANCE = new AntInterface(context,listener); - } - else - { - if(DEBUG) Log.d(TAG, "getInstance: Using existing instance"); - } - - if(!sServiceConnected) - { - if(DEBUG) Log.d(TAG, "getInstance: No connection to proxy service, attempting connection"); - - if(!INSTANCE.initService()) - { - Log.e(TAG, "getInstance: No connection to proxy service"); - - INSTANCE.destroy(); - INSTANCE = null; - } - } - - return INSTANCE; - } - } - - /** - * Go to market. - * - * @param pContext the context - * @param pSearchText the search text - * @since 1.2 - */ - public static void goToMarket(Context pContext, String pSearchText) - { - if(null == pSearchText) - { - goToMarket(pContext); - } - else - { - if(DEBUG) Log.i(TAG, "goToMarket: Search text = "+ pSearchText); - - Intent goToMarket = null; - goToMarket = new Intent(Intent.ACTION_VIEW,Uri.parse("http://market.android.com/search?q=" + pSearchText)); - goToMarket.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - pContext.startActivity(goToMarket); - } - } - - /** - * Go to market. - * - * @param pContext the context - * @since 1.2 - */ - public static void goToMarket(Context pContext) - { - if(DEBUG) Log.d(TAG, "goToMarket"); - - goToMarket(pContext, MARKET_SEARCH_TEXT_DEFAULT); - } - - /** - * Class for interacting with the ANT interface. - */ - private final ServiceConnection sIAntConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName pClassName, IBinder pService) { - // This is called when the connection with the service has been - // established, giving us the service object we can use to - // interact with the service. We are communicating with our - // service through an IDL interface, so get a client-side - // representation of that from the raw service object. - if(DEBUG) Log.d(TAG, "sIAntConnection onServiceConnected()"); - sAntReceiver = IAnt_6.Stub.asInterface(pService); - - sServiceConnected = true; - - // Notify the attached application if it is registered - if (sServiceListener != null) - { - sServiceListener.onServiceConnected(); - } - else - { - if(DEBUG) Log.d(TAG, "sIAntConnection onServiceConnected: No service listener registered"); - } - } - - public void onServiceDisconnected(ComponentName pClassName) { - // This is called when the connection with the service has been - // unexpectedly disconnected -- that is, its process crashed. - if(DEBUG) Log.d(TAG, "sIAntConnection onServiceDisconnected()"); - sAntReceiver = null; - - sServiceConnected = false; - mServiceLibraryVersionCode = 0; - - // Notify the attached application if it is registered - if (sServiceListener != null) - { - sServiceListener.onServiceDisconnected(); - } - else - { - if(DEBUG) Log.d(TAG, "sIAntConnection onServiceDisconnected: No service listener registered"); - } - - // Try and rebind to the service - INSTANCE.releaseService(); - INSTANCE.initService(); - } - }; - - /** - * Binds this activity to the ANT service. - * - * @return true, if successful - */ - private boolean initService() { - if(DEBUG) Log.d(TAG, "initService() entered"); - - boolean ret = false; - - if(!sServiceConnected) - { - ret = sContext.bindService(new Intent(IAnt_6.class.getName()), sIAntConnection, Context.BIND_AUTO_CREATE); - if(DEBUG) Log.i(TAG, "initService(): Bound with ANT service: " + ret); - } - else - { - if(DEBUG) Log.d(TAG, "initService: already initialised service"); - ret = true; - } - - return ret; - } - - /** Unbinds this activity from the ANT service. */ - private void releaseService() { - if(DEBUG) Log.d(TAG, "releaseService() entered"); - - // TODO Make sure can handle multiple calls to onDestroy - if(sServiceConnected) - { - sContext.unbindService(sIAntConnection); - sServiceConnected = false; - } - - if(DEBUG) Log.d(TAG, "releaseService() unbound."); - } - - /** - * True if this activity can communicate with the ANT service. - * - * @return true, if service is connected - * @since 1.2 - */ - public boolean isServiceConnected() - { - return sServiceConnected; - } - - /** - * Destroy. - * - * @return true, if successful - * @since 1.0 - */ - public boolean destroy() - { - if(DEBUG) Log.d(TAG, "destroy"); - - releaseService(); - - INSTANCE = null; - - return true; - } - - - ////------------------------------------------------- - - /** - * Enable. - * - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void enable() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.enable()) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Disable. - * - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void disable() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.disable()) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Checks if is enabled. - * - * @return true, if is enabled. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public boolean isEnabled() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.isEnabled(); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT tx message. - * - * @param message the message - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTTxMessage(byte[] message) throws AntInterfaceException - { - if(DEBUG) Log.d(TAG, "ANTTxMessage"); - - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTTxMessage(message)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT reset system. - * - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTResetSystem() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTResetSystem()) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT unassign channel. - * - * @param channelNumber the channel number - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTUnassignChannel(byte channelNumber) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTUnassignChannel(channelNumber)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT assign channel. - * - * @param channelNumber the channel number - * @param channelType the channel type - * @param networkNumber the network number - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTAssignChannel(byte channelNumber, byte channelType, byte networkNumber) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTAssignChannel(channelNumber, channelType, networkNumber)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT set channel id. - * - * @param channelNumber the channel number - * @param deviceNumber the device number - * @param deviceType the device type - * @param txType the tx type - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSetChannelId(byte channelNumber, short deviceNumber, byte deviceType, byte txType) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSetChannelId(channelNumber, deviceNumber, deviceType, txType)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT set channel period. - * - * @param channelNumber the channel number - * @param channelPeriod the channel period - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSetChannelPeriod(byte channelNumber, short channelPeriod) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSetChannelPeriod(channelNumber, channelPeriod)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT set channel rf freq. - * - * @param channelNumber the channel number - * @param radioFrequency the radio frequency - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSetChannelRFFreq(byte channelNumber, byte radioFrequency) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSetChannelRFFreq(channelNumber, radioFrequency)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT set channel search timeout. - * - * @param channelNumber the channel number - * @param searchTimeout the search timeout - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSetChannelSearchTimeout(byte channelNumber, byte searchTimeout) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSetChannelSearchTimeout(channelNumber, searchTimeout)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT set low priority channel search timeout. - * - * @param channelNumber the channel number - * @param searchTimeout the search timeout - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSetLowPriorityChannelSearchTimeout(byte channelNumber, byte searchTimeout) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSetLowPriorityChannelSearchTimeout(channelNumber, searchTimeout)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT set proximity search. - * - * @param channelNumber the channel number - * @param searchThreshold the search threshold - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSetProximitySearch(byte channelNumber, byte searchThreshold) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSetProximitySearch(channelNumber, searchThreshold)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT set channel transmit power - * @param channelNumber the channel number - * @param txPower the transmit power level - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSetChannelTxPower(byte channelNumber, byte txPower) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSetChannelTxPower(channelNumber, txPower)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT add channel id. - * - * @param channelNumber the channel number - * @param deviceNumber the device number - * @param deviceType the device type - * @param txType the tx type - * @param listIndex the list index - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTAddChannelId(byte channelNumber, short deviceNumber, byte deviceType, byte txType, byte listIndex) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTAddChannelId(channelNumber, deviceNumber, deviceType, txType, listIndex)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT config list. - * - * @param channelNumber the channel number - * @param listSize the list size - * @param exclude the exclude - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTConfigList(byte channelNumber, byte listSize, byte exclude) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTConfigList(channelNumber, listSize, exclude)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT config event buffering. - * - * @param screenOnFlushTimerInterval the screen on flush timer interval - * @param screenOnFlushBufferThreshold the screen on flush buffer threshold - * @param screenOffFlushTimerInterval the screen off flush timer interval - * @param screenOffFlushBufferThreshold the screen off flush buffer threshold - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.3 - */ - public void ANTConfigEventBuffering(short screenOnFlushTimerInterval, short screenOnFlushBufferThreshold, short screenOffFlushTimerInterval, short screenOffFlushBufferThreshold) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTConfigEventBuffering((int)screenOnFlushTimerInterval, (int)screenOnFlushBufferThreshold, (int)screenOffFlushTimerInterval, (int)screenOffFlushBufferThreshold)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT disable event buffering. - * - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.1 - */ - public void ANTDisableEventBuffering() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTDisableEventBuffering()) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT open channel. - * - * @param channelNumber the channel number - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTOpenChannel(byte channelNumber) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTOpenChannel(channelNumber)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT close channel. - * - * @param channelNumber the channel number - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTCloseChannel(byte channelNumber) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTCloseChannel(channelNumber)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT request message. - * - * @param channelNumber the channel number - * @param messageID the message id - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTRequestMessage(byte channelNumber, byte messageID) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTRequestMessage(channelNumber, messageID)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT send broadcast data. - * - * @param channelNumber the channel number - * @param txBuffer the tx buffer - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSendBroadcastData(byte channelNumber, byte[] txBuffer) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSendBroadcastData(channelNumber, txBuffer)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT send acknowledged data. - * - * @param channelNumber the channel number - * @param txBuffer the tx buffer - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSendAcknowledgedData(byte channelNumber, byte[] txBuffer) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSendAcknowledgedData(channelNumber, txBuffer)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT send burst transfer packet. - * - * @param control the control - * @param txBuffer the tx buffer - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public void ANTSendBurstTransferPacket(byte control, byte[] txBuffer) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - if(!sAntReceiver.ANTSendBurstTransferPacket(control, txBuffer)) - { - throw new AntInterfaceException(); - } - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Transmits the given data on channelNumber as part of a burst message. - * - * @param channelNumber Which channel to transmit on. - * @param txBuffer The data to send. - * @return The number of bytes still to be sent (approximately). 0 if success. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - */ - public int ANTSendBurstTransfer(byte channelNumber, byte[] txBuffer) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.ANTSendBurstTransfer(channelNumber, txBuffer); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * ANT send partial burst. - * - * @param channelNumber the channel number - * @param txBuffer the tx buffer - * @param initialPacket the initial packet - * @param containsEndOfBurst the contains end of burst - * @return The number of bytes still to be sent (approximately). 0 if success. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.0 - */ - public int ANTSendPartialBurst(byte channelNumber, byte[] txBuffer, int initialPacket, boolean containsEndOfBurst) throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.ANTTransmitBurst(channelNumber, txBuffer, initialPacket, containsEndOfBurst); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Returns the version code (eg. 1) of ANTLib used by the ANT application service - * - * @return the service library version code, or 0 on error. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.2 - */ - public int getServiceLibraryVersionCode() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - if(mServiceLibraryVersionCode == 0) - { - try - { - mServiceLibraryVersionCode = sAntReceiver.getServiceLibraryVersionCode(); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - return mServiceLibraryVersionCode; - } - - /** - * Returns the version name (eg "1.0") of ANTLib used by the ANT application service - * - * @return the service library version name, or null on error. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.2 - */ - public String getServiceLibraryVersionName() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.getServiceLibraryVersionName(); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Take control of the ANT Radio. - * - * @return True if control has been granted, false if another application has control or the request failed. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.5 - */ - public boolean claimInterface() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.claimInterface(); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Give up control of the ANT Radio. - * - * @return True if control has been given up, false if this application did not have control. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.5 - */ - public boolean releaseInterface() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.releaseInterface(); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Claims the interface if it is available. If not the user will be prompted (on the notification bar) if a force claim should be done. - * If the ANT Interface is claimed, an AntInterfaceIntent.ANT_INTERFACE_CLAIMED_ACTION intent will be sent, with the current applications pid. - * - * @param appName The name if this application, to show to the user. - * @returns false if a claim interface request notification already exists. - * @throws IllegalArgumentException - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.5 - */ - public boolean requestForceClaimInterface(String appName) throws AntInterfaceException - { - if((null == appName) || ("".equals(appName))) - { - throw new IllegalArgumentException(); - } - - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.requestForceClaimInterface(appName); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Clears the notification asking the user if they would like to seize control of the ANT Radio. - * - * @returns false if this process is not requesting to claim the interface. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.5 - */ - public boolean stopRequestForceClaimInterface() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.stopRequestForceClaimInterface(); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Check if the calling application has control of the ANT Radio. - * - * @return True if control is currently granted. - * @throws AntInterfaceException - * @throws AntServiceNotConnectedException - * @throws AntRemoteException - * @since 1.5 - */ - public boolean hasClaimedInterface() throws AntInterfaceException - { - if(!sServiceConnected) - { - throw new AntServiceNotConnectedException(); - } - - try - { - return sAntReceiver.hasClaimedInterface(); - } - catch(RemoteException e) - { - throw new AntRemoteException(e); - } - } - - /** - * Check if this device has support for ANT. - * - * @return True if the device supports ANT (may still require ANT Radio Service be installed). - * @since 1.5 - */ - public static boolean hasAntSupport(Context pContext) - { - if(!mCheckedAntSupported) - { - mAntSupported = Arrays.asList(pContext.getPackageManager().getSystemSharedLibraryNames()).contains(ANT_LIBRARY_NAME); - mCheckedAntSupported = true; - } - - return mAntSupported; - } -} diff --git a/MyTracks/src/com/dsi/ant/AntInterfaceIntent.java b/MyTracks/src/com/dsi/ant/AntInterfaceIntent.java deleted file mode 100644 index 7834e9daa..000000000 --- a/MyTracks/src/com/dsi/ant/AntInterfaceIntent.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - -/** - * Manages the ANT Interface - * - * @hide - */ -public interface AntInterfaceIntent { - - public static final String STATUS = "com.dsi.ant.rx.intent.STATUS"; - public static final String ANT_MESSAGE = "com.dsi.ant.intent.ANT_MESSAGE"; - public static final String ANT_INTERFACE_CLAIMED_PID = "com.dsi.ant.intent.ANT_INTERFACE_CLAIMED_PID"; - - public static final String ANT_ENABLED_ACTION = "com.dsi.ant.intent.action.ANT_ENABLED"; - public static final String ANT_DISABLED_ACTION = "com.dsi.ant.intent.action.ANT_DISABLED"; - public static final String ANT_RESET_ACTION = "com.dsi.ant.intent.action.ANT_RESET"; - - public static final String ANT_INTERFACE_CLAIMED_ACTION = "com.dsi.ant.intent.action.ANT_INTERFACE_CLAIMED_ACTION"; - - public static final String ANT_RX_MESSAGE_ACTION = "com.dsi.ant.intent.action.ANT_RX_MESSAGE_ACTION"; - -} diff --git a/MyTracks/src/com/dsi/ant/AntMesg.java b/MyTracks/src/com/dsi/ant/AntMesg.java deleted file mode 100644 index cf2ae70d9..000000000 --- a/MyTracks/src/com/dsi/ant/AntMesg.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Copyright 2010 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - -/** - * Public API for controlling the Ant Service. - * AntMesg contains definitions for ANT message IDs - * - * @hide - */ -public class AntMesg { - - ///////////////////////////////////////////////////////////////////////////// - // HCI VS Message Format - // Messages are in the format: - // - // Outgoing ANT messages (host -> ANT chip) - // 01 D1 FD XX YY YY II JJ ------ - // ^ ^ ^ ^ - // | HCI framing | | ANT Mesg | - // - // where: 01 is the 1 byte HCI packet Identifier (HCI Command packet) - // D1 FD is the 2 byte HCI op code (0xFDD1 stored in little endian) - // XX is the 1 byte Length of all parameters in bytes (number of bytes in the HCI packet after this byte) - // YY YY is the 2 byte Parameter describing the length of the entire ANT message (II JJ ------) stored in little endian - // II is the 1 byte size of the ANT message (0-249) - // JJ is the 1 byte ID of the ANT message (1-255, 0 is invalid) - // ------ is the data of the ANT message (0-249 bytes of data) - // - // Incoming HCI Command Complete for ANT message command (host <- ANT chip) - // 04 0E 04 01 D1 FD ZZ - // - // where: 04 is the 1 byte HCI packet Identifier (HCI Event packet) - // 0E is the 1 byte HCI event (Command Complete) - // 04 is the 1 byte Length of all parameters in bytes (there are 4 bytes) - // 01 is the 1 byte Number of parameters in the packet (there is 1 parameter) - // D1 FD is the 2 byte HCI Op code of the command (0xFDD1 stored in little endian) - // ZZ is the 1 byte response to the command (0x00 - Command Successful - // 0x1F - Returned if the receive message queue of the ANT chip is full, the command should be retried - // Other - Any other non-zero response code indicates an error) - // - // Incoming ANT messages (host <- ANT chip) - // 04 FF XX 00 05 YY YY II JJ ------ - // ^ ^ ^ ^ - // | HCI framing | | ANT Mesg | - // - // where: 04 is the 1 byte HCI packet Identifier (HCI Event packet) - // FF is the 1 byte HCI event code (0xFF Vendor Specific event) - // XX is the 1 byte Length of all parameters in bytes (number of bytes in the HCI packet after this byte) - // 00 05 is the 2 byte vendor specific event code for ANT messages (0x0500 stored in little endian) - // YY YY is the 2 byte Parameter describing the length of the entire ANT message (II JJ ------) stored in little endian - // II is the 1 byte size of the ANT message (0-249) - // JJ is the 1 byte ID of the ANT message (1-255, 0 is invalid) - // ------ is the data of the ANT message (0-249 bytes of data) - // - ///////////////////////////////////////////////////////////////////////////// - - public static final byte MESG_SYNC_SIZE =((byte)0); // Ant messages are embedded in HCI messages we do not include a sync byte - public static final byte MESG_SIZE_SIZE =((byte)1); - public static final byte MESG_ID_SIZE =((byte)1); - public static final byte MESG_CHANNEL_NUM_SIZE =((byte)1); - public static final byte MESG_EXT_MESG_BF_SIZE =((byte)1); // NOTE: this could increase in the future - public static final byte MESG_CHECKSUM_SIZE =((byte)0); // Ant messages are embedded in HCI messages we do not include a checksum - public static final byte MESG_DATA_SIZE =((byte)9); - - // The largest serial message is an ANT data message with all of the extended fields - public static final byte MESG_ANT_MAX_PAYLOAD_SIZE =AntDefine.ANT_STANDARD_DATA_PAYLOAD_SIZE; - - public static final byte MESG_MAX_EXT_DATA_SIZE =(AntDefine.ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE + AntDefine.ANT_EXT_STRING_SIZE); // ANT device ID (4 bytes) + Padding for ANT EXT string size(19 bytes) - - public static final byte MESG_MAX_DATA_SIZE =(MESG_ANT_MAX_PAYLOAD_SIZE + MESG_EXT_MESG_BF_SIZE + MESG_MAX_EXT_DATA_SIZE); // ANT data payload (8 bytes) + extended bitfield (1 byte) + extended data (10 bytes) - public static final byte MESG_MAX_SIZE_VALUE =(MESG_MAX_DATA_SIZE + MESG_CHANNEL_NUM_SIZE); // this is the maximum value that the serial message size value is allowed to be - public static final byte MESG_BUFFER_SIZE =(MESG_SIZE_SIZE + MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE + MESG_CHECKSUM_SIZE); - public static final byte MESG_FRAMED_SIZE =(MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE); - public static final byte MESG_HEADER_SIZE =(MESG_SYNC_SIZE + MESG_SIZE_SIZE + MESG_ID_SIZE); - public static final byte MESG_FRAME_SIZE =(MESG_HEADER_SIZE + MESG_CHECKSUM_SIZE); - public static final byte MESG_MAX_SIZE =(MESG_MAX_DATA_SIZE + MESG_FRAME_SIZE); - - public static final byte MESG_SIZE_OFFSET =(MESG_SYNC_SIZE); - public static final byte MESG_ID_OFFSET =(MESG_SYNC_SIZE + MESG_SIZE_SIZE); - public static final byte MESG_DATA_OFFSET =(MESG_HEADER_SIZE); - public static final byte MESG_RECOMMENDED_BUFFER_SIZE =((byte) 64); // This is the recommended size for serial message buffers if there are no RAM restrictions on the system - - ////////////////////////////////////////////// - // Message ID's - ////////////////////////////////////////////// - public static final byte MESG_INVALID_ID =((byte)0x00); - public static final byte MESG_EVENT_ID =((byte)0x01); - - public static final byte MESG_VERSION_ID =((byte)0x3E); - public static final byte MESG_RESPONSE_EVENT_ID =((byte)0x40); - - public static final byte MESG_UNASSIGN_CHANNEL_ID =((byte)0x41); - public static final byte MESG_ASSIGN_CHANNEL_ID =((byte)0x42); - public static final byte MESG_CHANNEL_MESG_PERIOD_ID =((byte)0x43); - public static final byte MESG_CHANNEL_SEARCH_TIMEOUT_ID =((byte)0x44); - public static final byte MESG_CHANNEL_RADIO_FREQ_ID =((byte)0x45); - public static final byte MESG_NETWORK_KEY_ID =((byte)0x46); - public static final byte MESG_RADIO_TX_POWER_ID =((byte)0x47); - public static final byte MESG_RADIO_CW_MODE_ID =((byte)0x48); - - public static final byte MESG_SYSTEM_RESET_ID =((byte)0x4A); - public static final byte MESG_OPEN_CHANNEL_ID =((byte)0x4B); - public static final byte MESG_CLOSE_CHANNEL_ID =((byte)0x4C); - public static final byte MESG_REQUEST_ID =((byte)0x4D); - - public static final byte MESG_BROADCAST_DATA_ID =((byte)0x4E); - public static final byte MESG_ACKNOWLEDGED_DATA_ID =((byte)0x4F); - public static final byte MESG_BURST_DATA_ID =((byte)0x50); - - public static final byte MESG_CHANNEL_ID_ID =((byte)0x51); - public static final byte MESG_CHANNEL_STATUS_ID =((byte)0x52); - public static final byte MESG_RADIO_CW_INIT_ID =((byte)0x53); - public static final byte MESG_CAPABILITIES_ID =((byte)0x54); - - public static final byte MESG_STACKLIMIT_ID =((byte)0x55); - - public static final byte MESG_SCRIPT_DATA_ID =((byte)0x56); - public static final byte MESG_SCRIPT_CMD_ID =((byte)0x57); - - public static final byte MESG_ID_LIST_ADD_ID =((byte)0x59); - public static final byte MESG_ID_LIST_CONFIG_ID =((byte)0x5A); - public static final byte MESG_OPEN_RX_SCAN_ID =((byte)0x5B); - - public static final byte MESG_EXT_CHANNEL_RADIO_FREQ_ID =((byte)0x5C); // OBSOLETE: (for 905 radio) - public static final byte MESG_EXT_BROADCAST_DATA_ID =((byte)0x5D); - public static final byte MESG_EXT_ACKNOWLEDGED_DATA_ID =((byte)0x5E); - public static final byte MESG_EXT_BURST_DATA_ID =((byte)0x5F); - - public static final byte MESG_CHANNEL_RADIO_TX_POWER_ID =((byte)0x60); - public static final byte MESG_GET_SERIAL_NUM_ID =((byte)0x61); - public static final byte MESG_GET_TEMP_CAL_ID =((byte)0x62); - public static final byte MESG_SET_LP_SEARCH_TIMEOUT_ID =((byte)0x63); - public static final byte MESG_SET_TX_SEARCH_ON_NEXT_ID =((byte)0x64); - public static final byte MESG_SERIAL_NUM_SET_CHANNEL_ID_ID =((byte)0x65); - public static final byte MESG_RX_EXT_MESGS_ENABLE_ID =((byte)0x66); - public static final byte MESG_RADIO_CONFIG_ALWAYS_ID =((byte)0x67); - public static final byte MESG_ENABLE_LED_FLASH_ID =((byte)0x68); - - public static final byte MESG_XTAL_ENABLE_ID =((byte)0x6D); - - public static final byte MESG_STARTUP_MESG_ID =((byte)0x6F); - public static final byte MESG_AUTO_FREQ_CONFIG_ID =((byte)0x70); - public static final byte MESG_PROX_SEARCH_CONFIG_ID =((byte)0x71); - public static final byte MESG_EVENT_BUFFERING_CONFIG_ID =((byte)0x74); - - - public static final byte MESG_CUBE_CMD_ID =((byte)0x80); - - public static final byte MESG_GET_PIN_DIODE_CONTROL_ID =((byte)0x8D); - public static final byte MESG_PIN_DIODE_CONTROL_ID =((byte)0x8E); - public static final byte MESG_FIT1_SET_AGC_ID =((byte)0x8F); - - public static final byte MESG_FIT1_SET_EQUIP_STATE_ID =((byte)0x91); // *** CONFLICT: w/ Sensrcore, Fit1 will never have sensrcore enabled - - // Sensrcore Messages - public static final byte MESG_SET_CHANNEL_INPUT_MASK_ID =((byte)0x90); - public static final byte MESG_SET_CHANNEL_DATA_TYPE_ID =((byte)0x91); - public static final byte MESG_READ_PINS_FOR_SECT_ID =((byte)0x92); - public static final byte MESG_TIMER_SELECT_ID =((byte)0x93); - public static final byte MESG_ATOD_SETTINGS_ID =((byte)0x94); - public static final byte MESG_SET_SHARED_ADDRESS_ID =((byte)0x95); - public static final byte MESG_ATOD_EXTERNAL_ENABLE_ID =((byte)0x96); - public static final byte MESG_ATOD_PIN_SETUP_ID =((byte)0x97); - public static final byte MESG_SETUP_ALARM_ID =((byte)0x98); - public static final byte MESG_ALARM_VARIABLE_MODIFY_TEST_ID =((byte)0x99); - public static final byte MESG_PARTIAL_RESET_ID =((byte)0x9A); - public static final byte MESG_OVERWRITE_TEMP_CAL_ID =((byte)0x9B); - public static final byte MESG_SERIAL_PASSTHRU_SETTINGS_ID =((byte)0x9C); - - public static final byte MESG_BIST_ID =((byte)0xAA); - - public static final byte MESG_UNLOCK_INTERFACE_ID =((byte)0xAD); - public static final byte MESG_SERIAL_ERROR_ID =((byte)0xAE); - public static final byte MESG_SET_ID_STRING_ID =((byte)0xAF); - - public static final byte MESG_PORT_GET_IO_STATE_ID =((byte)0xB4); - public static final byte MESG_PORT_SET_IO_STATE_ID =((byte)0xB5); - - public static final byte MESG_SLEEP_ID =((byte)0xC5); - public static final byte MESG_GET_GRMN_ESN_ID =((byte)0xC6); - public static final byte MESG_SET_USB_INFO_ID =((byte)0xC7); - - public static final byte MESG_COMMAND_COMPLETE_RESPONSE_ID =((byte)0xC8); - - ////////////////////////////////////////////// - // Command complete results - ////////////////////////////////////////////// - public static final byte MESG_COMMAND_COMPLETE_SUCCESS =((byte)0x00); - public static final byte MESG_COMMAND_COMPLETE_RETRY =((byte)0x1F); - - ////////////////////////////////////////////// - // Message Sizes - ////////////////////////////////////////////// - public static final byte MESG_INVALID_SIZE =((byte)0); - - public static final byte MESG_VERSION_SIZE =((byte)13); - public static final byte MESG_RESPONSE_EVENT_SIZE =((byte)3); - public static final byte MESG_CHANNEL_STATUS_SIZE =((byte)2); - - public static final byte MESG_UNASSIGN_CHANNEL_SIZE =((byte)1); - public static final byte MESG_ASSIGN_CHANNEL_SIZE =((byte)3); - public static final byte MESG_CHANNEL_ID_SIZE =((byte)5); - public static final byte MESG_CHANNEL_MESG_PERIOD_SIZE =((byte)3); - public static final byte MESG_CHANNEL_SEARCH_TIMEOUT_SIZE =((byte)2); - public static final byte MESG_CHANNEL_RADIO_FREQ_SIZE =((byte)2); - public static final byte MESG_CHANNEL_RADIO_TX_POWER_SIZE =((byte)2); - public static final byte MESG_NETWORK_KEY_SIZE =((byte)9); - public static final byte MESG_RADIO_TX_POWER_SIZE =((byte)2); - public static final byte MESG_RADIO_CW_MODE_SIZE =((byte)3); - public static final byte MESG_RADIO_CW_INIT_SIZE =((byte)1); - - public static final byte MESG_SYSTEM_RESET_SIZE =((byte)1); - public static final byte MESG_OPEN_CHANNEL_SIZE =((byte)1); - public static final byte MESG_CLOSE_CHANNEL_SIZE =((byte)1); - public static final byte MESG_REQUEST_SIZE =((byte)2); - - public static final byte MESG_CAPABILITIES_SIZE =((byte)6); - public static final byte MESG_STACKLIMIT_SIZE =((byte)2); - - public static final byte MESG_SCRIPT_DATA_SIZE =((byte)10); - public static final byte MESG_SCRIPT_CMD_SIZE =((byte)3); - - public static final byte MESG_ID_LIST_ADD_SIZE =((byte)6); - public static final byte MESG_ID_LIST_CONFIG_SIZE =((byte)3); - public static final byte MESG_OPEN_RX_SCAN_SIZE =((byte)1); - public static final byte MESG_EXT_CHANNEL_RADIO_FREQ_SIZE =((byte)3); - - public static final byte MESG_RADIO_CONFIG_ALWAYS_SIZE =((byte)2); - public static final byte MESG_RX_EXT_MESGS_ENABLE_SIZE =((byte)2); - public static final byte MESG_SET_TX_SEARCH_ON_NEXT_SIZE =((byte)2); - public static final byte MESG_SET_LP_SEARCH_TIMEOUT_SIZE =((byte)2); - - public static final byte MESG_SERIAL_NUM_SET_CHANNEL_ID_SIZE =((byte)3); - public static final byte MESG_ENABLE_LED_FLASH_SIZE =((byte)2); - public static final byte MESG_GET_SERIAL_NUM_SIZE =((byte)4); - public static final byte MESG_GET_TEMP_CAL_SIZE =((byte)4); - - public static final byte MESG_XTAL_ENABLE_SIZE =((byte)1); - public static final byte MESG_STARTUP_MESG_SIZE =((byte)1); - public static final byte MESG_AUTO_FREQ_CONFIG_SIZE =((byte)4); - public static final byte MESG_PROX_SEARCH_CONFIG_SIZE =((byte)2); - - public static final byte MESG_GET_PIN_DIODE_CONTROL_SIZE =((byte)1); - public static final byte MESG_PIN_DIODE_CONTROL_ID_SIZE =((byte)2); - public static final byte MESG_FIT1_SET_EQUIP_STATE_SIZE =((byte)2); - public static final byte MESG_FIT1_SET_AGC_SIZE =((byte)3); - - public static final byte MESG_BIST_SIZE =((byte)6); - public static final byte MESG_UNLOCK_INTERFACE_SIZE =((byte)1); - public static final byte MESG_SET_SHARED_ADDRESS_SIZE =((byte)3); - - public static final byte MESG_GET_GRMN_ESN_SIZE =((byte)5); - - public static final byte MESG_PORT_SET_IO_STATE_SIZE =((byte)5); - - public static final byte MESG_EVENT_BUFFERING_CONFIG_SIZE =((byte)6); - - public static final byte MESG_SLEEP_SIZE =((byte)1); - - - public static final byte MESG_EXT_DATA_SIZE =((byte)13); - - protected AntMesg() - { } -} diff --git a/MyTracks/src/com/dsi/ant/IAnt.aidl b/MyTracks/src/com/dsi/ant/IAnt.aidl deleted file mode 100644 index 8ee999070..000000000 --- a/MyTracks/src/com/dsi/ant/IAnt.aidl +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2010 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - -/** - * The Android Ant API is not finalized, and *will* be updated and expanded. - * This is the base level ANT messaging API and gives any application full - * control over the ANT radio HW. Caution should be exercised when using - * this interface. - * - * Public API for controlling the Ant Service. - * - * {@hide} - */ -interface IAnt { -// Since version 1 (1.0): - boolean enable(); - boolean disable(); - boolean isEnabled(); - - boolean ANTTxMessage(in byte[] message); - - boolean ANTResetSystem(); - boolean ANTUnassignChannel(byte channelNumber); - boolean ANTAssignChannel(byte channelNumber, byte channelType, byte networkNumber); - boolean ANTSetChannelId(byte channelNumber, int deviceNumber, byte deviceType, byte txType); - boolean ANTSetChannelPeriod(byte channelNumber, int channelPeriod); - boolean ANTSetChannelRFFreq(byte channelNumber, byte radioFrequency); - boolean ANTSetChannelSearchTimeout(byte channelNumber, byte searchTimeout); - boolean ANTSetLowPriorityChannelSearchTimeout(byte channelNumber, byte searchTimeout); - boolean ANTSetProximitySearch(byte channelNumber, byte searchThreshold); - boolean ANTSetChannelTxPower(byte channelNumber, byte txPower); - boolean ANTAddChannelId(byte channelNumber, int deviceNumber, byte deviceType, byte txType, byte listIndex); - boolean ANTConfigList(byte channelNumber, byte listSize, byte exclude); - - boolean ANTOpenChannel(byte channelNumber); - boolean ANTCloseChannel(byte channelNumber); - - boolean ANTRequestMessage(byte channelNumber, byte messageID); - boolean ANTSendBroadcastData(byte channelNumber, in byte[] txBuffer); - boolean ANTSendAcknowledgedData(byte channelNumber, in byte[] txBuffer); - - boolean ANTSendBurstTransferPacket(byte control, in byte[] txBuffer); - - int ANTSendBurstTransfer(byte channelNumber, in byte[] txBuffer); - int ANTTransmitBurst(byte channelNumber, in byte[] txBuffer, int initialPacket, boolean containsEndOfBurst); - -// Since version 4 (1.3): - boolean ANTConfigEventBuffering(int screenOnFlushTimerInterval, int screenOnFlushBufferThreshold, int screenOffFlushTimerInterval, int screenOffFlushBufferThreshold); - -// Since version 2 (1.1): - boolean ANTDisableEventBuffering(); - -// Since version 3 (1.2): - int getServiceLibraryVersionCode(); - String getServiceLibraryVersionName(); -} diff --git a/MyTracks/src/com/dsi/ant/IAnt_6.aidl b/MyTracks/src/com/dsi/ant/IAnt_6.aidl deleted file mode 100644 index 4caccbeb7..000000000 --- a/MyTracks/src/com/dsi/ant/IAnt_6.aidl +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2011 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - -/** - * The Android Ant API is not finalized, and *will* be updated and expanded. - * This is the base level ANT messaging API and gives any application full - * control over the ANT radio HW. Caution should be exercised when using - * this interface. - * - * Public API for controlling the Ant Service. - * - * {@hide} - */ -interface IAnt_6 { -// Since version 1 (1.0): - boolean enable(); - boolean disable(); - boolean isEnabled(); - - boolean ANTTxMessage(in byte[] message); - - boolean ANTResetSystem(); - boolean ANTUnassignChannel(byte channelNumber); - boolean ANTAssignChannel(byte channelNumber, byte channelType, byte networkNumber); - boolean ANTSetChannelId(byte channelNumber, int deviceNumber, byte deviceType, byte txType); - boolean ANTSetChannelPeriod(byte channelNumber, int channelPeriod); - boolean ANTSetChannelRFFreq(byte channelNumber, byte radioFrequency); - boolean ANTSetChannelSearchTimeout(byte channelNumber, byte searchTimeout); - boolean ANTSetLowPriorityChannelSearchTimeout(byte channelNumber, byte searchTimeout); - boolean ANTSetProximitySearch(byte channelNumber, byte searchThreshold); - boolean ANTSetChannelTxPower(byte channelNumber, byte txPower); - boolean ANTAddChannelId(byte channelNumber, int deviceNumber, byte deviceType, byte txType, byte listIndex); - boolean ANTConfigList(byte channelNumber, byte listSize, byte exclude); - - boolean ANTOpenChannel(byte channelNumber); - boolean ANTCloseChannel(byte channelNumber); - - boolean ANTRequestMessage(byte channelNumber, byte messageID); - boolean ANTSendBroadcastData(byte channelNumber, in byte[] txBuffer); - boolean ANTSendAcknowledgedData(byte channelNumber, in byte[] txBuffer); - - boolean ANTSendBurstTransferPacket(byte control, in byte[] txBuffer); - - int ANTSendBurstTransfer(byte channelNumber, in byte[] txBuffer); - int ANTTransmitBurst(byte channelNumber, in byte[] txBuffer, int initialPacket, boolean containsEndOfBurst); - -// Since version 4 (1.3): - boolean ANTConfigEventBuffering(int screenOnFlushTimerInterval, int screenOnFlushBufferThreshold, int screenOffFlushTimerInterval, int screenOffFlushBufferThreshold); - -// Since version 2 (1.1): - boolean ANTDisableEventBuffering(); - -// Since version 3 (1.2): - int getServiceLibraryVersionCode(); - String getServiceLibraryVersionName(); - -// Since version 6 (1.5): - boolean claimInterface(); - boolean requestForceClaimInterface(String appName); - boolean stopRequestForceClaimInterface(); - boolean releaseInterface(); - boolean hasClaimedInterface(); -} diff --git a/MyTracks/src/com/dsi/ant/IServiceSettings.aidl b/MyTracks/src/com/dsi/ant/IServiceSettings.aidl deleted file mode 100644 index 3d0cf61c8..000000000 --- a/MyTracks/src/com/dsi/ant/IServiceSettings.aidl +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2010 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - -/** - * - * API for configuring the non-ANT components of the ANT Service. - * - * {@hide} - */ -interface IServiceSettings { - void debugLogging(boolean debug); - - boolean setNumCombinedBurstPackets(int numPackets); - int getNumCombinedBurstPackets(); -} diff --git a/MyTracks/src/com/dsi/ant/Version.java b/MyTracks/src/com/dsi/ant/Version.java deleted file mode 100644 index 7d7cb8bd5..000000000 --- a/MyTracks/src/com/dsi/ant/Version.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011 Dynastream Innovations Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.dsi.ant; - - - -/** - * Defines version numbers - * - * @hide - */ -public class Version { - - ////////////////////////////////////////////// - // Library Version Information - ////////////////////////////////////////////// - public static final int ANT_LIBRARY_VERSION_CODE = 6; - public static final int ANT_LIBRARY_VERSION_MAJOR = 2; - public static final int ANT_LIBRARY_VERSION_MINOR = 0; - public static final String ANT_LIBRARY_VERSION_NAME = String.valueOf(ANT_LIBRARY_VERSION_MAJOR) + "." + String.valueOf(ANT_LIBRARY_VERSION_MINOR); - -} \ No newline at end of file diff --git a/MyTracks/src/com/dsi/ant/exception/AntInterfaceException.java b/MyTracks/src/com/dsi/ant/exception/AntInterfaceException.java deleted file mode 100644 index 164374e4a..000000000 --- a/MyTracks/src/com/dsi/ant/exception/AntInterfaceException.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.dsi.ant.exception; - -public class AntInterfaceException extends Exception -{ - - /** - * - */ - private static final long serialVersionUID = -7278855366167722274L; - - public AntInterfaceException() - { - this("Unknown ANT Interface error"); - } - - public AntInterfaceException(String string) - { - super(string); - } -} diff --git a/MyTracks/src/com/dsi/ant/exception/AntRemoteException.java b/MyTracks/src/com/dsi/ant/exception/AntRemoteException.java deleted file mode 100644 index 960740f1c..000000000 --- a/MyTracks/src/com/dsi/ant/exception/AntRemoteException.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.dsi.ant.exception; - -import android.os.RemoteException; - -public class AntRemoteException extends AntInterfaceException -{ - /** - * - */ - private static final long serialVersionUID = 8950974759973459561L; - - public AntRemoteException(RemoteException e) - { - this("ANT Interface error, ANT Radio Service remote error: "+e.toString(), e); - } - - public AntRemoteException(String string, RemoteException e) - { - super(string); - - this.initCause(e); - } -} diff --git a/MyTracks/src/com/dsi/ant/exception/AntServiceNotConnectedException.java b/MyTracks/src/com/dsi/ant/exception/AntServiceNotConnectedException.java deleted file mode 100644 index fc131cf8f..000000000 --- a/MyTracks/src/com/dsi/ant/exception/AntServiceNotConnectedException.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.dsi.ant.exception; - -public class AntServiceNotConnectedException extends AntInterfaceException -{ - /** - * - */ - private static final long serialVersionUID = -2085081032170129309L; - - public AntServiceNotConnectedException() - { - this("ANT Interface error, ANT Radio Service not connected."); - } - - public AntServiceNotConnectedException(String string) - { - super(string); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/AntPreference.java b/MyTracks/src/com/google/android/apps/mytracks/AntPreference.java deleted file mode 100644 index 687facde6..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/AntPreference.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks; - -import com.google.android.maps.mytracks.R; - -import android.content.Context; -import android.preference.Preference; -import android.util.AttributeSet; - -/** - * A preference for an ANT device pairing. - * Currently this shows the ID and lets the user clear that ID for future pairing. - * TODO: Support pairing from this preference. - * - * @author Sandor Dornbush - */ -public class AntPreference extends Preference { - - private final static int DEFAULT_PERSISTEDINT = 0; - - public AntPreference(Context context) { - super(context); - init(); - } - - public AntPreference(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - private void init() { - int sensorId = getPersistedInt(AntPreference.DEFAULT_PERSISTEDINT); - if (sensorId == 0) { - setSummary(R.string.settings_sensor_ant_not_paired); - } else { - setSummary(getContext().getString(R.string.settings_sensor_ant_paired, sensorId)); - } - - // Add actions to allow repairing. - setOnPreferenceClickListener( - new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - AntPreference.this.persistInt(0); - setSummary(R.string.settings_sensor_ant_not_paired); - return true; - } - }); - } -} \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/BluetoothSensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/BluetoothSensorManager.java index a8b8ce0af..fb12c8f9a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/BluetoothSensorManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/BluetoothSensorManager.java @@ -96,8 +96,7 @@ public class BluetoothSensorManager extends SensorManager { case BluetoothConnectionManager.MESSAGE_DEVICE_NAME: String deviceName = message.getData() .getString(BluetoothConnectionManager.KEY_DEVICE_NAME); - Toast.makeText(context, - context.getString(R.string.settings_sensor_bluetooth_connected, deviceName), + Toast.makeText(context, context.getString(R.string.settings_sensor_connected, deviceName), Toast.LENGTH_SHORT).show(); break; case BluetoothConnectionManager.MESSAGE_READ: diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java index 0f651fe70..d4e16bba1 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/SensorManagerFactory.java @@ -16,8 +16,7 @@ package com.google.android.apps.mytracks.services.sensors; -import com.google.android.apps.mytracks.services.sensors.ant.AntDirectSensorManager; -import com.google.android.apps.mytracks.services.sensors.ant.AntSrmBridgeSensorManager; +import com.google.android.apps.mytracks.services.sensors.ant.AntSensorManager; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.maps.mytracks.R; @@ -98,9 +97,7 @@ public class SensorManagerFactory { context, R.string.sensor_type_key, sensorTypeValueNone); if (sensorType.equals(context.getString(R.string.sensor_type_value_ant))) { - return new AntDirectSensorManager(context); - } else if (sensorType.equals(context.getString(R.string.sensor_type_value_srm_ant_bridge))) { - return new AntSrmBridgeSensorManager(context); + return new AntSensorManager(context); } else if (sensorType.equals(context.getString(R.string.sensor_type_value_zephyr))) { return new ZephyrSensorManager(context); } else if (sensorType.equals(context.getString(R.string.sensor_type_value_polar))) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelIdMessage.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelIdMessage.java deleted file mode 100644 index 2d866fe1c..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelIdMessage.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -/** - * This class decodes and encapsulates an ANT Channel ID message. - * (ANT Message ID 0x51, Protocol & Usage guide v4.2 section 9.5.7.2) - * - * @author Matthew Simmons - */ -public class AntChannelIdMessage extends AntMessage { - private byte channelNumber; - private short deviceNumber; - private byte deviceTypeId; - private byte transmissionType; - - public AntChannelIdMessage(byte[] messageData) { - channelNumber = messageData[0]; - deviceNumber = decodeShort(messageData[1], messageData[2]); - deviceTypeId = messageData[3]; - transmissionType = messageData[4]; - } - - /** Returns the channel number */ - public byte getChannelNumber() { - return channelNumber; - } - - /** Returns the device number */ - public short getDeviceNumber() { - return deviceNumber; - } - - /** Returns the device type */ - public byte getDeviceTypeId() { - return deviceTypeId; - } - - /** Returns the transmission type */ - public byte getTransmissionType() { - return transmissionType; - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelResponseMessage.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelResponseMessage.java deleted file mode 100644 index a29a0757d..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelResponseMessage.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -/** - * This class decodes and encapsulates an ANT Channel Response / Event message. - * (ANT Message ID 0x40, Protocol & Usage guide v4.2 section 9.5.6.1) - * - * @author Matthew Simmons - */ -public class AntChannelResponseMessage extends AntMessage { - private byte channelNumber; - private byte messageId; - private byte messageCode; - - public AntChannelResponseMessage(byte[] messageData) { - channelNumber = messageData[0]; - messageId = messageData[1]; - messageCode = messageData[2]; - } - - /** Returns the channel number */ - public byte getChannelNumber() { - return channelNumber; - } - - /** Returns the ID of the message being responded to */ - public byte getMessageId() { - return messageId; - } - - /** Returns the code for a specific response or event */ - public byte getMessageCode() { - return messageCode; - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManager.java deleted file mode 100644 index 669c8b040..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManager.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import static com.google.android.apps.mytracks.Constants.TAG; - -import com.dsi.ant.AntDefine; -import com.dsi.ant.AntMesg; -import com.dsi.ant.exception.AntInterfaceException; -import com.google.android.apps.mytracks.content.Sensor; -import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.maps.mytracks.R; - -import android.content.Context; -import android.util.Log; - -/** - * A sensor manager to connect ANT+ sensors. - * - * @author Sandor Dornbush - * @author Laszlo Molnar - */ -public class AntDirectSensorManager extends AntSensorManager - implements AntSensorDataCollector { - - // allocating one channel for each sensor type - private static final byte HEART_RATE_CHANNEL = 0; - private static final byte CADENCE_CHANNEL = 1; - private static final byte CADENCE_SPEED_CHANNEL = 2; - - // ids for device number preferences - private static final int sensorIdKeys[] = { - R.string.ant_heart_rate_sensor_id_key, - R.string.ant_cadence_sensor_id_key, - R.string.ant_cadence_speed_sensor_id_key, - }; - - private AntSensorBase sensors[] = null; - - // current data to be sent for SensorDataSet - private static final byte HEART_RATE_DATA_INDEX = 0; - private static final byte CADENCE_DATA_INDEX = 1; - private int currentSensorData[] = { -1, -1 }; - - private long lastDataSentMillis = 0; - private byte connectingChannelsBitmap = 0; - - public AntDirectSensorManager(Context context) { - super(context); - } - - @Override - protected boolean handleMessage(byte messageId, byte[] messageData) { - if (super.handleMessage(messageId, messageData)) { - return true; - } - - int channel = messageData[0] & AntDefine.CHANNEL_NUMBER_MASK; - if (sensors == null || channel >= sensors.length) { - Log.d(TAG, "Unknown channel in message: " + channel); - return false; - } - - AntSensorBase sensor = sensors[channel]; - switch (messageId) { - case AntMesg.MESG_BROADCAST_DATA_ID: - if (sensor.getDeviceNumber() == WILDCARD) { - resolveWildcardDeviceNumber((byte) channel); - } - sensor.handleBroadcastData(messageData, this); - break; - case AntMesg.MESG_RESPONSE_EVENT_ID: - handleMessageResponse(messageData); - break; - case AntMesg.MESG_CHANNEL_ID_ID: - sensor.setDeviceNumber(handleChannelId(messageData)); - break; - default: - Log.e(TAG, "Unexpected ANT message id: " + messageId); - } - - return true; - } - - private short handleChannelId(byte[] rawMessage) { - AntChannelIdMessage message = new AntChannelIdMessage(rawMessage); - short deviceNumber = message.getDeviceNumber(); - byte channel = message.getChannelNumber(); - if (channel >= sensors.length) { - Log.d(TAG, "Unknown channel in message: " + channel); - return WILDCARD; - } - Log.i(TAG, "Found ANT device id: " + deviceNumber + " on channel: " + channel); - - PreferencesUtils.setInt(context, sensorIdKeys[channel], deviceNumber); - return deviceNumber; - } - - private void channelOut(byte channel) - { - if (channel >= sensors.length) { - Log.d(TAG, "Unknown channel in message: " + channel); - return; - } - connectingChannelsBitmap &= ~(1 << channel); - Log.i(TAG, "ANT channel " + channel + " disconnected."); - - if (sensors[channel].getDeviceNumber() != WILDCARD) { - Log.i(TAG, "Retrying...."); - if (setupChannel(sensors[channel], channel)) { - connectingChannelsBitmap |= 1 << channel; - } - } - if (connectingChannelsBitmap == 0) { - setSensorState(Sensor.SensorState.DISCONNECTED); - } - } - - private void handleMessageResponse(byte[] rawMessage) { - AntChannelResponseMessage message = new AntChannelResponseMessage(rawMessage); - byte channel = message.getChannelNumber(); - switch (message.getMessageId()) { - case AntMesg.MESG_EVENT_ID: - if (message.getMessageCode() == AntDefine.EVENT_RX_SEARCH_TIMEOUT) { - // Search timeout - Log.w(TAG, "ANT search timed out. Unassigning channel " + channel); - try { - getAntReceiver().ANTUnassignChannel(channel); - } catch (AntInterfaceException e) { - Log.e(TAG, "ANT error unassigning channel", e); - channelOut(channel); - } - } - break; - - case AntMesg.MESG_UNASSIGN_CHANNEL_ID: - channelOut(channel); - break; - } - } - - private void resolveWildcardDeviceNumber(byte channel) { - try { - getAntReceiver().ANTRequestMessage(channel, AntMesg.MESG_CHANNEL_ID_ID); - } catch (AntInterfaceException e) { - Log.e(TAG, "ANT error handling broadcast data", e); - } - Log.d(TAG, "Requesting channel id id on channel: " + channel); - } - - @Override - protected void setupAntSensorChannels() { - short devIds[] = new short[sensorIdKeys.length]; - - for (int i = 0; i < sensorIdKeys.length; ++i) { - devIds[i] = (short) PreferencesUtils.getInt(context, sensorIdKeys[i], WILDCARD); - } - - sensors = new AntSensorBase[] { - new HeartRateSensor(devIds[HEART_RATE_CHANNEL]), - new CadenceSensor(devIds[CADENCE_CHANNEL]), - new CadenceSpeedSensor(devIds[CADENCE_SPEED_CHANNEL]), - }; - - connectingChannelsBitmap = 0; - for (int i = 0; i < sensors.length; ++i) { - if (setupChannel(sensors[i], (byte) i)) { - connectingChannelsBitmap |= 1 << i; - } - } - if (connectingChannelsBitmap == 0) { - setSensorState(Sensor.SensorState.DISCONNECTED); - } - } - - protected boolean setupChannel(AntSensorBase sensor, byte channel) { - Log.i(TAG, "setup channel=" + channel + " deviceType=" + sensor.getDeviceType()); - - return setupAntSensorChannel(sensor.getNetworkNumber(), - channel, - sensor.getDeviceNumber(), - sensor.getDeviceType(), - (byte) 0x01, - sensor.getChannelPeriod(), - sensor.getFrequency(), - (byte) 0); - } - - private void sendSensorData(byte index, int value) { - if (index >= currentSensorData.length) { - Log.w(TAG, "invalid index in sendSensorData:" + index); - return; - } - currentSensorData[index] = value; - - long now = System.currentTimeMillis(); - // data comes in at ~4Hz rate from the sensors, so after >300 msec - // fresh data is here from all the connected sensors - if (now < lastDataSentMillis + 300) { - return; - } - lastDataSentMillis = now; - setSensorState(Sensor.SensorState.CONNECTED); - - Sensor.SensorDataSet.Builder b = Sensor.SensorDataSet.newBuilder(); - if (currentSensorData[HEART_RATE_DATA_INDEX] >= 0) { - b.setHeartRate( - Sensor.SensorData.newBuilder() - .setValue(currentSensorData[HEART_RATE_DATA_INDEX]) - .setState(Sensor.SensorState.SENDING)); - } - - if (currentSensorData[CADENCE_DATA_INDEX] >= 0) { - b.setCadence( - Sensor.SensorData.newBuilder() - .setValue(currentSensorData[CADENCE_DATA_INDEX]) - .setState(Sensor.SensorState.SENDING)); - } - sensorData = b.setCreationTime(now).build(); - } - - public void setCadence(int value) { - sendSensorData(CADENCE_DATA_INDEX, value); - } - - public void setHeartRate(int value) { - sendSensorData(HEART_RATE_DATA_INDEX, value); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntMessage.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntMessage.java deleted file mode 100644 index b11c76da9..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntMessage.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -/** - * This is a common superclass for ANT message subclasses. - * - * @author Matthew Simmons - */ -public class AntMessage { - protected AntMessage() {} - - /** Build a short value from its constituent bytes */ - protected static short decodeShort(byte b0, byte b1) { - int value = b0 & 0xFF; - value |= (b1 & 0xFF) << 8; - return (short)value; - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensor.java deleted file mode 100644 index beac735a5..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensor.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.google.android.apps.mytracks.services.sensors.ant; - -/** - * A enum which stores static data about ANT sensors. - * - * @author Matthew Simmons - */ -public enum AntSensor { - SENSOR_HEART_RATE (Constants.ANT_DEVICE_TYPE_HRM), - SENSOR_CADENCE (Constants.ANT_DEVICE_TYPE_CADENCE), - SENSOR_SPEED (Constants.ANT_DEVICE_TYPE_SPEED), - SENSOR_POWER (Constants.ANT_DEVICE_TYPE_POWER); - - private static class Constants { - public static byte ANT_DEVICE_TYPE_POWER = 11; - public static byte ANT_DEVICE_TYPE_HRM = 120; - public static byte ANT_DEVICE_TYPE_CADENCE = 122; - public static byte ANT_DEVICE_TYPE_SPEED = 123; - }; - - private final byte deviceType; - - private AntSensor(byte deviceType) { - this.deviceType = deviceType; - } - - public byte getDeviceType() { - return deviceType; - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorBase.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorBase.java deleted file mode 100644 index 6e2dfb3f1..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorBase.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import static com.google.android.apps.mytracks.Constants.TAG; - -import android.util.Log; - -/** - * Base class for ANT+ sensors. - * - * @author Laszlo Molnar - */ - -public abstract class AntSensorBase { - /* - * These constants are defined by the ANT+ spec. - */ - public static final byte NETWORK_NUMBER = 1; - public static final byte RF_FREQUENCY = 57; - - private short deviceNumber; - private final byte deviceType; - private final short channelPeriod; - - AntSensorBase(short deviceNumber, byte deviceType, - String deviceTypeString, short channelPeriod) { - this.deviceNumber = deviceNumber; - this.deviceType = deviceType; - this.channelPeriod = channelPeriod; - - Log.i(TAG, "Will pair with " + deviceTypeString + " device: " + ((int) deviceNumber & 0xFFFF)); - } - - public abstract void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c); - - public void setDeviceNumber(short dn) { - deviceNumber = dn; - } - - public short getDeviceNumber() { - return deviceNumber; - } - - public byte getNetworkNumber() { - return NETWORK_NUMBER; - } - - public byte getFrequency() { - return RF_FREQUENCY; - } - - public byte getDeviceType() { - return deviceType; - } - - public short getChannelPeriod() { - return channelPeriod; - } -}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java index d174a6138..2ed9f6cf1 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2009 Google Inc. + * Copyright 2012 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of @@ -13,9 +13,8 @@ * License for the specific language governing permissions and limitations under * the License. */ -package com.google.android.apps.mytracks.services.sensors.ant; -import static com.google.android.apps.mytracks.Constants.TAG; +package com.google.android.apps.mytracks.services.sensors.ant; import com.dsi.ant.AntDefine; import com.dsi.ant.AntInterface; @@ -25,361 +24,696 @@ import com.dsi.ant.exception.AntInterfaceException; import com.dsi.ant.exception.AntServiceNotConnectedException; import com.google.android.apps.mytracks.content.Sensor; import com.google.android.apps.mytracks.content.Sensor.SensorDataSet; +import com.google.android.apps.mytracks.content.Sensor.SensorState; import com.google.android.apps.mytracks.services.sensors.SensorManager; +import com.google.android.apps.mytracks.util.PreferencesUtils; +import com.google.android.maps.mytracks.R; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.provider.Settings; import android.util.Log; +import android.widget.Toast; -import java.util.Locale; +import java.lang.reflect.Field; /** - * This is the common superclass for ANT-based sensors. It handles tasks which - * apply to the ANT framework as a whole, such as framework initialization and - * destruction. Subclasses are expected to handle the initialization and - * management of individual sensors. - * - * Implementation: - * - * The initialization process is somewhat complicated. This is due in part to - * the asynchronous nature of ANT Radio Service initialization, and in part due - * to an apparent bug in that service. The following is an overview of the - * initialization process. - * - * Initialization begins in {@link #setupChannel}, which is invoked by the - * {@link SensorManager} when track recording begins. {@link #setupChannel} - * asks the ANT Radio Service (via {@link AntInterface}) to start, using a - * AntInterface.ServiceListener to indicate when the service has - * connected. {@link #serviceConnected} claims and enables the Radio Service, - * and then resets it to a known state for our use. Completion of reset is - * indicated by receipt of a startup message (see {@link AntStartupMessage}). - * Once we've received that message, the ANT service is ready for use, and we - * can start sensor-specific initialization using - * {@link #setupAntSensorChannels}. The initialization of each sensor will - * usually result in a call to {@link #setupAntSensorChannel}. - * - * @author Sandor Dornbush + * Ant Sensor Manager. + * + * @author Jimmy Shih */ -public abstract class AntSensorManager extends SensorManager { - - // Pairing - protected static final short WILDCARD = 0; - - private AntInterface antReceiver; +public class AntSensorManager extends SensorManager { /** - * The data from the sensors. + * Channel States */ - protected SensorDataSet sensorData; + public enum ChannelStates { + CLOSED, // Channel is closed + PENDING_OPEN, // User has requested opening the channel, waiting for a reset + SEARCHING, // Channel is opened, but has not received data + TRACKING_STATUS, // Channel is opened and has received status data recently + TRACKING_DATA, // Channel is opened and has received measurement data + // recently + OFFLINE // Channel is closed as the result of a search timeout + } - protected Context context; + private static final String TAG = AntSensorManager.class.getSimpleName(); - private static final boolean DEBUGGING = false; + public static final short WILDCARD = 0; - /** Receives and logs all status ANT intents. */ - private final BroadcastReceiver statusReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context ctx, Intent intent) { - String antAction = intent.getAction(); - Log.i(TAG, "enter status onReceive" + antAction); - } - }; + private static final int CHANNELS = 2; + private static final byte HRM_CHANNEL = (byte) 0; + private static final byte SDM_CHANNEL = (byte) 1; - /** Receives all data ANT intents. */ - private final BroadcastReceiver dataReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context ctx, Intent intent) { - String antAction = intent.getAction(); - Log.i(TAG, "enter data onReceive" + antAction); + private static final byte HRM_DEVICE_TYPE = 0x78; + private static final byte SDM_DEVICE_TYPE = 0x7C; - if (antAction != null && antAction.equals(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION)) { - byte[] antMessage = intent.getByteArrayExtra(AntInterfaceIntent.ANT_MESSAGE); - if (DEBUGGING) { - Log.d(TAG, "Received RX message " + messageToString(antMessage)); - } - if (getAntReceiver() != null) { - handleMessage(antMessage); + private static final short HRM_PERIOD = 8070; + private static final short SDM_PERIOD = 8134; + + private static final byte DEFAULT_PROXIMITY_SEARCH_BIN = 7; + private static final short SCREEN_ON_BUFFER_THRESHOLD = AntDefine.MIN_BUFFER_THRESHOLD; + private static final short SCREEN_OFF_BUFFER_THRESHOLD = AntDefine.MAX_BUFFER_THRESHOLD; + + private static final String RADIO_ANT = "ant"; + private static final byte ANT_NETWORK = (byte) 0x01; + private static final int ANT_FREQUENCY = 57; // 2457Mhz (Ant+ frequency) + private static final int ANT_TRANSMISSION_TYPE = 0; // 0 for wild card search + + private final Context context; + private final ChannelConfiguration channelConfig[]; + private final IntentFilter statusIntentFilter; + private final AntInterface antInterface; + + private boolean serviceConnected = false; + private boolean hasClaimedInterface = false; + private ChannelStates hrmState = ChannelStates.CLOSED; + private ChannelStates sdmState = ChannelStates.CLOSED; + private short hrmDeviceNumber = WILDCARD; + private short sdmDeviceNumber = WILDCARD; + + private SensorDataSet sensorDataSet = null; + private int lastHeartRate = -1; + private int lastCadence = -1; + private long lastSensorDataSetTime = 0; + + private boolean requestedReset = false; + + /** + * Constructor. + * + * @param context the context + */ + public AntSensorManager(Context context) { + this.context = context; + + channelConfig = new ChannelConfiguration[CHANNELS]; + channelConfig[HRM_CHANNEL] = new ChannelConfiguration(); + channelConfig[SDM_CHANNEL] = new ChannelConfiguration(); + + statusIntentFilter = new IntentFilter(); + statusIntentFilter.addAction(AntInterfaceIntent.ANT_ENABLED_ACTION); + statusIntentFilter.addAction(AntInterfaceIntent.ANT_ENABLING_ACTION); + statusIntentFilter.addAction(AntInterfaceIntent.ANT_DISABLED_ACTION); + statusIntentFilter.addAction(AntInterfaceIntent.ANT_DISABLING_ACTION); + statusIntentFilter.addAction(AntInterfaceIntent.ANT_RESET_ACTION); + statusIntentFilter.addAction(AntInterfaceIntent.ANT_INTERFACE_CLAIMED_ACTION); + statusIntentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); + + antInterface = new AntInterface(); + } + + @Override + protected void setUpChannel() { + if (AntInterface.hasAntSupport(context)) { + context.registerReceiver(statusReceiver, statusIntentFilter); + if (!antInterface.initService(context, serviceListener)) { + AntInterface.goToMarket(context); + } else { + setSensorState(Sensor.SensorState.CONNECTING); + serviceConnected = antInterface.isServiceConnected(); + if (serviceConnected) { + try { + hasClaimedInterface = antInterface.hasClaimedInterface(); + if (hasClaimedInterface) { + enableDataMessage(true); + } + } catch (AntInterfaceException e) { + handleAntError(); + } } } } - }; - - /** - * ANT uses this listener to tell us when it has bound to the ANT Radio - * Service. We can't start sending ANT commands until we've been notified - * (via this listener) that the Radio Service has connected. - */ - private AntInterface.ServiceListener antServiceListener = new AntInterface.ServiceListener() { - @Override - public void onServiceConnected() { - serviceConnected(); - } - - @Override - public void onServiceDisconnected() { - Log.d(TAG, "ANT interface reports disconnection"); - } - }; - - public AntSensorManager(Context context) { - this.context = context; - - // We register for ANT intents early because we want to have a record of - // the status intents in the log as we start up. - registerForAntIntents(); - } @Override protected void tearDownChannel() { - Log.i(TAG, "destroying AntSensorManager"); - - cleanAntInterface(); - unregisterForAntIntents(); + try { + context.unregisterReceiver(statusReceiver); + } catch (IllegalArgumentException e) { + // Can safely ignore + } + enableDataMessage(false); + if (serviceConnected) { + try { + if (hasClaimedInterface) { + antInterface.releaseInterface(); + } + antInterface.stopRequestForceClaimInterface(); + } catch (AntServiceNotConnectedException e) { + // Can safely ignore + } catch (AntInterfaceException e) { + Log.w(TAG, "Exception in tearDonwChannel.", e); + } + antInterface.releaseService(); + } } @Override public SensorDataSet getSensorDataSet() { - return sensorData; + return sensorDataSet; + } + + /** + * Tries to claim the ant interface. + */ + public void tryClaimAnt() { + try { + antInterface.requestForceClaimInterface(context.getString(R.string.my_tracks_app_name)); + } catch (AntInterfaceException e) { + handleAntError(); + } + } + + private AntInterface.ServiceListener serviceListener = new AntInterface.ServiceListener() { + @Override + public void onServiceConnected() { + serviceConnected = true; + try { + hasClaimedInterface = antInterface.hasClaimedInterface(); + if (hasClaimedInterface) { + enableDataMessage(true); + } else { + // Need to claim the ant interface if it is available + hasClaimedInterface = antInterface.claimInterface(); + } + } catch (AntInterfaceException e) { + handleAntError(); + } + } + + @Override + public void onServiceDisconnected() { + serviceConnected = false; + if (hasClaimedInterface) { + enableDataMessage(false); + } + } + }; + + /** + * Configures ant radio. + */ + private void configureAntRadio() { + try { + if (serviceConnected && hasClaimedInterface && antInterface.isEnabled()) { + try { + antInterface.ANTConfigEventBuffering((short) 0xFFFF, SCREEN_ON_BUFFER_THRESHOLD, + (short) 0xFFFF, SCREEN_OFF_BUFFER_THRESHOLD); + } catch (AntInterfaceException e) { + Log.e(TAG, "Cannot configure event buffering.", e); + } + } else { + Log.i(TAG, "Cannot set event buffering now."); + } + } catch (AntInterfaceException e) { + Log.e(TAG, "Unable to check enabled state.", e); + } + } + + /** + * Handles ant error. + */ + private void handleAntError() { + clearAllChannels(); + } + + /** + * Opens a channel. + * + * @param channel the channel + */ + private void openChannel(byte channel) { + channelConfig[channel].deviceNumber = 0; + channelConfig[channel].deviceType = 0; + channelConfig[channel].TransmissionType = ANT_TRANSMISSION_TYPE; + channelConfig[channel].period = 0; + channelConfig[channel].freq = ANT_FREQUENCY; + channelConfig[channel].proxSearch = DEFAULT_PROXIMITY_SEARCH_BIN; + switch (channel) { + case HRM_CHANNEL: + hrmDeviceNumber = (short) PreferencesUtils.getInt( + context, R.string.ant_heart_rate_monitor_id_key, WILDCARD); + channelConfig[channel].deviceNumber = hrmDeviceNumber; + channelConfig[channel].deviceType = HRM_DEVICE_TYPE; + channelConfig[channel].period = HRM_PERIOD; + hrmState = ChannelStates.PENDING_OPEN; + break; + case SDM_CHANNEL: + sdmDeviceNumber = (short) PreferencesUtils.getInt( + context, R.string.ant_speed_distance_monitor_id_key, WILDCARD); + channelConfig[channel].deviceNumber = sdmDeviceNumber; + channelConfig[channel].deviceType = SDM_DEVICE_TYPE; + channelConfig[channel].period = SDM_PERIOD; + sdmState = ChannelStates.PENDING_OPEN; + break; + default: + break; + } + setupAntChannel(ANT_NETWORK, channel); + } + + /** + * Closes a channel. + * + * @param channel the channel + */ + private void closeChannel(byte channel) { + channelConfig[channel].isInitializing = false; + channelConfig[channel].isDeinitializing = true; + switch (channel) { + case HRM_CHANNEL: + hrmState = ChannelStates.CLOSED; + break; + case SDM_CHANNEL: + sdmState = ChannelStates.CLOSED; + break; + default: + break; + } + setSensorState(SensorState.DISCONNECTED); + try { + antInterface.ANTCloseChannel(channel); + // Note, unassign channel after getting channel closed event + } catch (AntInterfaceException e) { + Log.w(TAG, "Unable to close channel: " + channel, e); + handleAntError(); + } + } + + /** + * Clears all channels. + */ + private void clearAllChannels() { + hrmState = ChannelStates.CLOSED; + sdmState = ChannelStates.CLOSED; + setSensorState(SensorState.DISCONNECTED); + } + + /** + * Requests reset. + */ + public void requestReset() { + try { + requestedReset = true; + antInterface.ANTResetSystem(); + configureAntRadio(); + } catch (AntInterfaceException e) { + Log.e(TAG, "Unable to reset ant.", e); + requestedReset = false; + } } @Override public boolean isEnabled() { - return true; - } - - public AntInterface getAntReceiver() { - return antReceiver; - } - - /** - * This is the interface used by the {@link SensorManager} to tell this - * class when to start. It handles initialization of the ANT framework, - * eventually resulting in sensor-specific initialization via - * {@link #setupAntSensorChannels}. - */ - @Override - protected void setUpChannel() { - setup(); - } - - private synchronized void setup() { - // We handle this unpleasantly because the UI should've checked for ANT - // support before it even instantiated this class. - if (!AntInterface.hasAntSupport(context)) { - throw new IllegalStateException("device does not have ANT support"); + if (antInterface == null || !antInterface.isServiceConnected()) { + return false; } - - cleanAntInterface(); - - antReceiver = AntInterface.getInstance(context, antServiceListener); - - if (antReceiver == null) { - Log.e(TAG, "Failed to get ANT Receiver"); - return; - } - - setSensorState(Sensor.SensorState.CONNECTING); - } - - /** - * Cleans up the ANT+ receiver interface, by releasing the interface - * and destroying it. - */ - private void cleanAntInterface() { - Log.i(TAG, "Destroying AntSensorManager"); - - if (antReceiver == null) { - Log.e(TAG, "no ANT receiver"); - return; - } - try { - antReceiver.releaseInterface(); - antReceiver.destroy(); - antReceiver = null; - } catch (AntServiceNotConnectedException e) { - Log.i(TAG, "ANT service not connected", e); + return antInterface.isEnabled(); } catch (AntInterfaceException e) { - Log.e(TAG, "failed to release ANT interface", e); - } catch (RuntimeException e) { - Log.e(TAG, "run-time exception when cleaning the ANT interface", e); - } - } - - /** - * This method is invoked via the ServiceListener when we're connected to - * the ANT service. If we're just starting up, this is our first opportunity - * to initiate any ANT commands. - */ - private synchronized void serviceConnected() { - Log.d(TAG, "ANT service connected"); - - if (antReceiver == null) { - Log.e(TAG, "no ANT receiver"); - return; - } - - try { - if (!antReceiver.claimInterface()) { - Log.e(TAG, "failed to claim ANT interface"); - return; - } - - if (!antReceiver.isEnabled()) { - // Make sure not to call AntInterface.enable() again, if it has been - // already called before - Log.i(TAG, "Powering on Radio"); - antReceiver.enable(); - } else { - Log.i(TAG, "Radio already enabled"); - } - } catch (AntInterfaceException e) { - Log.e(TAG, "failed to enable ANT", e); - } - - try { - // We expect this call to throw an exception due to a bug in the ANT - // Radio Service. It won't actually fail, though, as we'll get the - // startup message (see {@link AntStartupMessage}) one normally expects - // after a reset. Channel initialization can proceed once we receive - // that message. - antReceiver.ANTResetSystem(); - } catch (AntInterfaceException e) { - Log.e(TAG, "failed to reset ANT (expected exception)", e); - } - } - - /** - * Process a raw ANT message. - * @param antMessage the ANT message, including the size and message ID bytes - * @deprecated Use {@link #handleMessage(byte, byte[])} instead. - */ - protected void handleMessage(byte[] antMessage) { - int len = antMessage[0]; - if (len != antMessage.length - 2 || antMessage.length <= 2) { - Log.e(TAG, "Invalid message: " + messageToString(antMessage)); - return; - } - - byte messageId = antMessage[1]; - // Arrays#copyOfRange doesn't exist?? - byte[] messageData = new byte[antMessage.length - 2]; - System.arraycopy(antMessage, 2, messageData, 0, antMessage.length - 2); - handleMessage(messageId, messageData); - } - - /** - * Process a raw ANT message. - * @param messageId the message ID. See the ANT Message Protocol and Usage - * guide, section 9.3. - * @param messageData the ANT message, without the size and message ID bytes. - * @return true if this method has taken responsibility for the passed - * message; false otherwise. - */ - protected boolean handleMessage(byte messageId, byte[] messageData) { - if (messageId == AntMesg.MESG_STARTUP_MESG_ID) { - Log.d(TAG, String.format(Locale.US, - "Received startup message (reason %02x); initializing channel", - new AntStartupMessage(messageData).getMessage())); - setupAntSensorChannels(); - return true; - } - - return false; - } - - /** - * Subclasses define this method to perform sensor-specific initialization. - * When this method is called, the ANT framework has been enabled, and is - * ready for use. - */ - protected abstract void setupAntSensorChannels(); - - /** - * Used by subclasses to set up an ANT channel for a single sensor. A given - * subclass may invoke this method multiple times if the subclass is - * responsible for more than one sensor. - * - * @return true on success - */ - protected boolean setupAntSensorChannel(byte networkNumber, byte channelNumber, - short deviceNumber, byte deviceType, byte txType, short channelPeriod, - byte radioFreq, byte proxSearch) { - - if (antReceiver == null) { - Log.e(TAG, "no ANT receiver"); - return false; - } - - try { - // Assign as slave channel on selected network (0 = public, 1 = ANT+, 2 = - // ANTFS) - antReceiver.ANTAssignChannel(channelNumber, AntDefine.PARAMETER_RX_NOT_TX, networkNumber); - - antReceiver.ANTSetChannelId(channelNumber, deviceNumber, deviceType, txType); - antReceiver.ANTSetChannelPeriod(channelNumber, channelPeriod); - antReceiver.ANTSetChannelRFFreq(channelNumber, radioFreq); - - // Disable high priority search - antReceiver.ANTSetChannelSearchTimeout(channelNumber, (byte) 0); - - // Set search timeout to 10 seconds (low priority search)) - antReceiver.ANTSetLowPriorityChannelSearchTimeout(channelNumber, (byte) 4); - - if (deviceNumber == WILDCARD) { - // Configure proximity search, if using wild card search - antReceiver.ANTSetProximitySearch(channelNumber, proxSearch); - } - - antReceiver.ANTOpenChannel(channelNumber); - return true; - - } catch (AntInterfaceException e) { - Log.e(TAG, "failed to setup ANT channel", e); + Log.w(TAG, "Unable to check enabled.", e); return false; } } - private void registerForAntIntents() { - Log.i(TAG, "Registering for ant intents."); - // Register for ANT intent broadcasts. - IntentFilter statusIntentFilter = new IntentFilter(); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_ENABLED_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_DISABLED_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_INTERFACE_CLAIMED_ACTION); - statusIntentFilter.addAction(AntInterfaceIntent.ANT_RESET_ACTION); - context.registerReceiver(statusReceiver, statusIntentFilter); + private final BroadcastReceiver statusReceiver = new BroadcastReceiver() { + public void onReceive(Context c, Intent intent) { + String ANTAction = intent.getAction(); + if (ANTAction.equals(AntInterfaceIntent.ANT_DISABLED_ACTION)) { + clearAllChannels(); + } else if (ANTAction.equals(AntInterfaceIntent.ANT_RESET_ACTION)) { + if (!requestedReset) { + // Someone else triggered an ant reset + clearAllChannels(); + } else { + requestedReset = false; + configureAntRadio(); + } + } else if (ANTAction.equals(AntInterfaceIntent.ANT_INTERFACE_CLAIMED_ACTION)) { + boolean wasClaimed = hasClaimedInterface; - IntentFilter dataIntentFilter = new IntentFilter(); - dataIntentFilter.addAction(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION); - context.registerReceiver(dataReceiver, dataIntentFilter); + // Could also read ANT_INTERFACE_CLAIMED_PID from intent and see if it + // matches the current process PID. + try { + hasClaimedInterface = antInterface.hasClaimedInterface(); + if (hasClaimedInterface) { + enableDataMessage(true); + } else { + if (wasClaimed) { + // Claimed by another application + enableDataMessage(false); + } + } + } catch (AntInterfaceException e) { + handleAntError(); + } + } else if (ANTAction.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) { + if (isAirPlaneMode()) { + clearAllChannels(); + } + } + } + }; + + private final BroadcastReceiver dataReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context c, Intent intent) { + if (intent.getAction().equals(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION)) { + byte[] ANTRxMessage = intent.getByteArrayExtra(AntInterfaceIntent.ANT_MESSAGE); + switch (ANTRxMessage[AntMesg.MESG_ID_OFFSET]) { + case AntMesg.MESG_BROADCAST_DATA_ID: + case AntMesg.MESG_ACKNOWLEDGED_DATA_ID: + // Switch on channel number + switch (ANTRxMessage[AntMesg.MESG_DATA_OFFSET]) { + case HRM_CHANNEL: + decodeHrmMessage(ANTRxMessage); + break; + case SDM_CHANNEL: + decodeSdmMessage(ANTRxMessage); + break; + default: + break; + } + break; + case AntMesg.MESG_RESPONSE_EVENT_ID: + handleResponseEventMessage(ANTRxMessage); + break; + case AntMesg.MESG_CHANNEL_ID_ID: + short deviceNum = (short) ((ANTRxMessage[AntMesg.MESG_DATA_OFFSET + 1] & 0xFF + | ((ANTRxMessage[AntMesg.MESG_DATA_OFFSET + 2] & 0xFF) << 8)) & 0xFFFF); + // Switch on channel number + switch (ANTRxMessage[AntMesg.MESG_DATA_OFFSET]) { + case HRM_CHANNEL: + hrmDeviceNumber = deviceNum; + PreferencesUtils.setInt( + context, R.string.ant_heart_rate_monitor_id_key, hrmDeviceNumber); + Toast.makeText(context, + context.getString(R.string.settings_sensor_connected, deviceNum), + Toast.LENGTH_SHORT).show(); + setSensorState(SensorState.CONNECTED); + break; + case SDM_CHANNEL: + sdmDeviceNumber = deviceNum; + PreferencesUtils.setInt( + context, R.string.ant_speed_distance_monitor_id_key, sdmDeviceNumber); + Toast.makeText(context, + context.getString(R.string.settings_sensor_connected, deviceNum), + Toast.LENGTH_SHORT).show(); + setSensorState(SensorState.CONNECTED); + break; + default: + break; + } + break; + default: + break; + } + } + } + + /** + * Handles response event message. + * + * @param message the message + */ + private void handleResponseEventMessage(byte[] message) { + // For a list of possible message codes see ANT Message Protocol and Usage + // section 9.5.6.1 available from thisisant.com + byte channelNumber = message[AntMesg.MESG_DATA_OFFSET]; + if ((message[AntMesg.MESG_DATA_OFFSET + 1] == AntMesg.MESG_EVENT_ID) + && (message[AntMesg.MESG_DATA_OFFSET + 2] == AntDefine.EVENT_RX_SEARCH_TIMEOUT)) { + // A channel timed out searching, unassign it + channelConfig[channelNumber].isInitializing = false; + channelConfig[channelNumber].isDeinitializing = false; + switch (channelNumber) { + case HRM_CHANNEL: + try { + hrmState = ChannelStates.OFFLINE; + antInterface.ANTUnassignChannel(HRM_CHANNEL); + setSensorState(SensorState.DISCONNECTED); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + case SDM_CHANNEL: + try { + sdmState = ChannelStates.OFFLINE; + antInterface.ANTUnassignChannel(SDM_CHANNEL); + setSensorState(SensorState.DISCONNECTED); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + default: + break; + } + } + + if (channelConfig[channelNumber].isInitializing) { + if (message[AntMesg.MESG_DATA_OFFSET + 2] != 0) { + // Error response + Log.e(TAG, String.format("Error code(%#02x) on message ID(%#02x) on channel %d", + message[AntMesg.MESG_DATA_OFFSET + 2], + message[AntMesg.MESG_DATA_OFFSET + 1], channelNumber)); + } else { + // Switch on message id + switch (message[AntMesg.MESG_DATA_OFFSET + 1]) { + case AntMesg.MESG_ASSIGN_CHANNEL_ID: + try { + antInterface.ANTSetChannelId(channelNumber, + channelConfig[channelNumber].deviceNumber, + channelConfig[channelNumber].deviceType, + channelConfig[channelNumber].TransmissionType); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + case AntMesg.MESG_CHANNEL_ID_ID: + try { + antInterface.ANTSetChannelPeriod( + channelNumber, channelConfig[channelNumber].period); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + case AntMesg.MESG_CHANNEL_MESG_PERIOD_ID: + try { + antInterface.ANTSetChannelRFFreq(channelNumber, channelConfig[channelNumber].freq); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + case AntMesg.MESG_CHANNEL_RADIO_FREQ_ID: + try { + // Disable high priority search + antInterface.ANTSetChannelSearchTimeout(channelNumber, (byte) 0); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + case AntMesg.MESG_CHANNEL_SEARCH_TIMEOUT_ID: + try { + // Set search timeout to 30 seconds (low priority search) + antInterface.ANTSetLowPriorityChannelSearchTimeout(channelNumber, (byte) 12); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + case AntMesg.MESG_SET_LP_SEARCH_TIMEOUT_ID: + if (channelConfig[channelNumber].deviceNumber == WILDCARD) { + try { + // Configure proximity search, if using wild card search + antInterface.ANTSetProximitySearch( + channelNumber, channelConfig[channelNumber].proxSearch); + } catch (AntInterfaceException e) { + handleAntError(); + } + } else { + try { + antInterface.ANTOpenChannel(channelNumber); + } catch (AntInterfaceException e) { + handleAntError(); + } + } + break; + case AntMesg.MESG_PROX_SEARCH_CONFIG_ID: + try { + antInterface.ANTOpenChannel(channelNumber); + } catch (AntInterfaceException e) { + handleAntError(); + } + break; + case AntMesg.MESG_OPEN_CHANNEL_ID: + channelConfig[channelNumber].isInitializing = false; + switch (channelNumber) { + case HRM_CHANNEL: + hrmState = ChannelStates.SEARCHING; + break; + case SDM_CHANNEL: + sdmState = ChannelStates.SEARCHING; + break; + default: + break; + } + break; + default: + break; + } + } + } else if (channelConfig[channelNumber].isDeinitializing) { + if ((message[AntMesg.MESG_DATA_OFFSET + 1] == AntMesg.MESG_EVENT_ID) + && (message[AntMesg.MESG_DATA_OFFSET + 2] == AntDefine.EVENT_CHANNEL_CLOSED)) { + try { + antInterface.ANTUnassignChannel(channelNumber); + } catch (AntInterfaceException e) { + handleAntError(); + } + } else if ((message[AntMesg.MESG_DATA_OFFSET + 1] == AntMesg.MESG_UNASSIGN_CHANNEL_ID) + && (message[AntMesg.MESG_DATA_OFFSET + 2] == AntDefine.RESPONSE_NO_ERROR)) { + channelConfig[channelNumber].isDeinitializing = false; + } + } + } + + /** + * Decodes HRM message. + * + * @param message the message + */ + private void decodeHrmMessage(byte[] message) { + if (hrmState != ChannelStates.CLOSED) { + hrmState = ChannelStates.TRACKING_DATA; + } + + if (hrmDeviceNumber == WILDCARD) { + try { + antInterface.ANTRequestMessage(HRM_CHANNEL, AntMesg.MESG_CHANNEL_ID_ID); + } catch (AntInterfaceException e) { + handleAntError(); + } + } + + lastHeartRate = message[10] & 0xFF; + setSenorDataSet(); + } + + /** + * Decodes SDM message. + * + * @param message the message + */ + private void decodeSdmMessage(byte[] message) { + if (sdmState != ChannelStates.CLOSED) { + sdmState = ChannelStates.TRACKING_DATA; + } + + if (sdmDeviceNumber == WILDCARD) { + try { + antInterface.ANTRequestMessage(SDM_CHANNEL, AntMesg.MESG_CHANNEL_ID_ID); + } catch (AntInterfaceException e) { + handleAntError(); + } + } + + // Check page 2 data + if (message[3] == 0x02) { + lastCadence = (int) ((message[6] & 0xFF) + (((message[7] >>> 4) & 0x0F) / 16.0f)); + setSenorDataSet(); + } + } + }; + + /** + * Sets sensor data set. + */ + private void setSenorDataSet() { + long now = System.currentTimeMillis(); + // Data comes in at ~4Hz rate from the sensors, so after >300 msec fresh + // data is here from all the connected sensors + if (now < lastSensorDataSetTime + 300) { return; } + lastSensorDataSetTime = now; + + SensorDataSet.Builder builder = Sensor.SensorDataSet.newBuilder(); + if (lastHeartRate != -1) { + builder.setHeartRate(Sensor.SensorData.newBuilder() + .setValue(lastHeartRate).setState(Sensor.SensorState.SENDING)); + } + if (lastCadence != -1) { + builder.setCadence(Sensor.SensorData.newBuilder() + .setValue(lastCadence).setState(Sensor.SensorState.SENDING)); + } + sensorDataSet = builder.setCreationTime(now).build(); + setSensorState(SensorState.SENDING); } - - private void unregisterForAntIntents() - { - Log.i(TAG, "Unregistering ANT Intents."); - + + /** + * Sets up ant channel. + * + * @param networkNumber the network number + * @param channel the channel + */ + private void setupAntChannel(byte networkNumber, byte channel) { try { - context.unregisterReceiver(statusReceiver); - } catch (IllegalArgumentException e) { - Log.w(TAG, "Failed to unregister ANT status receiver", e); + channelConfig[channel].isInitializing = true; + channelConfig[channel].isDeinitializing = false; + + // Assign as slave channel on selected network + antInterface.ANTAssignChannel(channel, AntDefine.PARAMETER_RX_NOT_TX, networkNumber); + + // The rest of the channel configuration will occur after the response is + // received in handleResponseEventMessage + } catch (AntInterfaceException aie) { + handleAntError(); + } + } + + /** + * Enables data message. + * + * @param enabled true to enable + */ + private void enableDataMessage(boolean enabled) { + if (enabled) { + context.registerReceiver( + dataReceiver, new IntentFilter(AntInterfaceIntent.ANT_RX_MESSAGE_ACTION)); + openChannel(HRM_CHANNEL); + openChannel(SDM_CHANNEL); + } else { + try { + context.unregisterReceiver(dataReceiver); + closeChannel(HRM_CHANNEL); + closeChannel(SDM_CHANNEL); + setSensorState(SensorState.DISCONNECTED); + } catch (IllegalArgumentException e) { + // Can safely ignore + } + } + } + + /** + * Returns true if in airplane mode. + */ + private boolean isAirPlaneMode() { + if (!Settings.System.getString( + context.getContentResolver(), Settings.System.AIRPLANE_MODE_RADIOS) + .contains(RADIO_ANT)) { + return false; + } + if (Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) + == 0) { + return false; } try { - context.unregisterReceiver(dataReceiver); - } catch (IllegalArgumentException e) { - Log.w(TAG, "Failed to unregister ANT data receiver", e); + Field field = Settings.System.class.getField("AIRPLANE_MODE_TOGGLEABLE_RADIOS"); + return !Settings.System.getString(context.getContentResolver(), (String) field.get(null)) + .contains(RADIO_ANT); + } catch (Exception e) { + // This is expected if the list does not yet exist, so just return true + return true; } - } - - private String messageToString(byte[] message) { - StringBuilder out = new StringBuilder(); - for (byte b : message) { - out.append(String.format(Locale.US, "%s%02x", (out.length() == 0 ? "" : " "), b)); - } - return out.toString(); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSrmBridgeSensorManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSrmBridgeSensorManager.java deleted file mode 100644 index be6c172ec..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSrmBridgeSensorManager.java +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import static com.google.android.apps.mytracks.Constants.TAG; - -import com.dsi.ant.AntDefine; -import com.dsi.ant.AntMesg; -import com.dsi.ant.exception.AntInterfaceException; -import com.google.android.apps.mytracks.content.Sensor; -import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.maps.mytracks.BuildConfig; -import com.google.android.maps.mytracks.R; - -import android.content.Context; -import android.util.Log; - -/** - * A sensor manager to the PC7 SRM ANT+ bridge. - * - * @author Sandor Dornbush - * @author Umran Abdulla - */ -public class AntSrmBridgeSensorManager extends AntSensorManager { - - /* - * These constants are defined by the ANT+ spec. - */ - public static final byte CHANNEL_NUMBER = 0; - public static final byte NETWORK_NUMBER = 0; - public static final byte DEVICE_TYPE = 12; - public static final byte NETWORK_ID = 1; - public static final short CHANNEL_PERIOD = 8192; - public static final byte RF_FREQUENCY = 50; - - private static final int INDEX_MESSAGE_TYPE = 1; - private static final int INDEX_MESSAGE_ID = 2; - private static final int INDEX_MESSAGE_POWER = 3; - private static final int INDEX_MESSAGE_SPEED = 5; - private static final int INDEX_MESSAGE_CADENCE = 7; - private static final int INDEX_MESSAGE_BPM = 8; - - private static final int MSG_INITIAL = 5; - private static final int MSG_DATA = 6; - - private short deviceNumber; - - public AntSrmBridgeSensorManager(Context context) { - super(context); - - Log.i(TAG, "new ANT SRM Bridge Sensor Manager created"); - - deviceNumber = WILDCARD; - - // First read the the device id that we will be pairing with. - deviceNumber = (short) PreferencesUtils.getInt( - context, R.string.ant_srm_bridge_sensor_id_key, WILDCARD); - Log.i(TAG, "Will pair with device: " + deviceNumber); - } - - - @Override - protected boolean handleMessage(byte messageId, byte[] messageData) { - if (super.handleMessage(messageId, messageData)) { - return true; - } - - if (BuildConfig.DEBUG) { - Log.d(TAG, "Received ANT msg: " + AntUtils.antMessageToString(messageId) + "(" + messageId + ")"); - } - - int channel = messageData[0] & AntDefine.CHANNEL_NUMBER_MASK; - switch (channel) { - case CHANNEL_NUMBER: - decodeChannelMsg(messageId, messageData); - break; - default: - Log.d(TAG, "Unhandled message: " + channel); - } - - return true; - } - - /** - * Decode an ant device message. - * @param messageData The byte array received from the device. - */ - private void decodeChannelMsg(int messageId, byte[] messageData) { - switch (messageId) { - case AntMesg.MESG_BROADCAST_DATA_ID: - handleBroadcastData(messageData); - break; - case AntMesg.MESG_RESPONSE_EVENT_ID: - handleMessageResponse(messageData); - break; - case AntMesg.MESG_CHANNEL_ID_ID: - handleChannelId(messageData); - break; - default: - Log.e(TAG, "Unexpected message id: " + messageId); - } - } - - private void handleBroadcastData(byte[] antMessage) { - if (deviceNumber == WILDCARD) { - try { - getAntReceiver().ANTRequestMessage(CHANNEL_NUMBER, AntMesg.MESG_CHANNEL_ID_ID); - } catch (AntInterfaceException e) { - Log.e(TAG, "ANT error handling broadcast data", e); - } - Log.d(TAG, "Requesting channel id id."); - } - - setSensorState(Sensor.SensorState.CONNECTED); - - int messageType = antMessage[INDEX_MESSAGE_TYPE] & 0xFF; - Log.d(TAG, "Received message-type=" + messageType); - - switch (messageType) { - case MSG_INITIAL: - break; - case MSG_DATA: - parseDataMsg(antMessage); - break; - } - } - - private void parseDataMsg(byte[] msg) - { - int messageId = msg[INDEX_MESSAGE_ID] & 0xFF; - Log.d(TAG, "Received message-id=" + messageId); - - int powerVal = (((msg[INDEX_MESSAGE_POWER] & 0xFF) << 8) | - (msg[INDEX_MESSAGE_POWER+1] & 0xFF)); - @SuppressWarnings("unused") - int speedVal = (((msg[INDEX_MESSAGE_SPEED] & 0xFF) << 8) | - (msg[INDEX_MESSAGE_SPEED+1] & 0xFF)); - int cadenceVal = (msg[INDEX_MESSAGE_CADENCE] & 0xFF); - int bpmVal = (msg[INDEX_MESSAGE_BPM] & 0xFF); - long time = System.currentTimeMillis(); - - Sensor.SensorData.Builder power = - Sensor.SensorData.newBuilder() - .setValue(powerVal) - .setState(Sensor.SensorState.SENDING); - - /* - * Although speed is available from the SRM Bridge, MyTracks doesn't use the value, and - * computes speed from the GPS location data. - */ -// Sensor.SensorData.Builder speed = Sensor.SensorData.newBuilder().setValue(speedVal).setState( -// Sensor.SensorState.SENDING); - - Sensor.SensorData.Builder cadence = - Sensor.SensorData.newBuilder() - .setValue(cadenceVal) - .setState(Sensor.SensorState.SENDING); - - Sensor.SensorData.Builder bpm = - Sensor.SensorData.newBuilder() - .setValue(bpmVal) - .setState(Sensor.SensorState.SENDING); - - sensorData = - Sensor.SensorDataSet.newBuilder() - .setCreationTime(time) - .setPower(power) - .setCadence(cadence) - .setHeartRate(bpm) - .build(); - } - - void handleChannelId(byte[] rawMessage) { - AntChannelIdMessage message = new AntChannelIdMessage(rawMessage); - deviceNumber = message.getDeviceNumber(); - Log.d(TAG, "Found device id: " + deviceNumber); - PreferencesUtils.setInt(context, R.string.ant_srm_bridge_sensor_id_key, deviceNumber); - } - - private void handleMessageResponse(byte[] rawMessage) { - AntChannelResponseMessage message = - new AntChannelResponseMessage(rawMessage); - if (BuildConfig.DEBUG) { - Log.d(TAG, "Received ANT Response: " + AntUtils.antMessageToString(message.getMessageId()) + - "(" + message.getMessageId() + ")" + - ", Code: " + AntUtils.antEventToStr(message.getMessageCode()) + - "(" + message.getMessageCode() + ")"); - } - switch (message.getMessageId()) { - case AntMesg.MESG_EVENT_ID: - if (message.getMessageCode() == AntDefine.EVENT_RX_SEARCH_TIMEOUT) { - // Search timeout - Log.w(TAG, "Search timed out. Unassigning channel."); - try { - getAntReceiver().ANTUnassignChannel((byte) 0); - } catch (AntInterfaceException e) { - Log.e(TAG, "ANT error unassigning channel", e); - } - } - break; - - case AntMesg.MESG_UNASSIGN_CHANNEL_ID: - setSensorState(Sensor.SensorState.DISCONNECTED); - Log.i(TAG, "Disconnected from the sensor: " + getSensorState()); - break; - } - } - - @Override protected void setupAntSensorChannels() { - Log.i(TAG, "Setting up ANT sensor channels"); - setupAntSensorChannel( - NETWORK_NUMBER, - CHANNEL_NUMBER, - deviceNumber, - DEVICE_TYPE, - (byte) 0x01, - CHANNEL_PERIOD, - RF_FREQUENCY, - (byte) 0); - } - - public short getDeviceNumber() { - return deviceNumber; - } - - void setDeviceNumber(short deviceNumber) { - this.deviceNumber = deviceNumber; - } -} \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntStartupMessage.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntStartupMessage.java deleted file mode 100644 index 3e4dc1f68..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntStartupMessage.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -/** - * This class decodes and encapsulates an ANT Startup message. - * (ANT Message ID 0x6f, Protocol & Usage guide v4.2 section 9.5.3.1) - * - * @author Matthew Simmons - */ -public class AntStartupMessage extends AntMessage { - private byte message; - - public AntStartupMessage(byte[] messageData) { - message = messageData[0]; - } - - /** Returns the cause of the startup */ - public byte getMessage() { - return message; - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntUtils.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntUtils.java deleted file mode 100644 index b8019c8da..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntUtils.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import com.dsi.ant.AntDefine; -import com.dsi.ant.AntInterface; - -import android.content.Context; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.HashSet; -import java.util.Set; - -/** - * Utility methods for ANT functionality. - * - * Prefer use of this class to importing DSI ANT classes into code outside of - * the sensors package. - */ -public class AntUtils { - private AntUtils() {} - - /** Returns true if this device supports ANT sensors. */ - public static boolean hasAntSupport(Context context) { - return AntInterface.hasAntSupport(context); - } - - /** - * Finds the names of in the messages with the given value - */ - public static String antMessageToString(byte msg) { - return findConstByteInClass(AntDefine.class, msg, "MESG_.*_ID"); - } - - /** - * Finds the names of in the events with the given value - */ - public static String antEventToStr(byte event) { - return findConstByteInClass(AntDefine.class, event, ".*EVENT.*"); - } - - /** - * Finds a set of constant static byte field declarations in the class that have the given value - * and whose name match the given pattern - * @param cl class to search in - * @param value value of constant static byte field declarations to match - * @param regexPattern pattern to match against the name of the field - * @return a set of the names of fields, expressed as a string - */ - private static String findConstByteInClass(Class cl, byte value, String regexPattern) - { - Field[] fields = cl.getDeclaredFields(); - Set fieldSet = new HashSet(); - for (Field f : fields) { - try { - if (f.getType() == Byte.TYPE && - (f.getModifiers() & Modifier.STATIC) != 0 && - f.getName().matches(regexPattern) && - f.getByte(null) == value) { - fieldSet.add(f.getName()); - } - } catch (IllegalArgumentException e) { - // ignore - } catch (IllegalAccessException e) { - // ignore - } - } - return fieldSet.toString(); - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSensor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSensor.java deleted file mode 100644 index 8931629f7..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSensor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - - -/** - * Ant+ cadence sensor. - * - * @author Laszlo Molnar - */ - -public class CadenceSensor extends AntSensorBase { - /* - * These constants are defined by the ANT+ bike speed and cadence sensor spec. - */ - public static final byte CADENCE_DEVICE_TYPE = 122; - public static final short CADENCE_CHANNEL_PERIOD = 8102; - - SensorEventCounter dataProcessor = new SensorEventCounter(); - - CadenceSensor(short devNum) { - super(devNum, CADENCE_DEVICE_TYPE, "cadence sensor", CADENCE_CHANNEL_PERIOD); - } - - /** - * Decode an ANT+ cadence sensor message. - * @param antMessage The byte array received from the cadence sensor. - */ - @Override - public void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c) { - int sensorTime = ((int) antMessage[5] & 0xFF) + ((int) antMessage[6] & 0xFF) * 256; - int crankRevs = ((int) antMessage[7] & 0xFF) + ((int) antMessage[8] & 0xFF) * 256; - c.setCadence(dataProcessor.getEventsPerMinute(crankRevs, sensorTime)); - } -}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSpeedSensor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSpeedSensor.java deleted file mode 100644 index 91d83677f..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/CadenceSpeedSensor.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - - -/** - * Ant+ combined cadence and speed sensor. - * - * @author Laszlo Molnar - */ - -public class CadenceSpeedSensor extends AntSensorBase { - /* - * These constants are defined by the ANT+ bike speed and cadence sensor spec. - */ - public static final byte CADENCE_SPEED_DEVICE_TYPE = 121; - public static final short CADENCE_SPEED_CHANNEL_PERIOD = 8086; - - SensorEventCounter dataProcessor = new SensorEventCounter(); - - CadenceSpeedSensor(short devNum) { - super(devNum, CADENCE_SPEED_DEVICE_TYPE, "speed&cadence sensor", CADENCE_SPEED_CHANNEL_PERIOD); - } - - /** - * Decode an ANT+ cadence&speed sensor message. - * @param antMessage The byte array received from the sensor. - */ - @Override - public void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c) { - int sensorTime = ((int) antMessage[1] & 0xFF) + ((int) antMessage[2] & 0xFF) * 256; - int crankRevs = ((int) antMessage[3] & 0xFF) + ((int) antMessage[4] & 0xFF) * 256; - c.setCadence(dataProcessor.getEventsPerMinute(crankRevs, sensorTime)); - } -}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorDataCollector.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/ChannelConfiguration.java similarity index 66% rename from MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorDataCollector.java rename to MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/ChannelConfiguration.java index 3efbaa696..e08b3de24 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorDataCollector.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/ChannelConfiguration.java @@ -17,19 +17,19 @@ package com.google.android.apps.mytracks.services.sensors.ant; /** - * Interface for collecting data from the sensors. - * @author Laszlo Molnar + * Ant channel configuration. + * + * @author Jimmy Shih */ +public class ChannelConfiguration { -public interface AntSensorDataCollector { - - /** - * Sets the current cadence to the value specified. - */ - void setCadence(int value); - - /** - * Sets the current heart rate to the value specified. - */ - void setHeartRate(int value); + public short deviceNumber; + public byte deviceType; + public byte TransmissionType; + public short period; + public byte freq; + public byte proxSearch; + public boolean isInitializing = false; + public boolean isDeinitializing = false; } + diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/HeartRateSensor.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/HeartRateSensor.java deleted file mode 100644 index 406e56c2c..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/HeartRateSensor.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import static com.google.android.apps.mytracks.Constants.TAG; - -import android.util.Log; - -/** - * Ant+ heart reate monitor sensor. - * - * @author Laszlo Molnar - */ - -public class HeartRateSensor extends AntSensorBase { - /* - * These constants are defined by the ANT+ heart rate monitor spec. - */ - public static final byte HEART_RATE_DEVICE_TYPE = 120; - public static final short HEART_RATE_CHANNEL_PERIOD = 8070; - - HeartRateSensor(short devNum) { - super(devNum, HEART_RATE_DEVICE_TYPE, "heart rate monitor", HEART_RATE_CHANNEL_PERIOD); - } - - /** - * Decode an ANT+ heart rate monitor message. - * @param antMessage The byte array received from the heart rate monitor. - */ - @Override - public void handleBroadcastData(byte[] antMessage, AntSensorDataCollector c) { - int bpm = (int) antMessage[8] & 0xFF; - Log.d(TAG, "now:" + System.currentTimeMillis() + " heart rate=" + bpm); - c.setHeartRate(bpm); - } -}; diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/SensorEventCounter.java b/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/SensorEventCounter.java deleted file mode 100644 index 45c2aaf5a..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/sensors/ant/SensorEventCounter.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import static com.google.android.apps.mytracks.Constants.TAG; - -import android.util.Log; - -import java.util.LinkedList; - -/** - * Processes an ANT+ sensor data (counter) + timestamp pair, - * and returns the instantaneous value of the sensor - * - * @author Laszlo Molnar - */ -public class SensorEventCounter { - - /** - * HistoryElement stores a time stamped sensor counter - */ - private static class HistoryElement { - final long systemTime; - final int counter; - final int sensorTime; - - HistoryElement(long systemTime, int counter, int sensorTime) { - this.systemTime = systemTime; - this.counter = counter; - this.sensorTime = sensorTime; - } - } - - /** - * The latest counter value reported by the sensor - */ - private int counter; - - /** - * The calculated instantaneous sensor value to be displayed - */ - private int eventsPerMinute; - - private static final int ONE_SECOND_MILLIS = 1000; - private static final int HISTORY_LENGTH_MILLIS = ONE_SECOND_MILLIS * 5; - private static final int HISTORY_MAX_LENGTH = 100; - private static final int ONE_MINUTE_MILLIS = ONE_SECOND_MILLIS * 60; - private static final int SENSOR_TIME_RESOLUTION = 1024; // in a second - private static final int SENSOR_TIME_ONE_MINUTE = SENSOR_TIME_RESOLUTION * 60; - - /** - * History of previous sensor data - oldest first - * only the latest HISTORY_LENGTH_MILLIS milliseconds of data is stored - */ - private LinkedList history; - - SensorEventCounter() { - counter = -1; - eventsPerMinute = 0; - history = new LinkedList(); - } - - /** - * Calculates the instantaneous sensor value to be displayed - * - * @param newCounter sensor reported counter value - * @param sensorTime sensor reported timestamp - * @return the calculated value - */ - public int getEventsPerMinute(int newCounter, int sensorTime) { - return getEventsPerMinute(newCounter, sensorTime, System.currentTimeMillis()); - } - - // VisibleForTesting - protected int getEventsPerMinute(int newCounter, int sensorTime, long now) { - int counterChange = (newCounter - counter) & 0xFFFF; - - Log.d(TAG, "now=" + now + " counter=" + newCounter + " sensortime=" + sensorTime); - - if (counter < 0) { - // store the initial counter value reported by the sensor - // the timestamp is probably out of date, so the history is not updated - counter = newCounter; - return eventsPerMinute = 0; - } - counter = newCounter; - - if (counterChange != 0) { - // if new data has arrived from the sensor ... - if (removeOldHistory(now)) { - // ... and the history is not empty, then use the latest entry - HistoryElement h = history.getLast(); - int sensorTimeChange = (sensorTime - h.sensorTime) & 0xFFFF; - counterChange = (counter - h.counter) & 0xFFFF; - eventsPerMinute = counterChange * SENSOR_TIME_ONE_MINUTE / sensorTimeChange; - } - // the previous removeOldHistory() call makes the length of the history capped - history.addLast(new HistoryElement(now, counter, sensorTime)); - } else if (!history.isEmpty()) { - // the sensor has resent an old (counter,timestamp) pair, - // but the history is not empty - - HistoryElement h = history.getLast(); - if (ONE_MINUTE_MILLIS < (now - h.systemTime) * eventsPerMinute) { - // Too much time has passed since the last counter change. - // This means that a smaller value than eventsPerMinute must be - // returned. This value is extrapolated from the history of - // HISTORY_LENGTH_MILLIS data. - // Note, that eventsPerMinute is NOT updated unless the history - // is empty or contains outdated entries. In that case it is zeroed. - return getValueFromHistory(now); - } // else the current eventsPerMinute is still valid, nothing to do here - } else { - // no new data from the sensor & the history is empty -> return 0 - eventsPerMinute = 0; - } - - Log.d(TAG, "getEventsPerMinute returns:" + eventsPerMinute); - return eventsPerMinute; - } - - /** - * Calculates the instantaneous sensor value to be displayed - * using the history when the sensor only resends the old data - */ - private int getValueFromHistory(long now) { - if (!removeOldHistory(now)) { - // there is nothing in the history, return 0 - return eventsPerMinute = 0; - } - HistoryElement f = history.getFirst(); - HistoryElement l = history.getLast(); - int sensorTimeChange = (l.sensorTime - f.sensorTime) & 0xFFFF; - int counterChange = (counter - f.counter) & 0xFFFF; - - // difference between now and systemTime of the oldest history entry - // for better precision sensor timestamps are considered between - // the first and the last history entry (could be overkill) - int systemTimeChange = (int) (now - l.systemTime - + (sensorTimeChange * ONE_SECOND_MILLIS) / SENSOR_TIME_RESOLUTION); - - // eventsPerMinute is not overwritten by this calculated value - // because it is still needed when a new sensor event arrives - int v = (counterChange * ONE_MINUTE_MILLIS) / systemTimeChange; - Log.d(TAG, "getEventsPerMinute returns (2):" + v); - - // do not return larger number than eventsPerMinute, because the reason - // this function got called is that more time has passed after the last - // sensor counter value change than the current eventsPerMinute - // would be valid - return v < eventsPerMinute ? v : eventsPerMinute; - } - - /** - * Removes old data from the history. - * - * @param now the current system time - * @return true if the remaining history is not empty - */ - private boolean removeOldHistory(long now) { - HistoryElement h; - while ((h = history.peek()) != null) { - // if the first element of the list is in our desired time range then return - if (now - h.systemTime <= HISTORY_LENGTH_MILLIS && history.size() < HISTORY_MAX_LENGTH) { - return true; - } - // otherwise remove the too old element, and look at the next (newer) one - history.removeFirst(); - } - return false; - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java b/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java index 303de6ea9..b29e47c04 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/settings/SensorSettingsActivity.java @@ -16,8 +16,10 @@ package com.google.android.apps.mytracks.settings; -import com.google.android.apps.mytracks.services.sensors.ant.AntUtils; +import com.dsi.ant.AntInterface; +import com.google.android.apps.mytracks.services.sensors.ant.AntSensorManager; import com.google.android.apps.mytracks.util.BluetoothDeviceUtils; +import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.maps.mytracks.R; import android.bluetooth.BluetoothAdapter; @@ -47,13 +49,14 @@ public class SensorSettingsActivity extends AbstractSettingsActivity { super.onCreate(bundle); addPreferencesFromResource(R.xml.sensor_settings); + boolean hasAntSupport = AntInterface.hasAntSupport(this); ListPreference sensorTypeListPreference = (ListPreference) findPreference( getString(R.string.sensor_type_key)); List sensorTypeEntries = Arrays.asList(getResources().getStringArray( - AntUtils.hasAntSupport(this) ? R.array.sensor_type_all_options + hasAntSupport ? R.array.sensor_type_all_options : R.array.sensor_type_bluetooth_options)); List sensorTypeEntryValues = Arrays.asList(getResources().getStringArray( - AntUtils.hasAntSupport(this) ? R.array.sensor_type_all_values + hasAntSupport ? R.array.sensor_type_all_values : R.array.sensor_type_bluetooth_values)); sensorTypeListPreference.setEntries(sensorTypeEntries.toArray( new CharSequence[sensorTypeEntries.size()])); @@ -78,7 +81,7 @@ public class SensorSettingsActivity extends AbstractSettingsActivity { } }); - if (!AntUtils.hasAntSupport(this)) { + if (!hasAntSupport) { PreferenceScreen rootPreferenceScreen = (PreferenceScreen) findPreference( getString(R.string.settings_sensor_root_key)); rootPreferenceScreen.removePreference( @@ -97,17 +100,39 @@ public class SensorSettingsActivity extends AbstractSettingsActivity { || getString(R.string.sensor_type_value_zephyr).equals(sensorType); findPreference(getString(R.string.settings_sensor_bluetooth_key)).setEnabled(isBluetooth); - Preference antHeartRateSensorId = findPreference( - getString(R.string.ant_heart_rate_sensor_id_key)); - if (antHeartRateSensorId != null) { - antHeartRateSensorId.setEnabled(getString(R.string.sensor_type_value_ant).equals(sensorType)); - } - - Preference antSrmBridgetSensorId = findPreference( - getString(R.string.ant_srm_bridge_sensor_id_key)); - if (antSrmBridgetSensorId != null) { - antSrmBridgetSensorId.setEnabled( - getString(R.string.sensor_type_value_srm_ant_bridge).equals(sensorType)); + boolean isAnt = getString(R.string.sensor_type_value_ant).equals(sensorType); + updateAntSensor(R.string.settings_sensor_ant_reset_heart_rate_monitor_key, + R.string.ant_heart_rate_monitor_id_key, isAnt); + updateAntSensor(R.string.settings_sensor_ant_reset_speed_distance_monitor_key, + R.string.ant_speed_distance_monitor_id_key, isAnt); + } + + /** + * Updates an ant sensor. + * + * @param preferenceKey the preference key + * @param valueKey the value key + * @param enabled true if enabled + */ + @SuppressWarnings("deprecation") + private void updateAntSensor(int preferenceKey, final int valueKey, boolean enabled) { + Preference preference = findPreference(getString(preferenceKey)); + if (preference != null) { + preference.setEnabled(enabled); + int deviceId = PreferencesUtils.getInt(this, valueKey, AntSensorManager.WILDCARD); + if (deviceId == AntSensorManager.WILDCARD) { + preference.setSummary(R.string.settings_sensor_not_connected); + } else { + preference.setSummary(getString(R.string.settings_sensor_ant_paired, deviceId)); + } + preference.setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference pref) { + PreferencesUtils.setInt(SensorSettingsActivity.this, valueKey, AntSensorManager.WILDCARD); + pref.setSummary(R.string.settings_sensor_not_connected); + return true; + } + }); } } diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/AntPreferenceTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/AntPreferenceTest.java deleted file mode 100644 index b83f4ef66..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/AntPreferenceTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks; - -import com.google.android.maps.mytracks.R; - -import android.test.AndroidTestCase; - -/** - * Tests for the AntPreference. - * - * @author Youtao Liu - */ -public class AntPreferenceTest extends AndroidTestCase { - - public void testNotPaired() { - - AntPreference antPreference = new AntPreference(getContext()) { - @Override - protected int getPersistedInt(int defaultReturnValue) { - return 0; - } - }; - assertEquals(getContext().getString(R.string.settings_sensor_ant_not_paired), - antPreference.getSummary()); - } - - public void testPaired() { - int persistInt = 1; - AntPreference antPreference = new AntPreference(getContext()) { - @Override - protected int getPersistedInt(int defaultReturnValue) { - return 1; - } - }; - assertEquals( - getContext().getString(R.string.settings_sensor_ant_paired, persistInt), - antPreference.getSummary()); - } -} \ No newline at end of file diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelIdMessageTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelIdMessageTest.java deleted file mode 100644 index 82d37fde9..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelIdMessageTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import android.test.AndroidTestCase; - -public class AntChannelIdMessageTest extends AndroidTestCase { - public void testParse() { - byte[] rawMessage = { - 0, // channel number - 0x34, 0x12, // device number - (byte) 0xaa, // device type id - (byte) 0xbb, // transmission type - }; - - AntChannelIdMessage message = new AntChannelIdMessage(rawMessage); - assertEquals(0, message.getChannelNumber()); - assertEquals(0x1234, message.getDeviceNumber()); - assertEquals((byte) 0xaa, message.getDeviceTypeId()); - assertEquals((byte) 0xbb, message.getTransmissionType()); - } -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelResponseMessageTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelResponseMessageTest.java deleted file mode 100644 index 9fdcfde24..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntChannelResponseMessageTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import com.dsi.ant.AntDefine; -import com.dsi.ant.AntMesg; - -import android.test.AndroidTestCase; - -public class AntChannelResponseMessageTest extends AndroidTestCase { - public void testParse() { - byte[] rawMessage = { - 0, - AntMesg.MESG_EVENT_ID, - AntDefine.EVENT_RX_SEARCH_TIMEOUT - }; - AntChannelResponseMessage message = new AntChannelResponseMessage(rawMessage); - - assertEquals(0, message.getChannelNumber()); - assertEquals(AntMesg.MESG_EVENT_ID, message.getMessageId()); - assertEquals(AntDefine.EVENT_RX_SEARCH_TIMEOUT, message.getMessageCode()); - } -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManagerTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManagerTest.java deleted file mode 100644 index 01cdac80b..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntDirectSensorManagerTest.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2009 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import com.dsi.ant.AntMesg; -import com.google.android.apps.mytracks.Constants; -import com.google.android.apps.mytracks.content.Sensor; -import com.google.android.apps.mytracks.util.PreferencesUtils; -import com.google.android.maps.mytracks.R; - -import android.content.Context; -import android.content.SharedPreferences; -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -public class AntDirectSensorManagerTest extends AndroidTestCase { - - private AntSensorBase heartRateSensor; - private static final byte HEART_RATE_CHANNEL = 0; - - private class MockAntDirectSensorManager extends AntDirectSensorManager { - public MockAntDirectSensorManager(Context context) { - super(context); - } - @Override - protected boolean setupChannel(AntSensorBase sensor, byte channel) { - if (channel == HEART_RATE_CHANNEL) { - heartRateSensor = sensor; - return true; - } - return false; - } - } - private AntDirectSensorManager manager; - - public void setUp() { - SharedPreferences sharedPreferences = getContext().getSharedPreferences( - Constants.SETTINGS_NAME, Context.MODE_PRIVATE); - // Let's use default values. - sharedPreferences.edit().clear().apply(); - manager = new MockAntDirectSensorManager(getContext()); - } - - @SmallTest - public void testBroadcastData() { - manager.setupAntSensorChannels(); - assertNotNull(heartRateSensor); - - heartRateSensor.setDeviceNumber((short) 42); - byte[] buff = new byte[9]; - buff[0] = HEART_RATE_CHANNEL; - buff[8] = (byte) 220; - manager.handleMessage(AntMesg.MESG_BROADCAST_DATA_ID, buff); - - Sensor.SensorDataSet sds = manager.getSensorDataSet(); - assertNotNull(sds); - assertTrue(sds.hasHeartRate()); - assertEquals(Sensor.SensorState.SENDING, - sds.getHeartRate().getState()); - assertEquals(220, sds.getHeartRate().getValue()); - - assertFalse(sds.hasCadence()); - assertFalse(sds.hasPower()); - assertEquals(Sensor.SensorState.CONNECTED, manager.getSensorState()); - } - - @SmallTest - public void testChannelId() { - manager.setupAntSensorChannels(); - assertNotNull(heartRateSensor); - - byte[] buff = new byte[9]; - buff[1] = 43; - manager.handleMessage(AntMesg.MESG_CHANNEL_ID_ID, buff); - - assertEquals(43, heartRateSensor.getDeviceNumber()); - assertEquals(43, PreferencesUtils.getInt( - getContext(), R.string.ant_heart_rate_sensor_id_key, AntSensorManager.WILDCARD)); - assertNull(manager.getSensorDataSet()); - } - - @SmallTest - public void testResponseEvent() { - manager.setupAntSensorChannels(); - assertNotNull(heartRateSensor); - manager.setHeartRate(210); - heartRateSensor.setDeviceNumber((short) 42); - - assertEquals(Sensor.SensorState.CONNECTED, manager.getSensorState()); - byte[] buff = new byte[3]; - buff[0] = HEART_RATE_CHANNEL; - buff[1] = AntMesg.MESG_UNASSIGN_CHANNEL_ID; - buff[2] = 0; // code - manager.handleMessage(AntMesg.MESG_RESPONSE_EVENT_ID, buff); - assertEquals(Sensor.SensorState.CONNECTED, manager.getSensorState()); - - heartRateSensor.setDeviceNumber((short) 0); - manager.handleMessage(AntMesg.MESG_RESPONSE_EVENT_ID, buff); - assertEquals(Sensor.SensorState.DISCONNECTED, manager.getSensorState()); - } - - // TODO: Test timeout too. -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntMessageTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntMessageTest.java deleted file mode 100644 index 4fda67411..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntMessageTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import android.test.AndroidTestCase; - -public class AntMessageTest extends AndroidTestCase { - private static class TestAntMessage extends AntMessage { - public static short decodeShort(byte low, byte high) { - return AntMessage.decodeShort(low, high); - } - } - - public void testDecode() { - assertEquals(0x1234, TestAntMessage.decodeShort((byte) 0x34, (byte) 0x12)); - } -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManagerTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManagerTest.java deleted file mode 100644 index d7817b80f..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntSensorManagerTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import android.content.Context; -import android.test.AndroidTestCase; -import android.test.MoreAsserts; - -public class AntSensorManagerTest extends AndroidTestCase { - private class TestAntSensorManager extends AntSensorManager { - - public TestAntSensorManager(Context context) { - super(context); - } - - public byte messageId; - public byte[] messageData; - - @Override - protected void setupAntSensorChannels() {} - - @SuppressWarnings("deprecation") - @Override - public void handleMessage(byte[] rawMessage) { - super.handleMessage(rawMessage); - } - - @SuppressWarnings("hiding") - @Override - public boolean handleMessage(byte messageId, byte[] messageData) { - this.messageId = messageId; - this.messageData = messageData; - return true; - } - } - - private TestAntSensorManager sensorManager; - - @Override - protected void setUp() throws Exception { - super.setUp(); - sensorManager = new TestAntSensorManager(getContext()); - } - - public void testSimple() { - byte[] rawMessage = { - 0x03, // length - 0x12, // message id - 0x11, 0x22, 0x33, // body - }; - - byte[] expectedBody = { 0x11, 0x22, 0x33 }; - - sensorManager.handleMessage(rawMessage); - assertEquals((byte) 0x12, sensorManager.messageId); - MoreAsserts.assertEquals(expectedBody, sensorManager.messageData); - } - - public void testTooShort() { - byte[] rawMessage = { - 0x53, // length - 0x12 // message id - }; - - sensorManager.handleMessage(rawMessage); - assertEquals(0, sensorManager.messageId); - assertNull(sensorManager.messageData); - } - - public void testLengthWrong() { - byte[] rawMessage = { - 0x53, // length - 0x12, // message id - 0x34, // body - }; - - sensorManager.handleMessage(rawMessage); - assertEquals(0, sensorManager.messageId); - assertNull(sensorManager.messageData); - } -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntStartupMessageTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntStartupMessageTest.java deleted file mode 100644 index 5fc0c53e3..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/AntStartupMessageTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import android.test.AndroidTestCase; - -public class AntStartupMessageTest extends AndroidTestCase { - public void testParse() { - byte[] rawMessage = { - 0x12, - }; - - AntStartupMessage message = new AntStartupMessage(rawMessage); - assertEquals(0x12, message.getMessage()); - } -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/SensorEventCounterTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/SensorEventCounterTest.java deleted file mode 100644 index 59affe2b9..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/sensors/ant/SensorEventCounterTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ -package com.google.android.apps.mytracks.services.sensors.ant; - -import android.test.AndroidTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -/** - * @author Laszlo Molnar - */ -public class SensorEventCounterTest extends AndroidTestCase { - - @SmallTest - public void testGetEventsPerMinute() { - SensorEventCounter sec = new SensorEventCounter(); - assertEquals(0, sec.getEventsPerMinute(0, 0, 0)); - assertEquals(0, sec.getEventsPerMinute(1, 1024, 1000)); - assertEquals(60, sec.getEventsPerMinute(2, 1024 * 2, 2000)); - assertEquals(60, sec.getEventsPerMinute(2, 1024 * 2, 2500)); - assertTrue(60 > sec.getEventsPerMinute(2, 1024 * 2, 4000)); - } -}