blob: 078532a0e64459777216a33c097f9b3e9fae7e71 [file] [log] [blame]
Arthur Ishigurob9ae7bd2017-10-09 12:47:52 -07001/*
2 * Copyright 2017 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 */
16package android.hardware.location;
17
Arthur Ishiguro1eef69f2018-11-08 15:17:11 -080018import android.annotation.Nullable;
Arthur Ishigurof2b6f012017-11-28 15:21:38 -080019import android.annotation.SystemApi;
Arthur Ishigurob9ae7bd2017-10-09 12:47:52 -070020import android.os.Parcel;
21import android.os.Parcelable;
22
Neil Fullerb5d1c152019-04-04 21:02:06 +010023import libcore.util.HexEncoding;
24
Arthur Ishiguro1eef69f2018-11-08 15:17:11 -080025import java.util.Arrays;
26
Arthur Ishigurob9ae7bd2017-10-09 12:47:52 -070027/**
28 * A class describing messages send to or from nanoapps through the Context Hub Service.
29 *
30 * The basis of the class is in the IContextHub.hal ContextHubMsg definition.
31 *
32 * @hide
33 */
Arthur Ishigurof2b6f012017-11-28 15:21:38 -080034@SystemApi
Arthur Ishigurob9ae7bd2017-10-09 12:47:52 -070035public final class NanoAppMessage implements Parcelable {
Arthur Ishiguro1d3b23c2018-01-05 16:05:25 -080036 private static final int DEBUG_LOG_NUM_BYTES = 16;
Arthur Ishigurob9ae7bd2017-10-09 12:47:52 -070037 private long mNanoAppId;
38 private int mMessageType;
39 private byte[] mMessageBody;
40 private boolean mIsBroadcasted;
41
42 private NanoAppMessage(
43 long nanoAppId, int messageType, byte[] messageBody, boolean broadcasted) {
44 mNanoAppId = nanoAppId;
45 mMessageType = messageType;
46 mMessageBody = messageBody;
47 mIsBroadcasted = broadcasted;
48 }
49
50 /**
51 * Creates a NanoAppMessage object to send to a nanoapp.
52 *
53 * This factory method can be used to generate a NanoAppMessage object to be used in
54 * the ContextHubClient.sendMessageToNanoApp API.
55 *
56 * @param targetNanoAppId the ID of the nanoapp to send the message to
57 * @param messageType the nanoapp-dependent message type
58 * @param messageBody the byte array message contents
59 *
60 * @return the NanoAppMessage object
61 */
62 public static NanoAppMessage createMessageToNanoApp(
63 long targetNanoAppId, int messageType, byte[] messageBody) {
64 return new NanoAppMessage(
65 targetNanoAppId, messageType, messageBody, false /* broadcasted */);
66 }
67
68 /**
69 * Creates a NanoAppMessage object sent from a nanoapp.
70 *
71 * This factory method is intended only to be used by the Context Hub Service when delivering
72 * messages from a nanoapp to clients.
73 *
74 * @param sourceNanoAppId the ID of the nanoapp that the message was sent from
75 * @param messageType the nanoapp-dependent message type
76 * @param messageBody the byte array message contents
77 * @param broadcasted {@code true} if the message was broadcasted, {@code false} otherwise
78 *
79 * @return the NanoAppMessage object
80 */
81 public static NanoAppMessage createMessageFromNanoApp(
82 long sourceNanoAppId, int messageType, byte[] messageBody, boolean broadcasted) {
83 return new NanoAppMessage(sourceNanoAppId, messageType, messageBody, broadcasted);
84 }
85
86 /**
87 * @return the ID of the source or destination nanoapp
88 */
89 public long getNanoAppId() {
90 return mNanoAppId;
91 }
92
93 /**
94 * @return the type of the message that is nanoapp-dependent
95 */
96 public int getMessageType() {
97 return mMessageType;
98 }
99
100 /**
101 * @return the byte array contents of the message
102 */
103 public byte[] getMessageBody() {
104 return mMessageBody;
105 }
106
107 /**
108 * @return {@code true} if the message is broadcasted, {@code false} otherwise
109 */
110 public boolean isBroadcastMessage() {
111 return mIsBroadcasted;
112 }
113
114 private NanoAppMessage(Parcel in) {
115 mNanoAppId = in.readLong();
116 mIsBroadcasted = (in.readInt() == 1);
117 mMessageType = in.readInt();
118
119 int msgSize = in.readInt();
120 mMessageBody = new byte[msgSize];
121 in.readByteArray(mMessageBody);
122 }
123
124 @Override
125 public int describeContents() {
126 return 0;
127 }
128
129 @Override
130 public void writeToParcel(Parcel out, int flags) {
131 out.writeLong(mNanoAppId);
132 out.writeInt(mIsBroadcasted ? 1 : 0);
133 out.writeInt(mMessageType);
134
135 out.writeInt(mMessageBody.length);
136 out.writeByteArray(mMessageBody);
137 }
138
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700139 public static final @android.annotation.NonNull Creator<NanoAppMessage> CREATOR =
Arthur Ishigurob9ae7bd2017-10-09 12:47:52 -0700140 new Creator<NanoAppMessage>() {
141 @Override
142 public NanoAppMessage createFromParcel(Parcel in) {
143 return new NanoAppMessage(in);
144 }
145
146 @Override
147 public NanoAppMessage[] newArray(int size) {
148 return new NanoAppMessage[size];
149 }
150 };
Arthur Ishiguro1d3b23c2018-01-05 16:05:25 -0800151
152 @Override
153 public String toString() {
154 int length = mMessageBody.length;
155
156 String ret = "NanoAppMessage[type = " + mMessageType + ", length = " + mMessageBody.length
157 + " bytes, " + (mIsBroadcasted ? "broadcast" : "unicast") + ", nanoapp = 0x"
158 + Long.toHexString(mNanoAppId) + "](";
159 if (length > 0) {
160 ret += "data = 0x";
161 }
162 for (int i = 0; i < Math.min(length, DEBUG_LOG_NUM_BYTES); i++) {
Neil Fullerb5d1c152019-04-04 21:02:06 +0100163 ret += HexEncoding.encodeToString(mMessageBody[i], true /* upperCase */);
Arthur Ishiguro1d3b23c2018-01-05 16:05:25 -0800164
165 if ((i + 1) % 4 == 0) {
166 ret += " ";
167 }
168 }
169 if (length > DEBUG_LOG_NUM_BYTES) {
170 ret += "...";
171 }
172 ret += ")";
173
174 return ret;
175 }
Arthur Ishiguro1eef69f2018-11-08 15:17:11 -0800176
177 @Override
178 public boolean equals(@Nullable Object object) {
179 if (object == this) {
180 return true;
181 }
182
183 boolean isEqual = false;
184 if (object instanceof NanoAppMessage) {
185 NanoAppMessage other = (NanoAppMessage) object;
186 isEqual = (other.getNanoAppId() == mNanoAppId)
187 && (other.getMessageType() == mMessageType)
188 && (other.isBroadcastMessage() == mIsBroadcasted)
189 && Arrays.equals(other.getMessageBody(), mMessageBody);
190 }
191
192 return isEqual;
193 }
Arthur Ishigurob9ae7bd2017-10-09 12:47:52 -0700194}