Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44fd822d authored by Mark Harman's avatar Mark Harman
Browse files

Refactoring.

parent d16a4a4f
Loading
Loading
Loading
Loading
+83 −88
Original line number Diff line number Diff line
@@ -31,15 +31,15 @@ import java.util.UUID;

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
public class BluetoothLeService extends Service {
    private final static String TAG = BluetoothLeService.class.getSimpleName();
    private final static String TAG = "BluetoothLeService";

    private BluetoothManager mBluetoothManager;
    private BluetoothAdapter mBluetoothAdapter;
    private String mBluetoothDeviceAddress;
    private BluetoothGatt mBluetoothGatt;
    private String mRemoteDeviceType;
    private final HashMap<String, BluetoothGattCharacteristic> subscribedCharacteristics = new HashMap<>();
    private final List<BluetoothGattCharacteristic> charsToSubscribeTo = new ArrayList<>();
    private BluetoothManager bluetoothManager;
    private BluetoothAdapter bluetoothAdapter;
    private String device_address;
    private BluetoothGatt bluetoothGatt;
    private String remote_device_type;
    private final HashMap<String, BluetoothGattCharacteristic> subscribed_characteristics = new HashMap<>();
    private final List<BluetoothGattCharacteristic> charsToSubscribe = new ArrayList<>();

