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.Toast;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -30,6 +33,7 @@ import nodomain.freeyourgadget.gadgetbridge.miband.MiBandConst;
|
|||
|
||||
public class ControlCenter extends Activity {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ControlCenter.class);
|
||||
|
||||
public static final String ACTION_QUIT
|
||||
= "nodomain.freeyourgadget.gadgetbride.controlcenter.action.quit";
|
||||
|
@ -57,7 +61,7 @@ public class ControlCenter extends Activity {
|
|||
refreshPairedDevices();
|
||||
break;
|
||||
case GBDevice.ACTION_DEVICE_CHANGED:
|
||||
GBDevice dev = intent.getParcelableExtra("device");
|
||||
GBDevice dev = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE);
|
||||
if (dev.getAddress() != null) {
|
||||
int index = deviceList.indexOf(dev); // search by address
|
||||
if (index >= 0) {
|
||||
|
@ -68,7 +72,8 @@ public class ControlCenter extends Activity {
|
|||
}
|
||||
refreshPairedDevices();
|
||||
|
||||
if (dev.isConnected() && dev.getFirmwareVersion() == null) {
|
||||
if (dev.isConnected() && dev.getFirmwareVersion() == null && !dev.isInitializing()) {
|
||||
LOG.info("device connected, requesting more info");
|
||||
requestDeviceInfo();
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -104,6 +104,10 @@ public class GBDevice implements Parcelable {
|
|||
return mState.ordinal() >= State.CONNECTED.ordinal();
|
||||
}
|
||||
|
||||
public boolean isInitializing() {
|
||||
return mState == State.INITIALIZING;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return mState.ordinal() >= State.INITIALIZED.ordinal();
|
||||
}
|
||||
|
@ -118,8 +122,10 @@ public class GBDevice implements Parcelable {
|
|||
|
||||
public void setState(State state) {
|
||||
mState = state;
|
||||
if (state.ordinal() <= State.CONNECTED.ordinal()) {
|
||||
unsetDynamicState();
|
||||
}
|
||||
}
|
||||
|
||||
private void unsetDynamicState() {
|
||||
setBatteryLevel(BATTERY_UNKNOWN);
|
||||
|
@ -136,6 +142,8 @@ public class GBDevice implements Parcelable {
|
|||
return GBApplication.getContext().getString(R.string.connecting);
|
||||
case CONNECTED:
|
||||
return GBApplication.getContext().getString(R.string.connected);
|
||||
case INITIALIZING:
|
||||
return GBApplication.getContext().getString(R.string.initializing);
|
||||
case INITIALIZED:
|
||||
return GBApplication.getContext().getString(R.string.initialized);
|
||||
}
|
||||
|
@ -238,6 +246,7 @@ public class GBDevice implements Parcelable {
|
|||
NOT_CONNECTED,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
INITIALIZING,
|
||||
INITIALIZED
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport im
|
|||
if (!isInitialized()) {
|
||||
// first, add a transaction that performs device initialization
|
||||
TransactionBuilder builder = createTransactionBuilder("Initialize device");
|
||||
builder.add(new CheckInitializedAction(gbDevice));
|
||||
initializeDevice(builder).queue(getQueue());
|
||||
}
|
||||
return createTransactionBuilder(taskName);
|
||||
|
|
|
@ -87,15 +87,14 @@ public final class BtLEQueue {
|
|||
}
|
||||
}
|
||||
} catch (InterruptedException ignored) {
|
||||
mWaitForActionResultLatch = null;
|
||||
mConnectionLatch = null;
|
||||
LOG.debug("Thread interrupted");
|
||||
} catch (Throwable ex) {
|
||||
LOG.error("Queue Dispatch Thread died: " + ex.getMessage());
|
||||
mCrashed = true;
|
||||
mWaitForActionResultLatch = null;
|
||||
mConnectionLatch = null;
|
||||
} finally {
|
||||
mWaitForActionResultLatch = 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
|
||||
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
|
||||
builder.add(new SetDeviceStateAction(getDevice(), State.INITIALIZING, getContext()));
|
||||
pair(builder)
|
||||
.sendUserInfo(builder)
|
||||
.enableNotifications(builder, true)
|
||||
.setCurrentTime(builder)
|
||||
.requestBatteryInfo(builder);
|
||||
.requestBatteryInfo(builder)
|
||||
.setInitialized(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
|
||||
private MiBandSupport enableNotifications(TransactionBuilder builder, boolean 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="pref_log_to_file">LogToFile</string>
|
||||
<string name="pref_write_logfiles">Write Log Files (needs restart)</string>
|
||||
<string name="initializing">initializing</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue