Skip to content

Range update period #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 93 additions & 5 deletions src/main/java/org/altbeacon/beacon/BeaconManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,30 @@ public static void setDebug(boolean debug) {
*/
public static final long DEFAULT_EXIT_PERIOD = 10000L;


public static final long DEFAULT_BACKGROUND_RANGE_UPDATE_PERIOD = 100;

public static final long DEFAULT_BACKGROUND_BETWEEN_RANGE_UPDATE_PERIOD = 0;

public static final long DEFAULT_FOREGROUND_RANGE_UPDATE_PERIOD = 100;

public static final long DEFAULT_FOREGROUND_BETWEEN_RANGE_UPDATE_PERIOD = 0;

private static long sExitRegionPeriod = DEFAULT_EXIT_PERIOD;

private long foregroundScanPeriod = DEFAULT_FOREGROUND_SCAN_PERIOD;
private long foregroundBetweenScanPeriod = DEFAULT_FOREGROUND_BETWEEN_SCAN_PERIOD;
private long backgroundScanPeriod = DEFAULT_BACKGROUND_SCAN_PERIOD;
private long backgroundBetweenScanPeriod = DEFAULT_BACKGROUND_BETWEEN_SCAN_PERIOD;

private boolean backgroundRangeMidScan = false;
private boolean foregroundRangeMidScan = false;

private long backgroundRangeUpdatePeriod = DEFAULT_BACKGROUND_RANGE_UPDATE_PERIOD;
private long backgroundBetweenRangeUpdatePeriod = DEFAULT_BACKGROUND_BETWEEN_RANGE_UPDATE_PERIOD;
private long foregroundRangeUpdatePeriod = DEFAULT_FOREGROUND_RANGE_UPDATE_PERIOD;
private long foregroundBetweenRangeUpdatePeriod = DEFAULT_FOREGROUND_BETWEEN_RANGE_UPDATE_PERIOD;

/**
* Sets the duration in milliseconds of each Bluetooth LE scan cycle to look for beacons.
* This function is used to setup the period before calling {@link #bind} or when switching
Expand All @@ -181,6 +198,7 @@ public static void setDebug(boolean debug) {
* @param p
*/
public void setForegroundScanPeriod(long p) {
foregroundRangeMidScan = true;
foregroundScanPeriod = p;
}

