1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.android.tv.btservices.remote; 18 19 import android.bluetooth.BluetoothDevice; 20 import android.content.Context; 21 import com.google.android.tv.btservices.R; 22 import java.util.concurrent.CompletableFuture; 23 import java.util.UUID; 24 25 public abstract class RemoteProxy { 26 27 private static final String TAG = "Atv.RemoteProxy"; 28 private static final boolean DEBUG = false; 29 30 public static final int DEFAULT_LOW_BATTERY_LEVEL = 20; 31 public static final int DEFAULT_CRITICAL_BATTERY_LEVEL = 0; 32 33 // Battery Info Profile 34 public static final UUID UUID_BATTERY_SERVICE = 35 UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb"); 36 public static final UUID UUID_BATTERY_LEVEL_CHARACTERISTIC = 37 UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb"); 38 public static final UUID CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID = 39 UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); 40 // Version info 41 public static final UUID UUID_DEVICE_INFO_SERVICE = 42 UUID.fromString("0000180a-0000-1000-8000-00805f9b34fb"); 43 public static final UUID UUID_VERSION_CHARACTERISTIC = 44 UUID.fromString("00002A28-0000-1000-8000-00805f9b34fb"); 45 46 public static class Result { 47 48 public static final int SUCCESS = 1; 49 public static final int UNKNOWN_FAILURE = 2; 50 public static final int GATT_DISCONNECTED = 3; 51 public static final int SUCCESS_NEEDS_PAIRING = 4; 52 public static final int NOT_IMPLEMENTED = 5; 53 public static final int DEVICE_BUSY = 6; 54 55 protected static final Result SUCCESS_INST = new Result(SUCCESS); 56 protected static final Result UNKNOWN_FAILURE_INST = new Result(UNKNOWN_FAILURE); 57 protected static final Result GATT_DISCONNECTED_INST = new Result(GATT_DISCONNECTED); 58 protected static final Result SUCCESS_NEEDS_PAIRING_INST = 59 new Result(SUCCESS_NEEDS_PAIRING); 60 protected static final Result NOT_IMPLEMENTED_INST = 61 new Result(NOT_IMPLEMENTED); 62 protected static final Result DEVICE_BUSY_INST = new Result(DEVICE_BUSY); 63 64 protected int mCode; 65 Result(int code)66 public Result(int code) { 67 mCode = code; 68 } 69 Result(Result res)70 protected Result(Result res) { 71 mCode = res.mCode; 72 } 73 code()74 public int code() { 75 return mCode; 76 } 77 } 78 79 public static class BatteryResult extends Result { 80 81 public static final BatteryResult RESULT_FAILURE = 82 new BatteryResult(Result.UNKNOWN_FAILURE_INST); 83 public static final BatteryResult RESULT_GATT_DISCONNECTED = 84 new BatteryResult(Result.GATT_DISCONNECTED); 85 public static final BatteryResult RESULT_NOT_IMPLEMENTED = 86 new BatteryResult(Result.NOT_IMPLEMENTED_INST); 87 88 private int mBattery; 89 BatteryResult(int battery)90 public BatteryResult(int battery) { 91 super(Result.SUCCESS); 92 mBattery = battery; 93 } 94 BatteryResult(Result res)95 private BatteryResult(Result res) { 96 super(res); 97 } 98 battery()99 public int battery() { 100 return mBattery; 101 } 102 } 103 104 public static class VersionResult extends Result { 105 106 public static final VersionResult RESULT_FAILURE = 107 new VersionResult(Result.UNKNOWN_FAILURE_INST); 108 public static final VersionResult RESULT_GATT_DISCONNECTED = 109 new VersionResult(Result.GATT_DISCONNECTED_INST); 110 111 private Version mVersion; 112 VersionResult(Version version)113 public VersionResult(Version version) { 114 super(Result.SUCCESS); 115 mVersion = version; 116 } 117 VersionResult(Result res)118 private VersionResult(Result res) { 119 super(res); 120 } 121 version()122 public Version version() { 123 return mVersion; 124 } 125 } 126 127 public static class DfuResult extends Result { 128 129 public static final DfuResult RESULT_FAILURE = new DfuResult(Result.UNKNOWN_FAILURE_INST); 130 public static final DfuResult RESULT_GATT_DISCONNECTED = 131 new DfuResult(Result.GATT_DISCONNECTED_INST); 132 public static final DfuResult RESULT_DEVICE_BUSY = new DfuResult(Result.DEVICE_BUSY_INST); 133 public static final DfuResult RESULT_SUCCESS = new DfuResult(Result.SUCCESS_INST); 134 public static final DfuResult RESULT_SUCCESS_NEEDS_PAIRING = 135 new DfuResult(Result.SUCCESS_NEEDS_PAIRING_INST); 136 137 // Continuing index from fields of Result 138 public static final int IN_PROGRESS = 103; 139 140 private final double mProgress; 141 DfuResult(double progress)142 public DfuResult(double progress) { 143 super(IN_PROGRESS); 144 mProgress = progress; 145 } 146 DfuResult(Result res)147 private DfuResult(Result res) { 148 super(res); 149 mProgress = 0; 150 } 151 progress()152 public double progress() { 153 return mProgress; 154 } 155 } 156 157 protected final BluetoothDevice mDevice; 158 RemoteProxy(Context context, BluetoothDevice device)159 protected RemoteProxy(Context context, BluetoothDevice device) { 160 mDevice = device; 161 } 162 initialize(Context context)163 public abstract boolean initialize(Context context); 164 refreshBatteryLevel()165 public abstract CompletableFuture<Boolean> refreshBatteryLevel(); 166 getLastKnownBatteryLevel()167 public abstract BatteryResult getLastKnownBatteryLevel(); 168 169 /** 170 * @param callback The callback which is called by the underlying implementation whenever there 171 * is a battery level update. 172 * @return A CompleteableFuture of Boolean that indicates whether the callback has been 173 * successfully registered. 174 */ registerBatteryLevelCallback(Runnable callback)175 public abstract CompletableFuture<Boolean> registerBatteryLevelCallback(Runnable callback); 176 lowBatteryLevel()177 public int lowBatteryLevel() { 178 return DEFAULT_LOW_BATTERY_LEVEL; 179 } 180 mapBatteryLevel(Context context, int level)181 public String mapBatteryLevel(Context context, int level) { 182 return context.getString(R.string.settings_remote_battery_level_percentage_label, level); 183 } 184 refreshVersion()185 public abstract CompletableFuture<Boolean> refreshVersion(); 186 getLastKnownVersion()187 public abstract Version getLastKnownVersion(); 188 requestDfu( DfuBinary dfu, DfuManager.Listener listener, boolean background)189 public abstract CompletableFuture<DfuResult> requestDfu( 190 DfuBinary dfu, DfuManager.Listener listener, boolean background); 191 getDfuState()192 public abstract DfuResult getDfuState(); 193 supportsBackgroundDfu()194 public abstract boolean supportsBackgroundDfu(); 195 } 196