1 /*
2  * Copyright (C) 2022 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.nearby;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import com.android.internal.util.Preconditions;
27 
28 import java.util.Arrays;
29 import java.util.Objects;
30 
31 /**
32  * Represents a data element in Nearby Presence.
33  *
34  * @hide
35  */
36 @SystemApi
37 public final class DataElement implements Parcelable {
38 
39     private final int mKey;
40     private final byte[] mValue;
41 
42     /**
43      * Note this interface is used for internal implementation only.
44      * We only keep those data element types used for encoding and decoding from the specs.
45      * Please read the nearby specs for learning more about each data type and use it as the only
46      * source.
47      *
48      * @hide
49      */
50     @IntDef({
51             DataType.SALT,
52             DataType.PRIVATE_IDENTITY,
53             DataType.TRUSTED_IDENTITY,
54             DataType.PUBLIC_IDENTITY,
55             DataType.PROVISIONED_IDENTITY,
56             DataType.TX_POWER,
57             DataType.ACTION,
58             DataType.ACCOUNT_KEY_DATA,
59             DataType.CONNECTION_STATUS,
60             DataType.BATTERY,
61             DataType.ENCRYPTION_INFO,
62             DataType.BLE_SERVICE_DATA,
63             DataType.BLE_ADDRESS,
64             DataType.SCAN_MODE,
65             DataType.TEST_DE_BEGIN,
66             DataType.TEST_DE_END
67     })
68     public @interface DataType {
69         int SALT = 0;
70         int PRIVATE_IDENTITY = 1;
71         int TRUSTED_IDENTITY = 2;
72         int PUBLIC_IDENTITY = 3;
73         int PROVISIONED_IDENTITY = 4;
74         int TX_POWER = 5;
75         int ACTION = 6;
76         int ACCOUNT_KEY_DATA = 9;
77         int CONNECTION_STATUS = 10;
78         int BATTERY = 11;
79 
80         int ENCRYPTION_INFO = 16;
81 
82         // Not defined in the spec. Reserved for internal use only.
83         int BLE_SERVICE_DATA = 100;
84         int BLE_ADDRESS = 101;
85         // This is to indicate if the scan is offload only
86         int SCAN_MODE = 102;
87 
88         int DEVICE_TYPE = 22;
89         // Reserves test DE ranges from {@link DataElement.DataType#TEST_DE_BEGIN}
90         // to {@link DataElement.DataType#TEST_DE_END}, inclusive.
91         // Reserves 128 Test DEs.
92         int TEST_DE_BEGIN = Integer.MAX_VALUE - 127; // 2147483520
93         int TEST_DE_END = Integer.MAX_VALUE; // 2147483647
94     }
95 
96     /**
97      * @return {@code true} if this is identity type.
98      * @hide
99      */
isIdentityDataType()100     public boolean isIdentityDataType() {
101         return mKey == DataType.PRIVATE_IDENTITY
102                 || mKey == DataType.TRUSTED_IDENTITY
103                 || mKey == DataType.PUBLIC_IDENTITY
104                 || mKey == DataType.PROVISIONED_IDENTITY;
105     }
106 
107     /**
108      * @return {@code true} if this is test data element type.
109      * @hide
110      */
isTestDeType(int type)111     public static boolean isTestDeType(int type) {
112         return type >= DataType.TEST_DE_BEGIN && type <= DataType.TEST_DE_END;
113     }
114 
115     /**
116      * Constructs a {@link DataElement}.
117      */
DataElement(int key, @NonNull byte[] value)118     public DataElement(int key, @NonNull byte[] value) {
119         Preconditions.checkArgument(value != null, "value cannot be null");
120         mKey = key;
121         mValue = value;
122     }
123 
124     @NonNull
125     public static final Creator<DataElement> CREATOR = new Creator<DataElement>() {
126         @Override
127         public DataElement createFromParcel(Parcel in) {
128             int key = in.readInt();
129             byte[] value = new byte[in.readInt()];
130             in.readByteArray(value);
131             return new DataElement(key, value);
132         }
133 
134         @Override
135         public DataElement[] newArray(int size) {
136             return new DataElement[size];
137         }
138     };
139 
140     @Override
equals(@ullable Object obj)141     public boolean equals(@Nullable Object obj) {
142         if (obj instanceof DataElement) {
143             return mKey == ((DataElement) obj).mKey
144                     && Arrays.equals(mValue, ((DataElement) obj).mValue);
145         }
146         return false;
147     }
148 
149     @Override
hashCode()150     public int hashCode() {
151         return Objects.hash(mKey, Arrays.hashCode(mValue));
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(mKey);
162         dest.writeInt(mValue.length);
163         dest.writeByteArray(mValue);
164     }
165 
166     /**
167      * Returns the key of the data element, as defined in the nearby presence specification.
168      */
getKey()169     public int getKey() {
170         return mKey;
171     }
172 
173     /**
174      * Returns the value of the data element.
175      */
176     @NonNull
getValue()177     public byte[] getValue() {
178         return mValue;
179     }
180 }
181