package com.codegy.aerlink.connection; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattService; import android.content.Context; import android.util.Log; import com.codegy.aerlink.services.aerlink.ALSConstants; import com.codegy.aerlink.services.aerlink.UtilsServiceHandler; import com.codegy.aerlink.services.battery.BASConstants; import com.codegy.aerlink.services.battery.BatteryServiceHandler; import com.codegy.aerlink.services.aerlink.cameraremote.CameraRemoteServiceHandler; import com.codegy.aerlink.connection.characteristic.CharacteristicIdentifier; import com.codegy.aerlink.connection.command.Command; import com.codegy.aerlink.services.currenttime.CTSConstants; import com.codegy.aerlink.services.currenttime.CurrentTimeServiceHandler; import com.codegy.aerlink.services.media.AMSConstants; import com.codegy.aerlink.services.media.MediaServiceHandler; import com.codegy.aerlink.services.notifications.ANCSConstants; import com.codegy.aerlink.services.notifications.NotificationServiceHandler; import com.codegy.aerlink.services.aerlink.reminders.ReminderServiceHandler; import com.codegy.aerlink.utils.ServiceHandler; import com.codegy.aerlink.utils.ServiceUtils; import java.util.*; /** * Created by Guiye on 25/8/16. */ public class ServiceHandlerManager { private static final String LOG_TAG = ServiceHandlerManager.class.getSimpleName(); private Context mContext; private ServiceUtils mServiceUtils; private Map<Class, ServiceHandler> mServiceHandlers; public ServiceHandlerManager(Context context, ServiceUtils serviceUtils) { this.mContext = context; this.mServiceUtils = serviceUtils; mServiceHandlers = new HashMap<>(6); } public ServiceHandler getServiceHandler(Class serviceHandlerClass) { return mServiceHandlers.get(serviceHandlerClass); } public void close() { for (ServiceHandler serviceHandler : mServiceHandlers.values()) { serviceHandler.close(); } } public Queue<CharacteristicIdentifier> subscribeToServices(BluetoothGatt bluetoothGatt) { for (ServiceHandler handler : mServiceHandlers.values()) { handler.reset(); } BluetoothGattService notificationService = bluetoothGatt.getService(ANCSConstants.SERVICE_UUID); if (notificationService != null) { Log.i(LOG_TAG, "Notification Service available"); if (!mServiceHandlers.containsKey(NotificationServiceHandler.class)) { mServiceHandlers.put(NotificationServiceHandler.class, new NotificationServiceHandler(mContext, mServiceUtils)); } } else { Log.e(LOG_TAG, "Notification Service unavailable"); mServiceHandlers.remove(NotificationServiceHandler.class); } BluetoothGattService mediaService = bluetoothGatt.getService(AMSConstants.SERVICE_UUID); if (mediaService != null) { Log.i(LOG_TAG, "Media Service available"); if (!mServiceHandlers.containsKey(MediaServiceHandler.class)) { mServiceHandlers.put(MediaServiceHandler.class, new MediaServiceHandler(mContext, mServiceUtils)); } Command trackCommand = new Command(AMSConstants.SERVICE_UUID, AMSConstants.CHARACTERISTIC_ENTITY_UPDATE, new byte[] { AMSConstants.EntityIDTrack, AMSConstants.TrackAttributeIDTitle, AMSConstants.TrackAttributeIDArtist }); trackCommand.setImportance(Command.IMPORTANCE_MAX); Command playerCommand = new Command(AMSConstants.SERVICE_UUID, AMSConstants.CHARACTERISTIC_ENTITY_UPDATE, new byte[] { AMSConstants.EntityIDPlayer, AMSConstants.PlayerAttributeIDPlaybackInfo }); playerCommand.setImportance(Command.IMPORTANCE_MAX); mServiceUtils.addCommandToQueue(trackCommand); mServiceUtils.addCommandToQueue(playerCommand); } else { Log.e(LOG_TAG, "Media Service unavailable"); mServiceHandlers.remove(MediaServiceHandler.class); } BluetoothGattService batteryService = bluetoothGatt.getService(BASConstants.SERVICE_UUID); if (batteryService != null) { Log.i(LOG_TAG, "Battery Service available"); if (!mServiceHandlers.containsKey(BatteryServiceHandler.class)) { mServiceHandlers.put(BatteryServiceHandler.class, new BatteryServiceHandler(mContext, mServiceUtils)); } Command batteryCommand = new Command(BASConstants.SERVICE_UUID, BASConstants.CHARACTERISTIC_BATTERY_LEVEL); mServiceUtils.addCommandToQueue(batteryCommand); } else { Log.e(LOG_TAG, "Battery Service unavailable"); mServiceHandlers.remove(CurrentTimeServiceHandler.class); } // TODO: Sync time with iPhone BluetoothGattService currentTimeService = bluetoothGatt.getService(CTSConstants.SERVICE_UUID); if (currentTimeService != null) { Log.i(LOG_TAG, "Current Time Service available"); if (!mServiceHandlers.containsKey(CurrentTimeServiceHandler.class)) { mServiceHandlers.put(CurrentTimeServiceHandler.class, new CurrentTimeServiceHandler(mContext, mServiceUtils)); } Command timeCommand = new Command(CTSConstants.SERVICE_UUID, CTSConstants.CHARACTERISTIC_CURRENT_TIME); mServiceUtils.addCommandToQueue(timeCommand); } else { Log.e(LOG_TAG, "Current Time Service unavailable"); mServiceHandlers.remove(CurrentTimeServiceHandler.class); } BluetoothGattService aerlinkService = bluetoothGatt.getService(ALSConstants.SERVICE_UUID); if (aerlinkService != null && aerlinkService.getCharacteristics().size() >= 6) { Log.i(LOG_TAG, "Aerlink Service available"); if (!mServiceHandlers.containsKey(ReminderServiceHandler.class)) { mServiceHandlers.put(ReminderServiceHandler.class, new ReminderServiceHandler(mContext, mServiceUtils)); } if (!mServiceHandlers.containsKey(CameraRemoteServiceHandler.class)) { mServiceHandlers.put(CameraRemoteServiceHandler.class, new CameraRemoteServiceHandler(mContext, mServiceUtils)); } if (!mServiceHandlers.containsKey(UtilsServiceHandler.class)) { mServiceHandlers.put(UtilsServiceHandler.class, new UtilsServiceHandler(mContext, mServiceUtils)); } } else { Log.e(LOG_TAG, "Aerlink Service unavailable"); mServiceHandlers.remove(ReminderServiceHandler.class); mServiceHandlers.remove(CameraRemoteServiceHandler.class); mServiceHandlers.remove(UtilsServiceHandler.class); } Queue<CharacteristicIdentifier> requests = new LinkedList<>(); for (ServiceHandler serviceHandler : mServiceHandlers.values()) { UUID serviceUUID = serviceHandler.getServiceUUID(); List<String> characteristics = serviceHandler.getCharacteristicsToSubscribe(); if (serviceUUID != null && characteristics != null) { Log.i(LOG_TAG, "Adding characteristics: " + serviceUUID.toString()); for (String characteristic : characteristics) { requests.add(new CharacteristicIdentifier(serviceUUID, characteristic)); } } } return requests; } public void handleCharacteristic(BluetoothGattCharacteristic characteristic) { for (ServiceHandler serviceHandler : mServiceHandlers.values()) { if (serviceHandler.canHandleCharacteristic(characteristic)) { serviceHandler.handleCharacteristic(characteristic); break; } } } }