Skip to content

Commit

Permalink
added: disable advertising (#3)
Browse files Browse the repository at this point in the history
* added: configuration to disable advertising

* prevent R8 minification to class disable and enable
  • Loading branch information
Mochamad Noor Syamsu authored Mar 30, 2022
1 parent 494e628 commit a190d6c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 46 deletions.
54 changes: 26 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Android Hypertrace - Kotlin implementation of OpenTrace by Hyperjump

Kotlin OpenTrace implementation based on [BlueTrace specification](https://bluetrace.io/static/bluetrace_whitepaper-938063656596c104632def383eb33b3c.pdf).
Kotlin OpenTrace implementation based on [BlueTrace specification](https://bluetrace.io/static/bluetrace_whitepaper-938063656596c104632def383eb33b3c.pdf). Example app is available in [example module](https://github.com/hyperjumptech/hypertrace-android-sdk/tree/main/example/src/main).

### Table of Content

Expand Down Expand Up @@ -66,32 +66,31 @@ HypertraceSdk.startService(config)

##### Available configuration

| Field | Type | Description | Mandatory | Default |
| :--------------------------------- | :------------------- | :------------------------------------------------------------------------------------------------------------------------------ | :-------- | :------------ |
| notificationChannelCreator | Function | Kotlin higher-order function for SDK to create android notification channel. (Required for API level 26 / Android O). | **YES** | - |
| foregroundNotificationCreator | Function | Kotlin higher-order function for SDK to create notification when service is actively running. | **YES** | - |
| bluetoothFailedNotificationCreator | Function | Kotlin higher-order function for SDK to create notification when service fails to access bluetooth and location permissions. | **YES** | - |
| userId | string | Main application's user ID. **Must be** 21 characters. | **YES** | - |
| organization | string | Application's organization name. Typically, this is a combination of `COUNTRY_CODE` and short organization name. | **YES** | - |
| baseUrl | string | URL for [Hypertrace server](https://github.com/hyperjumptech/hypertrace) implementation. **Must end** with slash `/` character. | **YES** | - |
| bleServiceUuid | string | BLE service UUID. **Must be** a valid UUID. | **YES** | - |
| bleCharacteristicUuid | string | BLE characteristic UUID. **Must be** a valid UUID. | **YES** | - |
| debug | boolean | Enable showing street pass list and bluetooth scanning activity | **NO** | - |
| keepAliveService | boolean | If `true`, Hypertrace will try to restart service everytime it is killed. | **NO** | `false` |
| scanDuration | long | Duration of each bluetooth scan action in **miliseconds.** Default to 10 seconds. | **NO** | 10_000 |
| minScanInterval | long | Minimum scan interval in **miliseconds.** Randomized between minScanInterval and maxScanInterval. Default to 30 seconds. | **NO** | 30_000 |
| maxScanInterval | long | Maximum scan interval in **miliseconds.** Randomized between minScanInterval and maxScanInterval. Default to 40 seconds. | **NO** | 40_000 |
| advertisingDuration | long | Duration of each bluetooth advertising action in **miliseconds.** Default to 30 minutes. | **NO** | 180_000 |
| advertisingInterval | long | Interval between bluetooth advertising action in **miliseconds.** Default to 6 seconds. | **NO** | 6_000 |
| purgeRecordInterval | long | Interval between purge action of encounter's records in **miliseconds.** Default to 24 hours. | **NO** | 86_400_000 |
| recordTTL | long | The lifetime of encounter's records in **miliseconds.** Default to 21 days. | **NO** | 1_814_400_000 |
| maxPeripheralQueueTime | long | Maximum time of a peripheral to wait to be processed in **miliseconds.** Default to 10 seconds. | **NO** | 10_000 |
| deviceConnectionTimeout | long | Maximum time of a peripheral read-write action in **miliseconds.** Default to 6 seconds. | **NO** | 6_000 |
| deviceBlacklistDuration | long | Maximum time of a device to be blacklisted time in **miliseconds.** Default to 1.5 minutes. | **NO** | 90_000 |
| temporaryIdCheckInterval | long | Interval between temporary IDs' supply check **miliseconds.** Default to 10 minutes. | **NO** | 600_000 |
| bluetoothServiceHeartBeat | long | Interval between OpenTrace bluetooth service check **miliseconds.** Default to 15 minutes. | **NO** | 900_000 |
| certificatePinner | CertificatePinner | Helper for certificate pinning provided by OkHttp. See [**Security Enhancements.**](#security-enhancements) | **NO** | null |
| okHttpConfig | OkHttpClient.Builder | For a complete control of SDK's OkHttpClient. | **NO** | null |
| Field | Type | Description | Mandatory | Default |
| :--------------------------------- | :------------------- | :------------------------------------------------------------------------------------------------------------------------------ | :-------- | :--------------------------------------------------------- |
| notificationChannelCreator | Function | Kotlin higher-order function for SDK to create android notification channel. (Required for API level 26 / Android O). | **YES** | - |
| foregroundNotificationCreator | Function | Kotlin higher-order function for SDK to create notification when service is actively running. | **YES** | - |
| bluetoothFailedNotificationCreator | Function | Kotlin higher-order function for SDK to create notification when service fails to access bluetooth and location permissions. | **YES** | - |
| userId | string | Main application's user ID. **Must be** 21 characters. | **YES** | - |
| organization | string | Application's organization name. Typically, this is a combination of `COUNTRY_CODE` and short organization name. | **YES** | - |
| baseUrl | string | URL for [Hypertrace server](https://github.com/hyperjumptech/hypertrace) implementation. **Must end** with slash `/` character. | **YES** | - |
| bleServiceUuid | string | BLE service UUID. **Must be** a valid UUID. | **YES** | - |
| bleCharacteristicUuid | string | BLE characteristic UUID. **Must be** a valid UUID. | **YES** | - |
| debug | boolean | Enable showing street pass list and bluetooth scanning activity | **NO** | - |
| keepAliveService | boolean | If `true`, Hypertrace will try to restart service everytime it is killed. | **NO** | `false` |
| scanDuration | long | Duration of each bluetooth scan action in **miliseconds.** Default to 10 seconds. | **NO** | 10_000 |
| minScanInterval | long | Minimum scan interval in **miliseconds.** Randomized between minScanInterval and maxScanInterval. Default to 30 seconds. | **NO** | 30_000 |
| maxScanInterval | long | Maximum scan interval in **miliseconds.** Randomized between minScanInterval and maxScanInterval. Default to 40 seconds. | **NO** | 40_000 |
| advertising | Config.Advertising | Hypertrace configuration for advertising's duration and interval. Default to `Advertising.Enable` | **NO** | `Advertising.Enable(duration = 180_000, interval = 6_000)` |
| purgeRecordInterval | long | Interval between purge action of encounter's records in **miliseconds.** Default to 24 hours. | **NO** | 86_400_000 |
| recordTTL | long | The lifetime of encounter's records in **miliseconds.** Default to 21 days. | **NO** | 1_814_400_000 |
| maxPeripheralQueueTime | long | Maximum time of a peripheral to wait to be processed in **miliseconds.** Default to 10 seconds. | **NO** | 10_000 |
| deviceConnectionTimeout | long | Maximum time of a peripheral read-write action in **miliseconds.** Default to 6 seconds. | **NO** | 6_000 |
| deviceBlacklistDuration | long | Maximum time of a device to be blacklisted time in **miliseconds.** Default to 1.5 minutes. | **NO** | 90_000 |
| temporaryIdCheckInterval | long | Interval between temporary IDs' supply check **miliseconds.** Default to 10 minutes. | **NO** | 600_000 |
| bluetoothServiceHeartBeat | long | Interval between OpenTrace bluetooth service check **miliseconds.** Default to 15 minutes. | **NO** | 900_000 |
| certificatePinner | CertificatePinner | Helper for certificate pinning provided by OkHttp. See [**Security Enhancements.**](#security-enhancements) | **NO** | null |
| okHttpConfig | OkHttpClient.Builder | For a complete control of SDK's OkHttpClient. | **NO** | null |

#### Stop background service

Expand Down Expand Up @@ -185,4 +184,3 @@ For more information visit [https://android-developers.googleblog.com/2020/04/go
**0.9.0**

- First release.

3 changes: 2 additions & 1 deletion example/src/main/java/tech/hyperjump/example/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import androidx.core.app.NotificationChannelCompat
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.lifecycle.lifecycleScope
import io.bluetrace.opentrace.streetpassdebug.StreetPassDebugActivity
import kotlinx.android.synthetic.main.activity_main.*
import pub.devrel.easypermissions.EasyPermissions
import tech.hyperjump.hypertrace.HyperTraceSdk
import tech.hyperjump.hypertrace.scandebug.ScanDebugActivity
import io.bluetrace.opentrace.streetpassdebug.StreetPassDebugActivity
import java.security.SecureRandom
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
Expand Down Expand Up @@ -121,6 +121,7 @@ class MainActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {
}

private fun buildConfig(): HyperTraceSdk.Config {
// hypertrace server requires uid to be 21 character length
userId = generateUserId(21)
// FIXME change to hypertrace server implementation
val baseUrl = "https://192.108.0.0/"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ import io.bluetrace.opentrace.bluetooth.gatt.STREET_PASS
import io.bluetrace.opentrace.idmanager.TempIDManager
import io.bluetrace.opentrace.idmanager.TemporaryID
import io.bluetrace.opentrace.logging.CentralLog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import pub.devrel.easypermissions.EasyPermissions
import tech.hyperjump.hypertrace.*
import io.bluetrace.opentrace.status.Status
import io.bluetrace.opentrace.status.persistence.StatusRecord
import io.bluetrace.opentrace.status.persistence.StatusRecordStorage
Expand All @@ -36,6 +30,14 @@ import io.bluetrace.opentrace.streetpass.StreetPassServer
import io.bluetrace.opentrace.streetpass.StreetPassWorker
import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecord
import io.bluetrace.opentrace.streetpass.persistence.StreetPassRecordStorage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import pub.devrel.easypermissions.EasyPermissions
import tech.hyperjump.hypertrace.BuildConfig
import tech.hyperjump.hypertrace.HyperTraceSdk
import tech.hyperjump.hypertrace.R
import java.lang.ref.WeakReference
import kotlin.coroutines.CoroutineContext

Expand Down Expand Up @@ -325,7 +327,10 @@ class BluetoothMonitoringService : Service(), CoroutineScope {
private fun actionAdvertise() {
setupAdvertiser()
if (isBluetoothEnabled()) {
advertiser?.startAdvertising(advertisingDuration)
val duration = HyperTraceSdk.CONFIG.advertising.let {
if (it is HyperTraceSdk.Config.Advertising.Enable) it.duration else 0
}
advertiser?.startAdvertising(duration)
} else {
CentralLog.w(TAG, "Unable to start advertising, bluetooth is off")
}
Expand Down Expand Up @@ -357,6 +362,8 @@ class BluetoothMonitoringService : Service(), CoroutineScope {
}

private fun setupAdvertisingCycles() {
// ignore if disabled
if (HyperTraceSdk.CONFIG.advertising is HyperTraceSdk.Config.Advertising.Disable) return
commandHandler.scheduleNextAdvertise(0)
}

Expand All @@ -377,8 +384,12 @@ class BluetoothMonitoringService : Service(), CoroutineScope {
}

private fun scheduleAdvertisement() {
if (!infiniteAdvertising) {
commandHandler.scheduleNextAdvertise(advertisingDuration + advertisingGap)
// ignore if disabled
if (HyperTraceSdk.CONFIG.advertising is HyperTraceSdk.Config.Advertising.Disable) return
val advertisingConfig = HyperTraceSdk.CONFIG.advertising
if (!infiniteAdvertising && advertisingConfig is HyperTraceSdk.Config.Advertising.Enable) {
val delay = advertisingConfig.duration + advertisingConfig.interval
commandHandler.scheduleNextAdvertise(delay)
}
}

Expand Down Expand Up @@ -429,6 +440,8 @@ class BluetoothMonitoringService : Service(), CoroutineScope {
}

if (!infiniteAdvertising) {
// ignore if disabled
if (HyperTraceSdk.CONFIG.advertising is HyperTraceSdk.Config.Advertising.Disable) return
if (!commandHandler.hasAdvertiseScheduled()) {
CentralLog.w(TAG, "Missing Advertise Schedule - rectifying")
// setupAdvertisingCycles()
Expand Down Expand Up @@ -637,14 +650,10 @@ class BluetoothMonitoringService : Service(), CoroutineScope {

var broadcastMessage: TemporaryID? = null

//should be more than advertising gap?
//should be more than advertising interval
val scanDuration: Long = HyperTraceSdk.CONFIG.scanDuration
val minScanInterval: Long = HyperTraceSdk.CONFIG.minScanInterval
val maxScanInterval: Long = HyperTraceSdk.CONFIG.maxScanInterval

val advertisingDuration: Long = HyperTraceSdk.CONFIG.advertisingDuration
val advertisingGap: Long = HyperTraceSdk.CONFIG.advertisingInterval

val maxQueueTime: Long = HyperTraceSdk.CONFIG.maxPeripheralQueueTime
val bmCheckInterval: Long = HyperTraceSdk.CONFIG.temporaryIdCheckInterval
val healthCheckInterval: Long = HyperTraceSdk.CONFIG.bluetoothServiceHeartBeat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,10 @@ object HyperTraceSdk {
val scanDuration: Long = 10_000,
val minScanInterval: Long = 30_000,
val maxScanInterval: Long = 40_000,
val advertisingDuration: Long = 180_000, // 30 minutes
val advertisingInterval: Long = 6_000,
val advertising: Advertising = Advertising.Enable(
duration = 180_000, // 30 minutes
interval = 6_000,
),
val purgeRecordInterval: Long = 86_400_000, // 24 hours
val recordTTL: Long = 1_814_400_000, // 21 days
val maxPeripheralQueueTime: Long = 10_000,
Expand All @@ -144,8 +146,16 @@ object HyperTraceSdk {
val okHttpConfig: (OkHttpClient.Builder.() -> Unit)? = null
) {

sealed class Advertising {

@Keep
object Disable : Advertising()

@Keep
class Enable(val duration: Long, val interval: Long) : Advertising()
}

fun validateConfig() {
if (userId.length < 21) throw Exception("User ID must have exactly 21 characters.")
if (organization.isEmpty()) throw Exception("Organization Code cannot be empty.")
if (baseUrl.isEmpty()) throw Exception("Base URL cannot be empty.")
if (baseUrl.last() != '/') throw Exception("Base URL must end with slash '/'.")
Expand Down

0 comments on commit a190d6c

Please sign in to comment.