1 /* 2 * Copyright (C) 2024 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 android.companion; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.os.Parcel; 24 import android.os.ParcelUuid; 25 import android.os.Parcelable; 26 27 import java.lang.annotation.Retention; 28 import java.lang.annotation.RetentionPolicy; 29 import java.util.Objects; 30 31 /** 32 * Event for observing device presence. 33 * 34 * @see CompanionDeviceManager#startObservingDevicePresence(ObservingDevicePresenceRequest) 35 * @see ObservingDevicePresenceRequest.Builder#setUuid(ParcelUuid) 36 * @see ObservingDevicePresenceRequest.Builder#setAssociationId(int) 37 */ 38 @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE) 39 public final class DevicePresenceEvent implements Parcelable { 40 41 /** @hide */ 42 @IntDef(prefix = {"EVENT"}, value = { 43 EVENT_BLE_APPEARED, 44 EVENT_BLE_DISAPPEARED, 45 EVENT_BT_CONNECTED, 46 EVENT_BT_DISCONNECTED, 47 EVENT_SELF_MANAGED_APPEARED, 48 EVENT_SELF_MANAGED_DISAPPEARED 49 }) 50 51 @Retention(RetentionPolicy.SOURCE) 52 public @interface Event {} 53 54 /** 55 * Indicate observing device presence base on the ParcelUuid but not association id. 56 */ 57 public static final int NO_ASSOCIATION = -1; 58 59 /** 60 * Companion app receives 61 * {@link CompanionDeviceService#onDevicePresenceEvent(DevicePresenceEvent)} callback 62 * with this event if the device comes into BLE range. 63 */ 64 public static final int EVENT_BLE_APPEARED = 0; 65 66 /** 67 * Companion app receives 68 * {@link CompanionDeviceService#onDevicePresenceEvent(DevicePresenceEvent)} callback 69 * with this event if the device is no longer in BLE range. 70 */ 71 public static final int EVENT_BLE_DISAPPEARED = 1; 72 73 /** 74 * Companion app receives 75 * {@link CompanionDeviceService#onDevicePresenceEvent(DevicePresenceEvent)} callback 76 * with this event when the bluetooth device is connected. 77 */ 78 public static final int EVENT_BT_CONNECTED = 2; 79 80 /** 81 * Companion app receives 82 * {@link CompanionDeviceService#onDevicePresenceEvent(DevicePresenceEvent)} callback 83 * with this event if the bluetooth device is disconnected. 84 */ 85 public static final int EVENT_BT_DISCONNECTED = 3; 86 87 /** 88 * A companion app for a self-managed device will receive the callback 89 * {@link CompanionDeviceService#onDevicePresenceEvent(DevicePresenceEvent)} 90 * if it reports that a device has appeared on its 91 * own. 92 */ 93 public static final int EVENT_SELF_MANAGED_APPEARED = 4; 94 95 /** 96 * A companion app for a self-managed device will receive the callback 97 * {@link CompanionDeviceService#onDevicePresenceEvent(DevicePresenceEvent)} if it reports 98 * that a device has disappeared on its own. 99 */ 100 public static final int EVENT_SELF_MANAGED_DISAPPEARED = 5; 101 private final int mAssociationId; 102 private final int mEvent; 103 @Nullable 104 private final ParcelUuid mUuid; 105 106 private static final int PARCEL_UUID_NULL = 0; 107 108 private static final int PARCEL_UUID_NOT_NULL = 1; 109 110 /** 111 * Create a new DevicePresenceEvent. 112 */ DevicePresenceEvent( int associationId, @Event int event, @Nullable ParcelUuid uuid)113 public DevicePresenceEvent( 114 int associationId, @Event int event, @Nullable ParcelUuid uuid) { 115 mAssociationId = associationId; 116 mEvent = event; 117 mUuid = uuid; 118 } 119 120 /** 121 * @return The association id has been used to observe device presence. 122 * 123 * Caller will receive the valid association id if only if using 124 * {@link ObservingDevicePresenceRequest.Builder#setAssociationId(int)}, otherwise 125 * return {@link #NO_ASSOCIATION}. 126 * 127 * @see ObservingDevicePresenceRequest.Builder#setAssociationId(int) 128 */ getAssociationId()129 public int getAssociationId() { 130 return mAssociationId; 131 } 132 133 /** 134 * @return Associated companion device's event. 135 */ getEvent()136 public int getEvent() { 137 return mEvent; 138 } 139 140 /** 141 * @return The ParcelUuid has been used to observe device presence. 142 * 143 * Caller will receive the ParcelUuid if only if using 144 * {@link ObservingDevicePresenceRequest.Builder#setUuid(ParcelUuid)}, otherwise return null. 145 * 146 * @see ObservingDevicePresenceRequest.Builder#setUuid(ParcelUuid) 147 */ 148 149 @Nullable getUuid()150 public ParcelUuid getUuid() { 151 return mUuid; 152 } 153 154 @Override describeContents()155 public int describeContents() { 156 return 0; 157 } 158 159 @Override writeToParcel(@onNull Parcel dest, int flags)160 public void writeToParcel(@NonNull Parcel dest, int flags) { 161 dest.writeInt(mAssociationId); 162 dest.writeInt(mEvent); 163 if (mUuid == null) { 164 // Write 0 to the parcel to indicate the ParcelUuid is null. 165 dest.writeInt(PARCEL_UUID_NULL); 166 } else { 167 dest.writeInt(PARCEL_UUID_NOT_NULL); 168 mUuid.writeToParcel(dest, flags); 169 } 170 } 171 172 @Override equals(@ullable Object o)173 public boolean equals(@Nullable Object o) { 174 if (this == o) return true; 175 if (!(o instanceof DevicePresenceEvent that)) return false; 176 177 return Objects.equals(mUuid, that.mUuid) 178 && mAssociationId == that.mAssociationId 179 && mEvent == that.mEvent; 180 } 181 182 @Override toString()183 public String toString() { 184 return "ObservingDevicePresenceResult { " 185 + "Association Id= " + mAssociationId + "," 186 + "ParcelUuid= " + mUuid + "," 187 + "Event= " + mEvent + "}"; 188 } 189 190 @Override hashCode()191 public int hashCode() { 192 return Objects.hash(mAssociationId, mEvent, mUuid); 193 } 194 195 @NonNull 196 public static final Parcelable.Creator<DevicePresenceEvent> CREATOR = 197 new Parcelable.Creator<DevicePresenceEvent>() { 198 @Override 199 public DevicePresenceEvent[] newArray(int size) { 200 return new DevicePresenceEvent[size]; 201 } 202 203 @Override 204 public DevicePresenceEvent createFromParcel(@NonNull Parcel in) { 205 return new DevicePresenceEvent(in); 206 } 207 }; 208 DevicePresenceEvent(@onNull Parcel in)209 private DevicePresenceEvent(@NonNull Parcel in) { 210 mAssociationId = in.readInt(); 211 mEvent = in.readInt(); 212 if (in.readInt() == PARCEL_UUID_NULL) { 213 mUuid = null; 214 } else { 215 mUuid = ParcelUuid.CREATOR.createFromParcel(in); 216 } 217 } 218 } 219