1 /*
2  * Copyright 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 package android.hardware.location;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.annotation.SystemApi;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 /**
25  * An RPC service published by a nanoapp.
26  *
27  * This class is meant to be informational and allows a nanoapp client to know if a given
28  * nanoapp publishes a service which supports an RPC interface. The implementation of the RPC
29  * interface is not specified by the Android APIs and is built by the platform implementation
30  * over the message payloads transferred through the {@link ContextHubClient}.
31  *
32  * This class is instantiated as a part of {@link NanoAppState}, which is provided as a result
33  * of {@link ContextHubManager.queryNanoApps(ContextHubInfo)}.
34  *
35  * See the chrePublishRpcServices() API for how this service is published by the nanoapp.
36  *
37  * @hide
38  */
39 @SystemApi
40 public final class NanoAppRpcService implements Parcelable {
41     private long mServiceId;
42 
43     private int mServiceVersion;
44 
45     /**
46      * @param serviceId The unique ID of this service, see {#getId()}.
47      * @param serviceVersion The software version of this service, see {#getVersion()}.
48      */
NanoAppRpcService(long serviceId, int serviceVersion)49     public NanoAppRpcService(long serviceId, int serviceVersion) {
50         mServiceId = serviceId;
51         mServiceVersion = serviceVersion;
52     }
53 
54     /**
55      * The unique 64-bit ID of an RPC service published by a nanoapp. Note that
56      * the uniqueness is only required within the nanoapp's domain (i.e. the
57      * combination of the nanoapp ID and service id must be unique).
58      *
59      * This ID must remain the same for the given nanoapp RPC service once
60      * published on Android (i.e. must never change).
61      *
62      * @return The service ID.
63      */
getId()64     public long getId() {
65         return mServiceId;
66     }
67 
68     /**
69      * The software version of this service, which follows the sematic
70      * versioning scheme (see semver.org). It follows the format
71      * major.minor.patch, where major and minor versions take up one byte
72      * each, and the patch version takes up the final 2 (lower) bytes.
73      * I.e. the version is encoded as 0xMMmmpppp, where MM, mm, pppp are
74      * the major, minor, patch versions, respectively.
75      *
76      * @return The service version.
77      */
getVersion()78     public int getVersion() {
79         return mServiceVersion;
80     }
81 
82     /**
83      * @return The service's major version.
84      */
getMajorVersion()85     private int getMajorVersion() {
86         return (mServiceVersion & 0xFF000000) >>> 24;
87     }
88 
89     /**
90      * @return The service's minor version.
91      */
getMinorVersion()92     private int getMinorVersion() {
93         return (mServiceVersion & 0x00FF0000) >>> 16;
94     }
95 
96     /**
97      * @return The service's patch version.
98      */
getPatchVersion()99     private int getPatchVersion() {
100         return mServiceVersion & 0x0000FFFF;
101     }
102 
NanoAppRpcService(Parcel in)103     private NanoAppRpcService(Parcel in) {
104         mServiceId = in.readLong();
105         mServiceVersion = in.readInt();
106     }
107 
108     @Override
describeContents()109     public int describeContents() {
110         return 0;
111     }
112 
113     @Override
writeToParcel(@onNull Parcel out, int flags)114     public void writeToParcel(@NonNull Parcel out, int flags) {
115         out.writeLong(mServiceId);
116         out.writeInt(mServiceVersion);
117     }
118 
119     public static final @NonNull Creator<NanoAppRpcService> CREATOR =
120             new Creator<NanoAppRpcService>() {
121                 @Override
122                 public NanoAppRpcService createFromParcel(Parcel in) {
123                     return new NanoAppRpcService(in);
124                 }
125 
126                 @Override
127                 public NanoAppRpcService[] newArray(int size) {
128                     return new NanoAppRpcService[size];
129                 }
130             };
131 
132     @NonNull
133     @Override
toString()134     public String toString() {
135         return "NanoAppRpcService[Id = " + Long.toHexString(mServiceId) + ", version = v"
136                 + getMajorVersion() + "." + getMinorVersion() + "." + getPatchVersion() + "]";
137     }
138 
139     @Override
equals(@ullable Object object)140     public boolean equals(@Nullable Object object) {
141         if (object == this) {
142             return true;
143         }
144 
145         boolean isEqual = false;
146         if (object instanceof NanoAppRpcService) {
147             NanoAppRpcService other = (NanoAppRpcService) object;
148             isEqual = (other.getId() == mServiceId)
149                     && (other.getVersion() == mServiceVersion);
150         }
151 
152         return isEqual;
153     }
154 
155     @Override
hashCode()156     public int hashCode() {
157         return (int) getId();
158     }
159 }
160