Expand All @@ -205,6 +223,7 @@ public void setForegroundBetweenScanPeriod(long p) {
* @param p
*/
public void setBackgroundScanPeriod(long p) {
backgroundRangeMidScan = true;
backgroundScanPeriod = p;
}

Expand All @@ -217,6 +236,23 @@ public void setBackgroundBetweenScanPeriod(long p) {
backgroundBetweenScanPeriod = p;
}

public void setBackgroundRangeUpdatePeriod(long p) {
backgroundRangeUpdatePeriod = p;
}

public void setBackgroundBetweenRangeUpdatePeriod(long p) {
backgroundBetweenRangeUpdatePeriod = p;
}

public void setForegroundRangeUpdatePeriod(long p) {
foregroundRangeUpdatePeriod = p;
}

public void setForegroundBetweenRangeUpdatePeriod(long p) {
foregroundBetweenRangeUpdatePeriod = p;
}


/**
* Set region exit period in milliseconds
*
Expand Down Expand Up @@ -617,7 +653,13 @@ public void startRangingBeaconsInRegion(Region region) throws RemoteException {
throw new RemoteException("The BeaconManager is not bound to the service. Call beaconManager.bind(BeaconConsumer consumer) and wait for a callback to onBeaconServiceConnect()");
}
Message msg = Message.obtain(null, BeaconService.MSG_START_RANGING, 0, 0);
StartRMData obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
StartRMData obj;
if (this.isRangeUpdateMidCycle()) {
obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode, this.getRangeUpdatePeriod(), this.getBetweenRangeUpdatePeriod());
}
else {
obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
}
msg.obj = obj;
serviceMessenger.send(msg);
synchronized (rangedRegions) {
Expand Down Expand Up @@ -645,7 +687,13 @@ public void stopRangingBeaconsInRegion(Region region) throws RemoteException {
throw new RemoteException("The BeaconManager is not bound to the service. Call beaconManager.bind(BeaconConsumer consumer) and wait for a callback to onBeaconServiceConnect()");
}
Message msg = Message.obtain(null, BeaconService.MSG_STOP_RANGING, 0, 0);
StartRMData obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
StartRMData obj;
if (this.isRangeUpdateMidCycle()) {
obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode, this.getRangeUpdatePeriod(), this.getBetweenRangeUpdatePeriod());
}
else {
obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
}
msg.obj = obj;
serviceMessenger.send(msg);
synchronized (rangedRegions) {
Expand Down Expand Up @@ -681,7 +729,7 @@ public void startMonitoringBeaconsInRegion(Region region) throws RemoteException
}
LogManager.d(TAG, "Starting monitoring region "+region+" with uniqueID: "+region.getUniqueId());
Message msg = Message.obtain(null, BeaconService.MSG_START_MONITORING, 0, 0);
StartRMData obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
StartRMData obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode, this.getRangeUpdatePeriod(), this.getBetweenRangeUpdatePeriod());
msg.obj = obj;
serviceMessenger.send(msg);
this.requestStateForRegion(region);
Expand All @@ -708,7 +756,13 @@ public void stopMonitoringBeaconsInRegion(Region region) throws RemoteException
throw new RemoteException("The BeaconManager is not bound to the service. Call beaconManager.bind(BeaconConsumer consumer) and wait for a callback to onBeaconServiceConnect()");
}
Message msg = Message.obtain(null, BeaconService.MSG_STOP_MONITORING, 0, 0);
StartRMData obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
StartRMData obj;
if (this.isRangeUpdateMidCycle()) {
obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode, this.getRangeUpdatePeriod(), this.getBetweenRangeUpdatePeriod());
}
else {
obj = new StartRMData(region, callbackPackageName(), this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
}
msg.obj = obj;
serviceMessenger.send(msg);
}
Expand All @@ -732,7 +786,14 @@ public void updateScanPeriods() throws RemoteException {
Message msg = Message.obtain(null, BeaconService.MSG_SET_SCAN_PERIODS, 0, 0);
LogManager.d(TAG, "updating background flag to %s", mBackgroundMode);
LogManager.d(TAG, "updating scan period to %s, %s", this.getScanPeriod(), this.getBetweenScanPeriod());
StartRMData obj = new StartRMData(this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
StartRMData obj;
if (this.isRangeUpdateMidCycle()) {
obj = new StartRMData(this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode, this.getRangeUpdatePeriod(), this.getBetweenRangeUpdatePeriod());
}
else
{
obj = new StartRMData(this.getScanPeriod(), this.getBetweenScanPeriod(), this.mBackgroundMode);
}
msg.obj = obj;
serviceMessenger.send(msg);
}
Expand Down Expand Up @@ -912,6 +973,33 @@ private long getBetweenScanPeriod() {
}
}

private boolean isRangeUpdateMidCycle() {
if(mBackgroundMode) {
return backgroundRangeMidScan;
}
else {
return foregroundRangeMidScan;
}
}

private long getRangeUpdatePeriod() {
if(mBackgroundMode) {
return backgroundRangeUpdatePeriod;
}
else {
return foregroundRangeUpdatePeriod;
}
}

private long getBetweenRangeUpdatePeriod() {
if(mBackgroundMode) {
return backgroundBetweenRangeUpdatePeriod;
}
else {
return foregroundBetweenRangeUpdatePeriod;
}
}

private void verifyServiceDeclaration() {
final PackageManager packageManager = mContext.getPackageManager();
final Intent intent = new Intent(mContext, BeaconService.class);
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/org/altbeacon/beacon/service/BeaconService.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,25 +155,40 @@ public void handleMessage(Message msg) {
LogManager.i(TAG, "start ranging received");
service.startRangingBeaconsInRegion(startRMData.getRegionData(), new org.altbeacon.beacon.service.Callback(startRMData.getCallbackPackageName()));
service.setScanPeriods(startRMData.getScanPeriod(), startRMData.getBetweenScanPeriod(), startRMData.getBackgroundFlag());
if(startRMData.hasMidCycleRangeUpdates()) {
service.setRangeUpdatePeriods(startRMData.getRangeUpdatePeriod(), startRMData.getBetweenRangeUpdatePeriod());
}
break;
case MSG_STOP_RANGING:
LogManager.i(TAG, "stop ranging received");
service.stopRangingBeaconsInRegion(startRMData.getRegionData());
service.setScanPeriods(startRMData.getScanPeriod(), startRMData.getBetweenScanPeriod(), startRMData.getBackgroundFlag());
if(startRMData.hasMidCycleRangeUpdates()) {
service.setRangeUpdatePeriods(startRMData.getRangeUpdatePeriod(), startRMData.getBetweenRangeUpdatePeriod());
}
break;
case MSG_START_MONITORING:
LogManager.i(TAG, "start monitoring received");
service.startMonitoringBeaconsInRegion(startRMData.getRegionData(), new org.altbeacon.beacon.service.Callback(startRMData.getCallbackPackageName()));
service.setScanPeriods(startRMData.getScanPeriod(), startRMData.getBetweenScanPeriod(), startRMData.getBackgroundFlag());
if(startRMData.hasMidCycleRangeUpdates()) {
service.setRangeUpdatePeriods(startRMData.getRangeUpdatePeriod(), startRMData.getBetweenRangeUpdatePeriod());
}
break;
case MSG_STOP_MONITORING:
LogManager.i(TAG, "stop monitoring received");
service.stopMonitoringBeaconsInRegion(startRMData.getRegionData());
service.setScanPeriods(startRMData.getScanPeriod(), startRMData.getBetweenScanPeriod(), startRMData.getBackgroundFlag());
if(startRMData.hasMidCycleRangeUpdates()) {
service.setRangeUpdatePeriods(startRMData.getRangeUpdatePeriod(), startRMData.getBetweenRangeUpdatePeriod());
}
break;
case MSG_SET_SCAN_PERIODS:
LogManager.i(TAG, "set scan intervals received");
service.setScanPeriods(startRMData.getScanPeriod(), startRMData.getBetweenScanPeriod(), startRMData.getBackgroundFlag());
if(startRMData.hasMidCycleRangeUpdates()) {
service.setRangeUpdatePeriods(startRMData.getRangeUpdatePeriod(), startRMData.getBetweenRangeUpdatePeriod());
}
break;
default:
super.handleMessage(msg);
Expand Down Expand Up @@ -343,6 +358,10 @@ public void setScanPeriods(long scanPeriod, long betweenScanPeriod, boolean back
mCycledScanner.setScanPeriods(scanPeriod, betweenScanPeriod, backgroundFlag);
}

public void setRangeUpdatePeriods(long rangeUpdatePeriod, long betweenRangeUpdatePeriod) {
mCycledScanner.setRangeUpdatePeriods(rangeUpdatePeriod, betweenRangeUpdatePeriod);
}

protected final CycledLeScanCallback mCycledLeScanCallback = new CycledLeScanCallback() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
Expand All @@ -358,6 +377,11 @@ public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
}
}

@Override
public void onMidScanRange() {
processRangeData();
}

@Override
public void onCycleEnd() {
monitoringStatus.updateNewlyOutside();
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/org/altbeacon/beacon/service/StartRMData.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,34 @@ public class StartRMData implements Serializable, Parcelable {
private Region region;
private long scanPeriod;
private long betweenScanPeriod;
private boolean hasMidCycleRangUpdate;
private long rangeUpdatePeriod;
private long betweenRangeUpdatePeriod;
private boolean backgroundFlag;
private String callbackPackageName;

public StartRMData(Region region, String callbackPackageName) {
this.region = region;
this.callbackPackageName = callbackPackageName;

this.hasMidCycleRangUpdate = false;
}
public StartRMData(long scanPeriod, long betweenScanPeriod, boolean backgroundFlag) {
this.scanPeriod = scanPeriod;
this.betweenScanPeriod = betweenScanPeriod;
this.backgroundFlag = backgroundFlag;

this.hasMidCycleRangUpdate = false;
}

public StartRMData(long scanPeriod, long betweenScanPeriod, boolean backgroundFlag, long rangeUpdatePeriod, long betweenRangeUpdatePeriod) {
this.scanPeriod = scanPeriod;
this.betweenScanPeriod = betweenScanPeriod;
this.backgroundFlag = backgroundFlag;

this.hasMidCycleRangUpdate = true;
this.rangeUpdatePeriod = rangeUpdatePeriod;
this.betweenRangeUpdatePeriod = betweenRangeUpdatePeriod;
}

public StartRMData(Region region, String callbackPackageName, long scanPeriod, long betweenScanPeriod, boolean backgroundFlag) {
Expand All @@ -53,11 +70,29 @@ public StartRMData(Region region, String callbackPackageName, long scanPeriod, l
this.region = region;
this.callbackPackageName = callbackPackageName;
this.backgroundFlag = backgroundFlag;

this.hasMidCycleRangUpdate = false;
}

public StartRMData(Region region, String callbackPackageName, long scanPeriod, long betweenScanPeriod, boolean backgroundFlag, long rangeUpdatePeriod, long betweenRangeUpdatePeriod) {
this.scanPeriod = scanPeriod;
this.betweenScanPeriod = betweenScanPeriod;
this.region = region;
this.callbackPackageName = callbackPackageName;
this.backgroundFlag = backgroundFlag;

this.hasMidCycleRangUpdate = true;
this.rangeUpdatePeriod = rangeUpdatePeriod;
this.betweenRangeUpdatePeriod = betweenRangeUpdatePeriod;
}



public long getScanPeriod() { return scanPeriod; }
public long getBetweenScanPeriod() { return betweenScanPeriod; }
public boolean hasMidCycleRangeUpdates() { return hasMidCycleRangUpdate; }
public long getRangeUpdatePeriod() { return rangeUpdatePeriod; }
public long getBetweenRangeUpdatePeriod() {return betweenRangeUpdatePeriod;}
public Region getRegionData() {
return region;
}
Expand All @@ -75,6 +110,9 @@ public void writeToParcel(Parcel out, int flags) {
out.writeLong(scanPeriod);
out.writeLong(betweenScanPeriod);
out.writeByte((byte) (backgroundFlag ? 1 : 0));
out.writeByte((byte) (hasMidCycleRangUpdate ? 1 : 0));
out.writeLong(rangeUpdatePeriod);
out.writeLong(betweenRangeUpdatePeriod);
}

public static final Parcelable.Creator<StartRMData> CREATOR
Expand All @@ -94,6 +132,9 @@ private StartRMData(Parcel in) {
scanPeriod = in.readLong();
betweenScanPeriod = in.readLong();
backgroundFlag = in.readByte() != 0;
hasMidCycleRangUpdate = in.readByte() != 0;
rangeUpdatePeriod = in.readLong();
betweenRangeUpdatePeriod = in.readLong();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
public interface CycledLeScanCallback {
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord);
public void onCycleEnd();
public void onMidScanRange();
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ public abstract class CycledLeScanner {
private long mScanCycleStopTime = 0l;
private long mLastScanStopTime = 0l;

private boolean mIsMidScanRangeUpdate = false;
private long mRangeCycleUpdateTime = 0l;

private boolean mScanning;
protected boolean mScanningPaused;
private boolean mScanCyclerStarted = false;
private boolean mScanningEnabled = false;
protected final Context mContext;
private long mScanPeriod;
private long mMidScanRangeUpdatePeriod;

protected long mBetweenScanPeriod;

Expand Down Expand Up @@ -96,6 +100,11 @@ public static CycledLeScanner createScanner(Context context, long scanPeriod, lo

}

public void setRangeUpdatePeriods(long rangeUpdatePeriod, long betweenRangeUpdate) {
mMidScanRangeUpdatePeriod = rangeUpdatePeriod;
mIsMidScanRangeUpdate = true;
}

/**
* Tells the cycler the scan rate and whether it is in operating in background mode.
* Background mode flag is used only with the Android 5.0 scanning implementations to switch
Expand Down Expand Up @@ -226,7 +235,11 @@ protected void scanLeDevice(final Boolean enable) {
LogManager.d(TAG, "We are already scanning");
}
mScanCycleStopTime = (SystemClock.elapsedRealtime() + mScanPeriod);
mRangeCycleUpdateTime = (SystemClock.elapsedRealtime() + mMidScanRangeUpdatePeriod);
scheduleScanCycleStop();
if(mIsMidScanRangeUpdate == true) {
scheduleCycleRangeUpdate();
}

LogManager.d(TAG, "Scan started");
} else {
Expand All @@ -242,7 +255,26 @@ protected void scanLeDevice(final Boolean enable) {
}
}

protected void scheduleCycleRangeUpdate() {
//Update Range after a pre-defined update period.
long milliscondsUntilRangeUpdate = mRangeCycleUpdateTime - SystemClock.elapsedRealtime();
if(milliscondsUntilRangeUpdate > 0 ) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
scheduleCycleRangeUpdate();
}
}, milliscondsUntilRangeUpdate > 1000 ? 1000 : milliscondsUntilRangeUpdate);
}
else {
mCycledLeScanCallback.onMidScanRange();
mRangeCycleUpdateTime = (SystemClock.elapsedRealtime() + mMidScanRangeUpdatePeriod);
scheduleCycleRangeUpdate();
}
}

protected void scheduleScanCycleStop() {

// Stops scanning after a pre-defined scan period.
long millisecondsUntilStop = mScanCycleStopTime - SystemClock.elapsedRealtime();
if (millisecondsUntilStop > 0) {
Expand Down