UpdateClockJob.kt 4.67 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
 * Copyright by the original author or authors.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package de.ccc.events.badge.card10.background

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
32
import de.ccc.events.badge.card10.CARD10_BLUETOOTH_MAC_PREFIX
33
import de.ccc.events.badge.card10.CARD10_SERVICE_UUID
34
35
import de.ccc.events.badge.card10.TIME_CHARACTERISTIC_UUID
import java.nio.ByteBuffer
36
37
38
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

39
class UpdateClockJob(context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) {
40
41
42
43
44
    private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()

    override fun doWork(): Result {
        System.out.println("=== doWork() job started")
        for (device in bluetoothAdapter.bondedDevices) {
45
46
47
48
49
50
51
52
53
54
55
56
57
            if (device.address.startsWith(CARD10_BLUETOOTH_MAC_PREFIX, true)) {
                System.out.println("=== doWork() ${device}")
                var gatt: BluetoothGatt? = null
                try {
                    val gattLatch = CountDownLatch(1);
                    var writeLatch: CountDownLatch? = null
                    var timeCharacteristic: BluetoothGattCharacteristic? = null
                    val callback = object : BluetoothGattCallback() {
                        override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
                            System.out.println("=== doWork() onConnectionStateChange " + gatt + " / " + status + " / " + newState)
                            if (newState == BluetoothGatt.STATE_CONNECTED)
                                gatt.discoverServices()
                        }
58

59
60
61
62
63
64
                        override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
                            System.out.println("=== doWork() onServicesDiscovered " + gatt + " / " + status)
                            val card10Service = gatt.getService(CARD10_SERVICE_UUID)
                            timeCharacteristic = card10Service.getCharacteristic(TIME_CHARACTERISTIC_UUID)
                            gattLatch.countDown()
                        }
65

66
67
68
69
70
71
72
                        override fun onCharacteristicWrite(
                            gatt: BluetoothGatt?,
                            characteristic: BluetoothGattCharacteristic?,
                            status: Int
                        ) {
                            writeLatch?.countDown()
                        }
73
                    }
74
75
76
                    gatt = device.connectGatt(applicationContext, true, callback)
                    if (!gattLatch.await(1, TimeUnit.MINUTES))
                        return Result.retry()
77

78
79
80
81
82
83
84
85
86
87
88
89
90
                    val buffer = ByteBuffer.allocate(8)
                    buffer.putLong(System.currentTimeMillis())
                    timeCharacteristic?.value = buffer.array()
                    if (gatt.writeCharacteristic(timeCharacteristic)) {
                        writeLatch = CountDownLatch(1)
                        if (!writeLatch.await(1, TimeUnit.MINUTES))
                            return Result.failure()
                        System.out.println("=== doWork() updated time")
                    }
                } catch (x: Exception) {
                    x.printStackTrace()
                } finally {
                    gatt?.close();
91
92
93
94
                }
            }
        }

95
        System.out.println("=== doWork() job finished (success)")
96
97
98
        return Result.success()
    }
}