Some fixes regarding device initialization, should avoid disconnects
Avoid repeated initializations and device info requests. Fix unsetting of dynamic state (e.g. battery info) when initialized.
This commit is contained in:
parent
f60903699e
commit
7f89f4bb57
|
@ -20,6 +20,9 @@ import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -30,6 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst;
|
||||||
|
|
||||||
public class ControlCenter extends Activity {
|
public class ControlCenter extends Activity {
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(ControlCenter.class);
|
||||||
|
|
||||||
public static final String ACTION_QUIT
|
public static final String ACTION_QUIT
|
||||||
= "nodomain.freeyourgadget.gadgetbride.controlcenter.action.quit";
|
= "nodomain.freeyourgadget.gadgetbride.controlcenter.action.quit";
|
||||||
|
@ -57,7 +61,7 @@ public class ControlCenter extends Activity {
|
||||||
refreshPairedDevices();
|
refreshPairedDevices();
|
||||||
break;
|
break;
|
||||||
case GBDevice.ACTION_DEVICE_CHANGED:
|
case GBDevice.ACTION_DEVICE_CHANGED:
|
||||||
GBDevice dev = intent.getParcelableExtra("device");
|
GBDevice dev = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||||
if (dev.getAddress() != null) {
|
if (dev.getAddress() != null) {
|
||||||
int index = deviceList.indexOf(dev); // search by address
|
int index = deviceList.indexOf(dev); // search by address
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@ -68,7 +72,8 @@ public class ControlCenter extends Activity {
|
||||||
}
|
}
|
||||||
refreshPairedDevices();
|
refreshPairedDevices();
|
||||||
|
|
||||||
if (dev.isConnected() && dev.getFirmwareVersion() == null) {
|
if (dev.isConnected() && dev.getFirmwareVersion() == null && !dev.isInitializing()) {
|
||||||
|
LOG.info("device connected, requesting more info");
|
||||||
requestDeviceInfo();
|
requestDeviceInfo();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -104,6 +104,10 @@ public class GBDevice implements Parcelable {
|
||||||
return mState.ordinal() >= State.CONNECTED.ordinal();
|
return mState.ordinal() >= State.CONNECTED.ordinal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInitializing() {
|
||||||
|
return mState == State.INITIALIZING;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isInitialized() {
|
public boolean isInitialized() {
|
||||||
return mState.ordinal() >= State.INITIALIZED.ordinal();
|
return mState.ordinal() >= State.INITIALIZED.ordinal();
|
||||||
}
|
}
|
||||||
|
@ -118,7 +122,9 @@ public class GBDevice implements Parcelable {
|
||||||
|
|
||||||
public void setState(State state) {
|
public void setState(State state) {
|
||||||
mState = state;
|
mState = state;
|
||||||
unsetDynamicState();
|
if (state.ordinal() <= State.CONNECTED.ordinal()) {
|
||||||
|
unsetDynamicState();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unsetDynamicState() {
|
private void unsetDynamicState() {
|
||||||
|
@ -136,6 +142,8 @@ public class GBDevice implements Parcelable {
|
||||||
return GBApplication.getContext().getString(R.string.connecting);
|
return GBApplication.getContext().getString(R.string.connecting);
|
||||||
case CONNECTED:
|
case CONNECTED:
|
||||||
return GBApplication.getContext().getString(R.string.connected);
|
return GBApplication.getContext().getString(R.string.connected);
|
||||||
|
case INITIALIZING:
|
||||||
|
return GBApplication.getContext().getString(R.string.initializing);
|
||||||
case INITIALIZED:
|
case INITIALIZED:
|
||||||
return GBApplication.getContext().getString(R.string.initialized);
|
return GBApplication.getContext().getString(R.string.initialized);
|
||||||
}
|
}
|
||||||
|
@ -238,6 +246,7 @@ public class GBDevice implements Parcelable {
|
||||||
NOT_CONNECTED,
|
NOT_CONNECTED,
|
||||||
CONNECTING,
|
CONNECTING,
|
||||||
CONNECTED,
|
CONNECTED,
|
||||||
|
INITIALIZING,
|
||||||
INITIALIZED
|
INITIALIZED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,7 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
|
||||||
if (!isInitialized()) {
|
if (!isInitialized()) {
|
||||||
// first, add a transaction that performs device initialization
|
// first, add a transaction that performs device initialization
|
||||||
TransactionBuilder builder = createTransactionBuilder("Initialize device");
|
TransactionBuilder builder = createTransactionBuilder("Initialize device");
|
||||||
|
builder.add(new CheckInitializedAction(gbDevice));
|
||||||
initializeDevice(builder).queue(getQueue());
|
initializeDevice(builder).queue(getQueue());
|
||||||
}
|
}
|
||||||
return createTransactionBuilder(taskName);
|
return createTransactionBuilder(taskName);
|
||||||
|
|
|
@ -87,15 +87,14 @@ public final class BtLEQueue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
mWaitForActionResultLatch = null;
|
|
||||||
mConnectionLatch = null;
|
mConnectionLatch = null;
|
||||||
LOG.debug("Thread interrupted");
|
LOG.debug("Thread interrupted");
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
LOG.error("Queue Dispatch Thread died: " + ex.getMessage());
|
LOG.error("Queue Dispatch Thread died: " + ex.getMessage());
|
||||||
mCrashed = true;
|
mCrashed = true;
|
||||||
mWaitForActionResultLatch = null;
|
|
||||||
mConnectionLatch = null;
|
mConnectionLatch = null;
|
||||||
} finally {
|
} finally {
|
||||||
|
mWaitForActionResultLatch = null;
|
||||||
mWaitCharacteristic = null;
|
mWaitCharacteristic = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.btle;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBDevice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A special action that is executed at the very front of the initialization
|
||||||
|
* sequence (transaction). It will abort the entire initialization sequence
|
||||||
|
* by returning false, when the device is already initialized.
|
||||||
|
*/
|
||||||
|
public class CheckInitializedAction extends BtLEAction {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(CheckInitializedAction.class);
|
||||||
|
|
||||||
|
private final GBDevice device;
|
||||||
|
|
||||||
|
public CheckInitializedAction(GBDevice gbDevice) {
|
||||||
|
device = gbDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean run(BluetoothGatt gatt) {
|
||||||
|
boolean continueWithOtherInitActions = !device.isInitialized();
|
||||||
|
if (!continueWithOtherInitActions) {
|
||||||
|
LOG.info("Aborting device initialization, because already initialized: " + device);
|
||||||
|
}
|
||||||
|
return continueWithOtherInitActions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean expectsResult() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,15 +55,27 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
|
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
|
||||||
|
builder.add(new SetDeviceStateAction(getDevice(), State.INITIALIZING, getContext()));
|
||||||
pair(builder)
|
pair(builder)
|
||||||
.sendUserInfo(builder)
|
.sendUserInfo(builder)
|
||||||
.enableNotifications(builder, true)
|
.enableNotifications(builder, true)
|
||||||
.setCurrentTime(builder)
|
.setCurrentTime(builder)
|
||||||
.requestBatteryInfo(builder);
|
.requestBatteryInfo(builder)
|
||||||
|
.setInitialized(builder);
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Last action of initialization sequence. Sets the device to initialized.
|
||||||
|
* It is only invoked if all other actions were successfully run, so the device
|
||||||
|
* must be initialized, then.
|
||||||
|
* @param builder
|
||||||
|
*/
|
||||||
|
private void setInitialized(TransactionBuilder builder) {
|
||||||
|
builder.add(new SetDeviceStateAction(getDevice(), State.INITIALIZED, getContext()));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: tear down the notifications on quit
|
// TODO: tear down the notifications on quit
|
||||||
private MiBandSupport enableNotifications(TransactionBuilder builder, boolean enable) {
|
private MiBandSupport enableNotifications(TransactionBuilder builder, boolean enable) {
|
||||||
builder.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_NOTIFICATION), enable)
|
builder.notify(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_NOTIFICATION), enable)
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package nodomain.freeyourgadget.gadgetbridge.miband;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothGatt;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.btle.BtLEAction;
|
||||||
|
|
||||||
|
public class SetDeviceStateAction extends BtLEAction {
|
||||||
|
private final GBDevice device;
|
||||||
|
private final GBDevice.State deviceState;
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
|
public SetDeviceStateAction(GBDevice device, GBDevice.State deviceState, Context context) {
|
||||||
|
this.device = device;
|
||||||
|
this.deviceState = deviceState;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean run(BluetoothGatt gatt) {
|
||||||
|
device.setState(deviceState);
|
||||||
|
device.sendDeviceUpdateIntent(getContext());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean expectsResult() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
|
@ -104,5 +104,6 @@
|
||||||
<string name="title_activity_sleepmonitor">Sleep Monitor</string>
|
<string name="title_activity_sleepmonitor">Sleep Monitor</string>
|
||||||
<string name="pref_log_to_file">LogToFile</string>
|
<string name="pref_log_to_file">LogToFile</string>
|
||||||
<string name="pref_write_logfiles">Write Log Files (needs restart)</string>
|
<string name="pref_write_logfiles">Write Log Files (needs restart)</string>
|
||||||
|
<string name="initializing">initializing</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in New Issue