From 773f6822cae99d13b73c75f6605dee6ee25d8543 Mon Sep 17 00:00:00 2001 From: Alexander Heinrich Date: Tue, 8 Mar 2022 14:46:47 +0100 Subject: [PATCH 01/15] Detecting a tile device --- .../database/models/device/DeviceManager.kt | 49 +++++++++---------- .../database/models/device/types/Tile.kt | 38 ++------------ fastlane/Fastfile | 6 +++ 3 files changed, 34 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt index 21d45a67..9b76a9c5 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt @@ -3,7 +3,6 @@ package de.seemoo.at_tracking_detection.database.models.device import android.bluetooth.le.ScanFilter import android.bluetooth.le.ScanResult import android.content.IntentFilter -import android.util.Log import de.seemoo.at_tracking_detection.database.models.device.types.* import de.seemoo.at_tracking_detection.util.ble.BluetoothConstants import timber.log.Timber @@ -15,35 +14,33 @@ object DeviceManager { fun getDeviceType(scanResult: ScanResult): DeviceType { Timber.d("Checking device type for ${scanResult.device.address}") - val manufacturerData = scanResult.scanRecord?.getManufacturerSpecificData(0x004c) ?: return Unknown.deviceType - val statusByte: Byte = manufacturerData[2] - Timber.d("Status byte $statusByte, ${statusByte.toString(2)}") - // Get the correct int from the byte - val deviceTypeInt = (statusByte.and(0x30).toInt() shr 4) - Timber.d("Device type int: $deviceTypeInt") - var deviceTypeFilter: DeviceType? = null - var deviceTypeCheck: DeviceType? = null - - for (device in devices) { - // Implementation of device detection is incorrect. - - if (device.bluetoothFilter.matches(scanResult)) { - deviceTypeFilter = device.deviceType + val manufacturerData = scanResult.scanRecord?.getManufacturerSpecificData(0x004c) + val services = scanResult.scanRecord?.serviceUuids + if (manufacturerData != null) { + val statusByte: Byte = manufacturerData[2] +// Timber.d("Status byte $statusByte, ${statusByte.toString(2)}") + // Get the correct int from the byte + val deviceTypeInt = (statusByte.and(0x30).toInt() shr 4) +// Timber.d("Device type int: $deviceTypeInt") + + var deviceTypeCheck: DeviceType? = null + + for (device in devices) { + // Implementation of device detection is incorrect. + if (device.statusByteDeviceType == deviceTypeInt.toUInt()) { + deviceTypeCheck = device.deviceType + } } - if (device.statusByteDeviceType == deviceTypeInt.toUInt()) { - deviceTypeCheck = device.deviceType - } - } - if (deviceTypeCheck != deviceTypeFilter) { - Timber.d("Different device types detected: Check $deviceTypeCheck filter: $deviceTypeFilter") + return deviceTypeCheck ?: Unknown.deviceType + }else if (services != null) { + //Check if this device is a Tile + if (services.contains(Tile.offlineFindingServiceUUID)) { + return Tile.deviceType + } } - - val result = deviceTypeCheck ?: deviceTypeFilter ?: Unknown.deviceType - - Timber.d("Result device check: $result") - return result + return Unknown.deviceType } val scanFilter: List = devices.map { it.bluetoothFilter } diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt index cd1365a6..94afd7fa 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt @@ -4,6 +4,7 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCallback import android.bluetooth.BluetoothGattCharacteristic import android.bluetooth.le.ScanFilter +import android.os.ParcelUuid import androidx.annotation.DrawableRes import de.seemoo.at_tracking_detection.ATTrackingDetectionApplication import de.seemoo.at_tracking_detection.R @@ -14,7 +15,7 @@ import de.seemoo.at_tracking_detection.database.models.device.DeviceType import de.seemoo.at_tracking_detection.util.ble.BluetoothConstants import timber.log.Timber -class Tile(val id: Int) : Device(), Connectable { +class Tile(val id: Int) : Device(){ override val imageResource: Int @DrawableRes get() = R.drawable.ic_baseline_device_unknown_24 @@ -26,41 +27,10 @@ class Tile(val id: Int) : Device(), Connectable { override val deviceContext: DeviceContext get() = Tile - override val bluetoothGattCallback: BluetoothGattCallback - get() = object : BluetoothGattCallback() { - override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { - when (status) { - BluetoothGatt.GATT_SUCCESS -> { - when (newState) { - else -> { - Timber.d("Connection state changed to $newState") - } - } - } - else -> { - Timber.e("Failed to connect to bluetooth device! Status: $status") - broadcastUpdate(BluetoothConstants.ACTION_EVENT_FAILED) - } - } - } - - override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { - super.onServicesDiscovered(gatt, status) - } - - override fun onCharacteristicRead( - gatt: BluetoothGatt?, - characteristic: BluetoothGattCharacteristic?, - status: Int - ) { - - } - } - companion object : DeviceContext { // TODO: Implement scan filter for tile override val bluetoothFilter: ScanFilter - get() = ScanFilter.Builder().setDeviceAddress("FF:FF:FF:FF:FF:FF").build() + get() = ScanFilter.Builder().setServiceUuid(offlineFindingServiceUUID).build() override val deviceType: DeviceType get() = DeviceType.TILE @@ -70,5 +40,7 @@ class Tile(val id: Int) : Device(), Connectable { override val statusByteDeviceType: UInt get() = 0u + + val offlineFindingServiceUUID: ParcelUuid = ParcelUuid.fromString("FEED") } } \ No newline at end of file diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 19c557cc..2515af37 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -35,4 +35,10 @@ platform :android do gradle(task: "clean assembleRelease") upload_to_play_store end + + desc "Fetch Screenshots and metadata from Google Play" + lane :update_metadta do + download_from_play_store + end + end From 2eb7f9fb0e57f6f6afb5375ae4d584faa0a7dec4 Mon Sep 17 00:00:00 2001 From: Alexander Heinrich Date: Fri, 11 Mar 2022 13:46:57 +0100 Subject: [PATCH 02/15] Adding UUIDs to the beacons --- .../database/AppDatabase.kt | 2 +- .../database/Converters.kt | 17 +++++++++++++++++ .../database/models/Beacon.kt | 12 ++++++++---- .../detection/ScanBluetoothWorker.kt | 5 +++-- 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt index 6e1272ef..71859a3c 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt @@ -20,7 +20,7 @@ import de.seemoo.at_tracking_detection.util.converter.DateTimeConverter autoMigrations = [AutoMigration(from = 2, to = 3), AutoMigration(from = 3, to = 4), AutoMigration(from = 4, to = 5)], exportSchema = true ) -@TypeConverters(DateTimeConverter::class) +@TypeConverters(Converters::class, DateTimeConverter::class) abstract class AppDatabase : RoomDatabase() { abstract fun deviceDao(): DeviceDao diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt new file mode 100644 index 00000000..5756e0fc --- /dev/null +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt @@ -0,0 +1,17 @@ +package de.seemoo.at_tracking_detection.database + +import androidx.room.TypeConverter +import java.time.LocalDateTime + +class Converters { + + @TypeConverter + fun fromStringToList(value: String): List { + return value.split(";") + } + + @TypeConverter + fun toStringFromList(list: List): String { + return list.joinToString(";") + } +} \ No newline at end of file diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt index 647459bb..0dd9a4c1 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt @@ -4,13 +4,14 @@ import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey import androidx.room.TypeConverters +import de.seemoo.at_tracking_detection.database.Converters import de.seemoo.at_tracking_detection.util.converter.DateTimeConverter import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.time.format.FormatStyle @Entity(tableName = "beacon") -@TypeConverters(DateTimeConverter::class) +@TypeConverters(DateTimeConverter::class, Converters::class) data class Beacon( @PrimaryKey(autoGenerate = true) val beaconId: Int, @ColumnInfo(name = "receivedAt") val receivedAt: LocalDateTime, @@ -18,7 +19,8 @@ data class Beacon( @ColumnInfo(name = "deviceAddress") var deviceAddress: String, @ColumnInfo(name = "longitude") var longitude: Double?, @ColumnInfo(name = "latitude") var latitude: Double?, - @ColumnInfo(name = "mfg") var manufacturerData: ByteArray? + @ColumnInfo(name = "mfg") var manufacturerData: ByteArray?, + @ColumnInfo(name = "serviceUUIDs") var serviceUUIDs: List? ) { constructor( receivedAt: LocalDateTime, @@ -26,7 +28,8 @@ data class Beacon( deviceAddress: String, longitude: Double?, latitude: Double?, - mfg: ByteArray? + mfg: ByteArray?, + serviceUUIDs: List? ) : this( 0, receivedAt, @@ -34,7 +37,8 @@ data class Beacon( deviceAddress, longitude, latitude, - mfg + mfg, + serviceUUIDs ) fun getFormattedDate(): String = diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt b/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt index 18407e35..520b44ae 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt @@ -161,16 +161,17 @@ class ScanBluetoothWorker @AssistedInject constructor( Timber.d("Device: $device") + val uuids = scanResult.scanRecord?.serviceUuids?.map { it.toString() }?.toList() val beacon = if (BuildConfig.DEBUG) { // Save the manufacturer data to the beacon Beacon( discoveryDate, scanResult.rssi, scanResult.device.address, latitude, longitude, - scanResult.scanRecord?.bytes + scanResult.scanRecord?.bytes, uuids ) } else { Beacon( discoveryDate, scanResult.rssi, scanResult.device.address, latitude, longitude, - null + null, uuids ) } From a28784445901110510db96007318fe8d59195743 Mon Sep 17 00:00:00 2001 From: Alexander Heinrich Date: Fri, 11 Mar 2022 16:56:50 +0100 Subject: [PATCH 03/15] Handling database migration Part 1 --- .../de/seemoo/at_tracking_detection/database/AppDatabase.kt | 4 ++-- .../de/seemoo/at_tracking_detection/database/Converters.kt | 4 ++-- .../de/seemoo/at_tracking_detection/database/models/Beacon.kt | 2 +- .../database/models/device/BaseDevice.kt | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt index 71859a3c..85c69858 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/AppDatabase.kt @@ -15,9 +15,9 @@ import de.seemoo.at_tracking_detection.database.models.device.BaseDevice import de.seemoo.at_tracking_detection.util.converter.DateTimeConverter @Database( - version = 5, + version = 6, entities = [BaseDevice::class, Notification::class, Beacon::class, Feedback::class], - autoMigrations = [AutoMigration(from = 2, to = 3), AutoMigration(from = 3, to = 4), AutoMigration(from = 4, to = 5)], + autoMigrations = [AutoMigration(from = 2, to = 3), AutoMigration(from = 3, to = 4), AutoMigration(from = 4, to = 5), AutoMigration(from = 5, to = 6)], exportSchema = true ) @TypeConverters(Converters::class, DateTimeConverter::class) diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt index 5756e0fc..af12ec9c 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/Converters.kt @@ -11,7 +11,7 @@ class Converters { } @TypeConverter - fun toStringFromList(list: List): String { - return list.joinToString(";") + fun toStringFromList(list: List?): String { + return list?.joinToString(";") ?: "" } } \ No newline at end of file diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt index 0dd9a4c1..d8ec5fe9 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/Beacon.kt @@ -20,7 +20,7 @@ data class Beacon( @ColumnInfo(name = "longitude") var longitude: Double?, @ColumnInfo(name = "latitude") var latitude: Double?, @ColumnInfo(name = "mfg") var manufacturerData: ByteArray?, - @ColumnInfo(name = "serviceUUIDs") var serviceUUIDs: List? + @ColumnInfo(name = "serviceUUIDs", defaultValue = "null") var serviceUUIDs: List? ) { constructor( receivedAt: LocalDateTime, diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt index 9f41e5a8..0b275fbc 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt @@ -25,7 +25,7 @@ data class BaseDevice( @ColumnInfo(name = "lastSeen") var lastSeen: LocalDateTime, @ColumnInfo(name = "notificationSent") var notificationSent: Boolean, @ColumnInfo(name = "lastNotificationSent") var lastNotificationSent: LocalDateTime?, - @ColumnInfo(name = "deviceType", defaultValue = "null") val deviceType: DeviceType? + @ColumnInfo(name = "deviceType") val deviceType: DeviceType? ) { constructor( From a99d9c841c1d80ce4ddc6e2a154da4d78507d9bf Mon Sep 17 00:00:00 2001 From: Alexander Heinrich Date: Tue, 15 Mar 2022 08:38:28 +0100 Subject: [PATCH 04/15] Tile device discovery tested Manual scan with Tiles --- .../database/models/device/BaseDevice.kt | 1 + .../database/models/device/Device.kt | 4 ++++ .../database/models/device/DeviceManager.kt | 5 +++-- .../database/models/device/types/Tile.kt | 2 +- .../detection/TrackingDetectorWorker.kt | 1 + .../at_tracking_detection/util/BindingAdapter.kt | 12 ++++++++++++ app/src/main/res/layout/item_scan_result.xml | 2 +- 7 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt index 0b275fbc..1101cb7e 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/BaseDevice.kt @@ -82,6 +82,7 @@ data class BaseDevice( DeviceType.APPLE -> AppleDevice(deviceId) DeviceType.AIRPODS -> AirPods(deviceId) DeviceType.FIND_MY -> FindMy(deviceId) + DeviceType.TILE -> Tile(deviceId) else -> { // For backwards compatibility if (payloadData?.and(0x10)?.toInt() != 0 && connectable == true) { diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/Device.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/Device.kt index 104f8239..5b3afe4c 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/Device.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/Device.kt @@ -16,4 +16,8 @@ abstract class Device { val context = ATTrackingDetectionApplication.getAppContext() return AppCompatResources.getDrawable(context, imageResource) } + + fun isConnectable(): Boolean { + return this is Connectable + } } \ No newline at end of file diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt index 9b76a9c5..6e5b6539 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/DeviceManager.kt @@ -10,7 +10,8 @@ import kotlin.experimental.and object DeviceManager { - val devices = listOf(AirTag, FindMy, AirPods, AppleDevice) + val devices = listOf(AirTag, FindMy, AirPods, AppleDevice, Tile) + val appleDevices = listOf(AirTag, FindMy, AirPods, AppleDevice) fun getDeviceType(scanResult: ScanResult): DeviceType { Timber.d("Checking device type for ${scanResult.device.address}") @@ -26,7 +27,7 @@ object DeviceManager { var deviceTypeCheck: DeviceType? = null - for (device in devices) { + for (device in appleDevices) { // Implementation of device detection is incorrect. if (device.statusByteDeviceType == deviceTypeInt.toUInt()) { deviceTypeCheck = device.deviceType diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt index 94afd7fa..69c5b715 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/database/models/device/types/Tile.kt @@ -41,6 +41,6 @@ class Tile(val id: Int) : Device(){ override val statusByteDeviceType: UInt get() = 0u - val offlineFindingServiceUUID: ParcelUuid = ParcelUuid.fromString("FEED") + val offlineFindingServiceUUID: ParcelUuid = ParcelUuid.fromString("0000FEED-0000-1000-8000-00805F9B34FB") } } \ No newline at end of file diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt b/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt index 34a396a6..4e432c2b 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt @@ -43,6 +43,7 @@ class TrackingDetectorWorker @AssistedInject constructor( //TODO: Can we do this in parallel? cleanedBeaconsPerDevice.forEach { mapEntry -> + //TODO: Implement tracking detection for Tile val device = deviceRepository.getDevice(mapEntry.key) //Check that we found enough beacons diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/util/BindingAdapter.kt b/app/src/main/java/de/seemoo/at_tracking_detection/util/BindingAdapter.kt index accbee23..338d633d 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/util/BindingAdapter.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/util/BindingAdapter.kt @@ -1,6 +1,7 @@ package de.seemoo.at_tracking_detection.util import android.bluetooth.le.ScanResult +import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.databinding.BindingAdapter @@ -8,6 +9,7 @@ import androidx.preference.PreferenceManager import androidx.recyclerview.widget.RecyclerView import de.seemoo.at_tracking_detection.ATTrackingDetectionApplication import de.seemoo.at_tracking_detection.database.models.device.BaseDevice +import de.seemoo.at_tracking_detection.database.models.device.Connectable import de.seemoo.at_tracking_detection.database.models.device.Device import de.seemoo.at_tracking_detection.database.models.device.DeviceManager import java.util.* @@ -51,4 +53,14 @@ fun setDeviceDrawable(imageView: ImageView, scanResult: ScanResult) { fun setDeviceName(textView: TextView, scanResult: ScanResult) { val device = BaseDevice(scanResult).device textView.text = device.deviceContext.defaultDeviceName +} + +@BindingAdapter("hideWhenNoSoundPlayed", requireAll = true) +fun hideWhenNoSoundPlayed(view: View, scanResult: ScanResult) { + val device = BaseDevice(scanResult).device + if (device.isConnectable()) { + view.visibility = View.VISIBLE + }else { + view.visibility = View.GONE + } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_scan_result.xml b/app/src/main/res/layout/item_scan_result.xml index 86c4c804..1edc765e 100644 --- a/app/src/main/res/layout/item_scan_result.xml +++ b/app/src/main/res/layout/item_scan_result.xml @@ -128,11 +128,11 @@ android:layout_height="0dp" android:layout_marginVertical="12dp" android:src="@{@drawable/ic_baseline_play_circle_outline_24}" - android:visibility="@{!scanResult.isConnectable() ? View.GONE : View.VISIBLE}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toRightOf="@id/scan_result_guideline_right" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" + app:hideWhenNoSoundPlayed="@{scanResult}" tools:src="@drawable/ic_baseline_play_circle_outline_24" /> From aef09b74b8ba47a883b1ff3b31a2336aca8d43fb Mon Sep 17 00:00:00 2001 From: Niklas Bittner Date: Sat, 5 Mar 2022 17:39:24 +0100 Subject: [PATCH 05/15] restore previous changelogs --- fastlane/metadata/android/en-US/changelogs/15.txt | 1 + fastlane/metadata/android/en-US/changelogs/18.txt | 7 +++++++ fastlane/metadata/android/en-US/changelogs/19.txt | 12 ++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/15.txt create mode 100644 fastlane/metadata/android/en-US/changelogs/18.txt create mode 100644 fastlane/metadata/android/en-US/changelogs/19.txt diff --git a/fastlane/metadata/android/en-US/changelogs/15.txt b/fastlane/metadata/android/en-US/changelogs/15.txt new file mode 100644 index 00000000..4a9ca686 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/15.txt @@ -0,0 +1 @@ +Detect malicious trackers following you \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/18.txt b/fastlane/metadata/android/en-US/changelogs/18.txt new file mode 100644 index 00000000..26e3d8f3 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/18.txt @@ -0,0 +1,7 @@ +# Bug Fixes +- Manual scanning crashed when Bluetooth was disabled +- App froze when loading many beacons into the map + +# Misc +- Correct typos, clarified wording in strings.xml by @lazytownfan +- Correct minor typos and formatting in Privacy Policy by @lazytownfan \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/19.txt b/fastlane/metadata/android/en-US/changelogs/19.txt new file mode 100644 index 00000000..02d93d82 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/19.txt @@ -0,0 +1,12 @@ +# Features +- UI redesign +- Device list filter + +# Bug Fixes +- Crash when manually scanning and closing the view before the scan was complete +- Status bar color for m3 design was mismatched +- Onboarding crash + +# Misc +- Copyright overlay on OpenStreetMaps +- Text improvements \ No newline at end of file From 17fc9be35a2e5d0bc59644be433ff1e80a296ffb Mon Sep 17 00:00:00 2001 From: Niklas Bittner Date: Sat, 5 Mar 2022 17:49:14 +0100 Subject: [PATCH 06/15] show ignored icon in device list --- app/src/main/res/layout/item_device.xml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/item_device.xml b/app/src/main/res/layout/item_device.xml index fffa121f..a66f9c98 100644 --- a/app/src/main/res/layout/item_device.xml +++ b/app/src/main/res/layout/item_device.xml @@ -184,14 +184,27 @@ app:srcCompat="@drawable/ic_baseline_chevron_right_24" tools:ignore="ContentDescription" /> + + From 5087f7471b60909e57e8112b79fc83632033acf3 Mon Sep 17 00:00:00 2001 From: Alexander Heinrich Date: Fri, 11 Mar 2022 16:08:29 +0100 Subject: [PATCH 07/15] Fixing memory leaks due to BLE scanning --- app/build.gradle | 2 + .../detection/ScanBluetoothWorker.kt | 11 +++-- .../detection/TrackingDetectorWorker.kt | 1 + .../ui/debug/DebugFragment.kt | 16 +++++-- .../ui/scan/ScanFragment.kt | 13 +++--- .../seemoo/at_tracking_detection/util/Util.kt | 8 +++- .../util/ble/BLEScanCallback.kt | 42 +++++++++++++++++++ app/src/main/res/layout/fragment_debug.xml | 24 +++++++++-- 8 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/de/seemoo/at_tracking_detection/util/ble/BLEScanCallback.kt diff --git a/app/build.gradle b/app/build.gradle index e144135e..a71062ce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -117,4 +117,6 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' + + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1' } \ No newline at end of file diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt b/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt index 520b44ae..0619fadc 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/detection/ScanBluetoothWorker.kt @@ -22,6 +22,7 @@ import de.seemoo.at_tracking_detection.database.repository.BeaconRepository import de.seemoo.at_tracking_detection.database.repository.DeviceRepository import de.seemoo.at_tracking_detection.notifications.NotificationService import de.seemoo.at_tracking_detection.util.Util +import de.seemoo.at_tracking_detection.util.ble.BLEScanCallback import de.seemoo.at_tracking_detection.worker.BackgroundWorkScheduler import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay @@ -87,14 +88,12 @@ class ScanBluetoothWorker @AssistedInject constructor( val scanSettings = ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build() - bluetoothAdapter.bluetoothLeScanner.startScan( - DeviceManager.scanFilter, - scanSettings, - leScanCallback - ) + BLEScanCallback.startScanning(bluetoothAdapter.bluetoothLeScanner, DeviceManager.scanFilter, scanSettings, leScanCallback) delay(getScanDuration()) - bluetoothAdapter.bluetoothLeScanner.stopScan(leScanCallback) + + BLEScanCallback.stopScanning(bluetoothAdapter.bluetoothLeScanner) + Timber.d("Scanning for bluetooth le devices stopped!. Discovered ${scanResultDictionary.size} devices") if (location == null) { diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt b/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt index 4e432c2b..d6b78d7c 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/detection/TrackingDetectorWorker.kt @@ -96,6 +96,7 @@ class TrackingDetectorWorker @AssistedInject constructor( LocalDateTime.now(ZoneOffset.UTC).toString() ) ) + //Gets all beacons found in the last scan. Then we get all beacons for the device that emitted one of those beaconRepository.getLatestBeacons(since).forEach { val beacons = beaconRepository.getDeviceBeacons(it.deviceAddress) beaconsPerDevice[it.deviceAddress] = beacons diff --git a/app/src/main/java/de/seemoo/at_tracking_detection/ui/debug/DebugFragment.kt b/app/src/main/java/de/seemoo/at_tracking_detection/ui/debug/DebugFragment.kt index 1bf54270..3a7254bd 100644 --- a/app/src/main/java/de/seemoo/at_tracking_detection/ui/debug/DebugFragment.kt +++ b/app/src/main/java/de/seemoo/at_tracking_detection/ui/debug/DebugFragment.kt @@ -29,6 +29,7 @@ import de.seemoo.at_tracking_detection.notifications.NotificationService import de.seemoo.at_tracking_detection.statistics.api.Api import de.seemoo.at_tracking_detection.ui.dashboard.DashboardRiskFragmentDirections import de.seemoo.at_tracking_detection.util.Util +import de.seemoo.at_tracking_detection.util.ble.BLEScanCallback import de.seemoo.at_tracking_detection.worker.BackgroundWorkScheduler import fr.bipi.tressence.file.FileLoggerTree import kotlinx.coroutines.CoroutineScope @@ -112,6 +113,15 @@ class DebugFragment : Fragment() { DebugFragmentDirections.actionNavigationDebugToDebugLogFragment() findNavController().navigate(directions) } + + view.findViewById