    private double currentTemp = -1;
    private double currentDepth = -1;
@@ -73,15 +73,12 @@ public class BluetoothLeService extends Service {
    public final static int COMMAND_UP = 64;
    public final static int COMMAND_DOWN = 80;



    public void setRemoteDeviceType(String remoteDeviceType) {
    public void setRemoteDeviceType(String remote_device_type) {
        if( MyDebug.LOG )
            Log.d(TAG, "Setting remote type: " + remoteDeviceType);
        mRemoteDeviceType = remoteDeviceType;
            Log.d(TAG, "Setting remote type: " + remote_device_type);
        this.remote_device_type = remote_device_type;
    }

    // Various callback methods defined by the BLE API.
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
@@ -90,14 +87,14 @@ public class BluetoothLeService extends Service {
                intentAction = ACTION_GATT_CONNECTED;
                broadcastUpdate(intentAction);
                if( MyDebug.LOG ) {
                    Log.d(TAG, "Connected to GATT server.");
                    Log.d(TAG, "Attempting to start service discovery");
                    Log.d(TAG, "Connected to GATT server, call discoverServices()");
                }
                mBluetoothGatt.discoverServices();
                bluetoothGatt.discoverServices();
                currentDepth = -1;
                currentTemp = -1;

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            }
            else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                intentAction = ACTION_GATT_DISCONNECTED;
                if( MyDebug.LOG )
                    Log.d(TAG, "Disconnected from GATT server, reattempting every 5 seconds.");
@@ -112,7 +109,7 @@ public class BluetoothLeService extends Service {
                public void run() {
                    if( MyDebug.LOG )
                        Log.d(TAG, "Attempting to reconnect to remote.");
                    connect(mBluetoothDeviceAddress);
                    connect(device_address);
                }
            }, 5000);
        }
@@ -122,37 +119,33 @@ public class BluetoothLeService extends Service {
            if( status == BluetoothGatt.GATT_SUCCESS ) {
                broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                subscribeToServices();
            } else {
            }
            else {
                if( MyDebug.LOG )
                    Log.d(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            if( status == BluetoothGatt.GATT_SUCCESS ) {
                broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            if( MyDebug.LOG )
                Log.d(TAG,"Got notification");
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }

        @Override
        public void onDescriptorWrite (BluetoothGatt gatt,
                                       BluetoothGattDescriptor descriptor,
                                       int status) {
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            // We need to wait for this callback before enabling the next notification in case we
            // have several in our list
            if (!charsToSubscribeTo.isEmpty()) {
                setCharacteristicNotification(charsToSubscribeTo.remove(0), true);
            if( !charsToSubscribe.isEmpty() ) {
                setCharacteristicNotification(charsToSubscribe.remove(0), true);
            }
        }
    };
@@ -167,7 +160,7 @@ public class BluetoothLeService extends Service {
        if (gattServices == null) return;
        List<UUID> mCharacteristicsWanted;

        switch (mRemoteDeviceType) {
        switch( remote_device_type ) {
            case "preference_remote_type_kraken":
                mCharacteristicsWanted = KrakenGattAttributes.getDesiredCharacteristics();
                break;
@@ -176,23 +169,19 @@ public class BluetoothLeService extends Service {
                break;
        }

        // Loops through available GATT Services and characteristics, and subscribe to
        // the ones we want. Today, we just enable notifications since that's all we need.
        for(BluetoothGattService gattService : gattServices) {
            List<BluetoothGattCharacteristic> gattCharacteristics =
                    gattService.getCharacteristics();
            // Loops through available Characteristics.
            for(BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                UUID uuid = gattCharacteristic.getUuid();
                if( mCharacteristicsWanted.contains(uuid) ) {
                    if( MyDebug.LOG )
                        Log.d(TAG, "Found characteristic to subscribe to: " + uuid);
                    charsToSubscribeTo.add(gattCharacteristic);
                    charsToSubscribe.add(gattCharacteristic);
                }
            }
        }
        // We need to enable notifications asynchronously
        setCharacteristicNotification(charsToSubscribeTo.remove(0), true);
        setCharacteristicNotification(charsToSubscribe.remove(0), true);
    }

    private void broadcastUpdate(final String action) {
@@ -200,8 +189,7 @@ public class BluetoothLeService extends Service {
        sendBroadcast(intent);
    }

    private void broadcastUpdate( String action,
                                 final BluetoothGattCharacteristic characteristic) {
    private void broadcastUpdate(String action, final BluetoothGattCharacteristic characteristic) {
        UUID uuid = characteristic.getUuid();
        final int format_uint8 = BluetoothGattCharacteristic.FORMAT_UINT8;
        final int format_uint16 = BluetoothGattCharacteristic.FORMAT_UINT16;
@@ -222,20 +210,25 @@ public class BluetoothLeService extends Service {
            if( buttonCode == 32 ) {
                // Shutter press
                remoteCommand = COMMAND_SHUTTER;
            } else if (buttonCode == 16) {
            }
            else if( buttonCode == 16 ) {
                // "Mode" button: either "back" action or "Photo/Camera" switch
                remoteCommand = COMMAND_MODE;
            } else if (buttonCode == 48) {
            }
            else if( buttonCode == 48 ) {
                // "Menu" button
                remoteCommand = COMMAND_MENU;
            } else if (buttonCode == 97) {
            }
            else if( buttonCode == 97 ) {
                // AF/MF button
                remoteCommand = COMMAND_AFMF;
            } else if (buttonCode == 96) {
            }
            else if( buttonCode == 96 ) {
                // Long press on MF/AF button.
                // Note: the camera issues button code 97 first, then
                // 96 after one second of continuous press
            } else if (buttonCode == 64) {
            }
            else if( buttonCode == 64 ) {
                // Up button
                remoteCommand = COMMAND_UP;
            } else if (buttonCode == 80) {
@@ -248,7 +241,8 @@ public class BluetoothLeService extends Service {
                intent.putExtra(EXTRA_DATA, remoteCommand);
                sendBroadcast(intent);
            }
        } else if (KrakenGattAttributes.KRAKEN_SENSORS_CHARACTERISTIC.equals(uuid)) {
        }
        else if( KrakenGattAttributes.KRAKEN_SENSORS_CHARACTERISTIC.equals(uuid) ) {
            // The housing returns four bytes.
            // Byte 0-1: depth = (Byte 0 + Byte 1 << 8) / 10 / density
            // Byte 2-3: temperature = (Byte 2 + Byte 3 << 8) / 10
@@ -300,16 +294,16 @@ public class BluetoothLeService extends Service {


    public boolean initialize() {
        if (mBluetoothManager == null) {
            mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
            if (mBluetoothManager == null) {
        if( bluetoothManager == null ) {
            bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
            if( bluetoothManager == null ) {
                Log.e(TAG, "Unable to initialize BluetoothManager.");
                return false;
            }
        }

        mBluetoothAdapter = mBluetoothManager.getAdapter();
        if (mBluetoothAdapter == null) {
        bluetoothAdapter = bluetoothManager.getAdapter();
        if( bluetoothAdapter == null ) {
            Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
            return false;
        }
@@ -320,9 +314,9 @@ public class BluetoothLeService extends Service {
	public boolean connect(final String address) {
        if( MyDebug.LOG )
            Log.d(TAG, "connect: " + address);
        if( mBluetoothAdapter == null ) {
        if( bluetoothAdapter == null ) {
            if( MyDebug.LOG )
                Log.d(TAG, "mBluetoothAdapter is null");
                Log.d(TAG, "bluetoothAdapter is null");
            return false;
        }
        else if( address == null ) {
@@ -331,13 +325,13 @@ public class BluetoothLeService extends Service {
            return false;
        }

        if( mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null ) {
            mBluetoothGatt.disconnect();
            mBluetoothGatt.close();
            mBluetoothGatt = null;
        if( device_address != null && address.equals(device_address) && bluetoothGatt != null ) {
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            bluetoothGatt = null;
        }

        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
        if( device == null ) {
            if( MyDebug.LOG )
                Log.d(TAG, "device not found");
@@ -352,48 +346,49 @@ public class BluetoothLeService extends Service {
            return false;
        }

        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
        mBluetoothDeviceAddress = address;
        bluetoothGatt = device.connectGatt(this, false, mGattCallback);
        device_address = address;
        return true;
	}

    private void close() {
        if( mBluetoothGatt == null ) {
        if( bluetoothGatt == null ) {
            return;
        }
        mBluetoothGatt.close();
        mBluetoothGatt = null;
        bluetoothGatt.close();
        bluetoothGatt = null;
    }

    private void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
                                              boolean enabled) {
        if( mBluetoothAdapter == null ) {
    private void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
        if( bluetoothAdapter == null ) {
            if( MyDebug.LOG )
                Log.d(TAG, "mBluetoothAdapter is null");
                Log.d(TAG, "bluetoothAdapter is null");
            return;
        }
        else if( mBluetoothGatt == null ) {
        else if( bluetoothGatt == null ) {
            if( MyDebug.LOG )
                Log.d(TAG, "mBluetoothGatt is null");
                Log.d(TAG, "bluetoothGatt is null");
            return;
        }

        String uuid = characteristic.getUuid().toString();
        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
        bluetoothGatt.setCharacteristicNotification(characteristic, enabled);
        if( enabled ) {
            subscribedCharacteristics.put(uuid, characteristic);
        } else {
            subscribedCharacteristics.remove(uuid);
            subscribed_characteristics.put(uuid, characteristic);
        }
        else {
            subscribed_characteristics.remove(uuid);
        }

        BluetoothGattDescriptor descriptor = characteristic.getDescriptor(KrakenGattAttributes.CLIENT_CHARACTERISTIC_CONFIG);
        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
        mBluetoothGatt.writeDescriptor(descriptor);
        bluetoothGatt.writeDescriptor(descriptor);
    }

    private List<BluetoothGattService> getSupportedGattServices() {
        if (mBluetoothGatt == null) return null;
        if( bluetoothGatt == null )
            return null;

        return mBluetoothGatt.getServices();
        return bluetoothGatt.getServices();
    }
}
+64 −52
Original line number Diff line number Diff line
@@ -27,16 +27,16 @@ public class BluetoothRemoteControl {

    private final MainActivity main_activity;

    private BluetoothLeService mBluetoothLeService;
    private String mRemoteDeviceAddress;
    private String mRemoteDeviceType;
    private boolean mRemoteConnected;
    private BluetoothLeService bluetoothLeService;
    private String remoteDeviceAddress;
    private String remoteDeviceType;
    private boolean is_connected;

    public BluetoothRemoteControl(MainActivity main_activity) {
        this.main_activity = main_activity;
    }

    // Code to manage Service lifecycle for remote control.
    // class to manage the Service lifecycle for remote control.
    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
@@ -45,13 +45,13 @@ public class BluetoothRemoteControl {
                // BluetoothLeService requires Android 4.3+
                return;
            }
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
            bluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if( !bluetoothLeService.initialize() ) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                stopRemoteControl();
            }
            // Automatically connects to the device upon successful start-up initialization.
            mBluetoothLeService.connect(mRemoteDeviceAddress);
            // connect to the device
            bluetoothLeService.connect(remoteDeviceAddress);
        }

        @Override
@@ -61,7 +61,7 @@ public class BluetoothRemoteControl {
                public void run() {
                    if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 ) {
                        // BluetoothLeService requires Android 4.3+
                        mBluetoothLeService.connect(mRemoteDeviceAddress);
                        bluetoothLeService.connect(remoteDeviceAddress);
                    }
                }
            }, 5000);
@@ -88,28 +88,29 @@ public class BluetoothRemoteControl {
                if( MyDebug.LOG )
                    Log.d(TAG, "Remote connected");
                // Tell the Bluetooth service what type of remote we want to use
                mBluetoothLeService.setRemoteDeviceType(mRemoteDeviceType);
                bluetoothLeService.setRemoteDeviceType(remoteDeviceType);
                main_activity.setBrightnessForCamera(false);
            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            }
            else if( BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action) ) {
                if( MyDebug.LOG )
                    Log.d(TAG, "Remote disconnected");
                mRemoteConnected = false;
                is_connected = false;
                applicationInterface.getDrawPreview().onExtraOSDValuesChanged("-- \u00B0C", "-- m");
                mainUI.updateRemoteConnectionIcon();
                main_activity.setBrightnessToMinimumIfWanted();
                if (mainUI.isExposureUIOpen())
                    mainUI.toggleExposureUI();
            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            }
            else if( BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action) ) {
                if( MyDebug.LOG )
                    Log.d(TAG, "Remote services discovered");
                /*
                We let the BluetoothLEService subscribe to what is relevant, so we
                do nothing here, but we wait until this is done to update the UI
                icon
                */
                mRemoteConnected = true;
                // We let the BluetoothLEService subscribe to what is relevant, so we
                // do nothing here, but we wait until this is done to update the UI
                // icon
                is_connected = true;
                mainUI.updateRemoteConnectionIcon();
            } else if (BluetoothLeService.ACTION_SENSOR_VALUE.equals(action)) {
            }
            else if( BluetoothLeService.ACTION_SENSOR_VALUE.equals(action) ) {
                double temp = intent.getDoubleExtra(BluetoothLeService.SENSOR_TEMPERATURE, -1);
                double depth = intent.getDoubleExtra(BluetoothLeService.SENSOR_DEPTH, -1) / main_activity.getWaterDensity();
                depth = (Math.round(depth* 10)) / 10.0; // Round to 1 decimal
@@ -119,7 +120,8 @@ public class BluetoothRemoteControl {
                String line1 = "" + temp + " \u00B0C";
                String line2 = "" + depth + " m";
                applicationInterface.getDrawPreview().onExtraOSDValuesChanged(line1, line2);
            } else if (BluetoothLeService.ACTION_REMOTE_COMMAND.equals(action)) {
            }
            else if( BluetoothLeService.ACTION_REMOTE_COMMAND.equals(action) ) {
                int command = intent.getIntExtra(BluetoothLeService.EXTRA_DATA, -1);
                // TODO: we could abstract this into a method provided by each remote control model
                switch( command ) {
@@ -132,9 +134,11 @@ public class BluetoothRemoteControl {
                        // closes the settings screen that is currently open
                        if( mainUI.popupIsOpen() ) {
                            mainUI.togglePopupSettings();
                        } else if (mainUI.isExposureUIOpen()) {
                        }
                        else if( mainUI.isExposureUIOpen() ) {
                            mainUI.toggleExposureUI();
                        } else {
                        }
                        else {
                            main_activity.clickedSwitchVideo(null);
                        }
                        break;
@@ -145,10 +149,12 @@ public class BluetoothRemoteControl {
                        if( !mainUI.popupIsOpen() ) {
                            if( !mainUI.isExposureUIOpen() ) {
                                mainUI.toggleExposureUI();
                            } else {
                            }
                            else {
                                mainUI.commandMenuExposure();
                            }
                        } else {
                        }
                        else {
                            mainUI.commandMenuPopup();
                        }
                        break;
@@ -159,7 +165,8 @@ public class BluetoothRemoteControl {
                            // - if we are on autofocus, then adjust zoom.
                            if( main_activity.getPreview().getCurrentFocusValue() != null && main_activity.getPreview().getCurrentFocusValue().equals("focus_mode_manual2") ) {
                                main_activity.changeFocusDistance(-25, false);
                            } else {
                            }
                            else {
                                // Adjust zoom
                                main_activity.zoomIn();
                            }
@@ -169,7 +176,8 @@ public class BluetoothRemoteControl {
                        if( !mainUI.processRemoteDownButton() ) {
                            if( main_activity.getPreview().getCurrentFocusValue() != null && main_activity.getPreview().getCurrentFocusValue().equals("focus_mode_manual2") ) {
                                main_activity.changeFocusDistance(25, false);
                            } else {
                            }
                            else {
                                // Adjust zoom
                                main_activity.zoomOut();
                            }
@@ -186,7 +194,8 @@ public class BluetoothRemoteControl {
                    default:
                        break;
                }
            } else {
            }
            else {
                if( MyDebug.LOG )
                    Log.d(TAG, "Other remote event");
            }
@@ -196,7 +205,7 @@ public class BluetoothRemoteControl {
    public boolean remoteConnected() {
		/*if( true )
			return true; // test*/
        return mRemoteConnected;
        return is_connected;
    }

    // TODO: refactor for a filter than receives generic remote control intents
@@ -228,16 +237,18 @@ public class BluetoothRemoteControl {
                Log.d(TAG, "Remote enabled, starting service");
            main_activity.bindService(gattServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
            main_activity.registerReceiver(remoteControlCommandReceiver, makeRemoteCommandIntentFilter());
        } else {
        }
        else {
            if( MyDebug.LOG )
                Log.d(TAG, "Remote disabled, stopping service");
            // Stop the service if necessary
            try {
                main_activity.unregisterReceiver(remoteControlCommandReceiver);
                main_activity.unbindService(mServiceConnection);
                mRemoteConnected = false; // Unbinding closes the connection, of course
                is_connected = false; // Unbinding closes the connection, of course
                main_activity.getMainUI().updateRemoteConnectionIcon();
            } catch (IllegalArgumentException e){
            }
            catch(IllegalArgumentException e){
                if( MyDebug.LOG )
                    Log.d(TAG, "Remote Service was not running, that's fine");
            }
@@ -252,9 +263,10 @@ public class BluetoothRemoteControl {
            try {
                main_activity.unregisterReceiver(remoteControlCommandReceiver);
                main_activity.unbindService(mServiceConnection);
                mRemoteConnected = false; // Unbinding closes the connection, of course
                is_connected = false; // Unbinding closes the connection, of course
                main_activity.getMainUI().updateRemoteConnectionIcon();
            } catch (IllegalArgumentException e){
            }
            catch(IllegalArgumentException e){
                Log.e(TAG, "Remote Service was not running, that's strange");
                e.printStackTrace();
            }
@@ -273,8 +285,8 @@ public class BluetoothRemoteControl {
        }
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(main_activity);
        boolean remote_enabled = sharedPreferences.getBoolean(PreferenceKeys.EnableRemote, false);
        mRemoteDeviceType = sharedPreferences.getString(PreferenceKeys.RemoteType, "undefined");
        mRemoteDeviceAddress = sharedPreferences.getString(PreferenceKeys.RemoteName, "undefined");
        return remote_enabled && !mRemoteDeviceAddress.equals("undefined");
        remoteDeviceType = sharedPreferences.getString(PreferenceKeys.RemoteType, "undefined");
        remoteDeviceAddress = sharedPreferences.getString(PreferenceKeys.RemoteName, "undefined");
        return remote_enabled && !remoteDeviceAddress.equals("undefined");
    }
}
+48 −62

File changed.

Preview size limit exceeded, changes collapsed.

+0 −3
Original line number Diff line number Diff line
@@ -10,9 +10,6 @@ import java.util.UUID;
 * Bluetooth Low Energy
 */
public class KrakenGattAttributes {
    // The Kraken Smart Housing advertises itself as a heart measurement device, talk about
    // lazy devs...
    //public static final UUID HEART_RATE_MEASUREMENT = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb");
    public static final UUID CLIENT_CHARACTERISTIC_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

    //public static final UUID KRAKEN_SENSORS_SERVICE = UUID.fromString("00001623-1212-efde-1523-785feabcd123");