blob: 6936f22706600a648daf0eb2a153bd4d1244e55a [file] [log] [blame]
Enrico Granata3a3850c2017-03-27 12:40:13 -07001/*
2 * Copyright (C) 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 */
16
17package com.android.car.vehiclehal;
18
19import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
20import android.util.JsonReader;
21import android.util.Log;
22import android.util.SparseArray;
23import com.android.car.vehiclehal.Utils.SparseArrayIterator;
24import java.io.IOException;
25import java.util.Objects;
26import java.util.Optional;
27
28public class DiagnosticJson {
Enrico Granatace7ee202017-04-05 14:31:41 -070029 public final String type;
Enrico Granata3a3850c2017-03-27 12:40:13 -070030 public final long timestamp;
31 public final SparseArray<Integer> intValues;
32 public final SparseArray<Float> floatValues;
33 public final String dtc;
34
35 DiagnosticJson(
Enrico Granatace7ee202017-04-05 14:31:41 -070036 String type,
Enrico Granata3a3850c2017-03-27 12:40:13 -070037 long timestamp,
38 SparseArray<Integer> intValues,
39 SparseArray<Float> floatValues,
40 String dtc) {
41 this.type = type;
42 this.timestamp = timestamp;
43 this.intValues = Objects.requireNonNull(intValues);
44 this.floatValues = Objects.requireNonNull(floatValues);
45 this.dtc = dtc;
46 }
47
48 VehiclePropValue build(DiagnosticEventBuilder builder) {
49 new SparseArrayIterator<>(intValues)
50 .forEach(
51 (SparseArrayIterator.SparseArrayEntry<Integer> entry) ->
52 builder.addIntSensor(entry.key, entry.value));
53 new SparseArrayIterator<>(floatValues)
54 .forEach(
55 (SparseArrayIterator.SparseArrayEntry<Float> entry) ->
56 builder.addFloatSensor(entry.key, entry.value));
57 builder.setDTC(dtc);
58 VehiclePropValue vehiclePropValue = builder.build(timestamp);
59 builder.clear();
60 return vehiclePropValue;
61 }
62
63 static class Builder {
64 public static final String TAG = Builder.class.getSimpleName();
65
66 static class WriteOnce<T> {
67 private Optional<T> mValue = Optional.empty();
68
69 void write(T value) {
70 if (mValue.isPresent()) throw new IllegalStateException("WriteOnce already stored");
71 mValue = Optional.of(value);
72 }
73
74 T get() {
75 if (!mValue.isPresent()) throw new IllegalStateException("WriteOnce never stored");
76 return mValue.get();
77 }
78
79 T get(T defaultValue) {
80 return mValue.isPresent() ? mValue.get() : defaultValue;
81 }
82 }
83
Enrico Granatace7ee202017-04-05 14:31:41 -070084 final WriteOnce<String> mType = new WriteOnce<>();
Enrico Granata3a3850c2017-03-27 12:40:13 -070085 final WriteOnce<Long> mTimestamp = new WriteOnce<>();
86 final SparseArray<Integer> mIntValues = new SparseArray<>();
87 final SparseArray<Float> mFloatValues = new SparseArray<>();
88 final WriteOnce<String> mDtc = new WriteOnce<>();
89
90 private void readIntValues(JsonReader jsonReader) throws IOException {
91 while (jsonReader.hasNext()) {
92 int id = 0;
93 int value = 0;
94 jsonReader.beginObject();
95 while (jsonReader.hasNext()) {
96 String name = jsonReader.nextName();
97 if (name.equals("id")) id = jsonReader.nextInt();
98 else if (name.equals("value")) value = jsonReader.nextInt();
99 }
100 jsonReader.endObject();
101 mIntValues.put(id, value);
102 }
103 }
104
105 private void readFloatValues(JsonReader jsonReader) throws IOException {
106 while (jsonReader.hasNext()) {
107 int id = 0;
108 float value = 0.0f;
109 jsonReader.beginObject();
110 while (jsonReader.hasNext()) {
111 String name = jsonReader.nextName();
112 if (name.equals("id")) id = jsonReader.nextInt();
113 else if (name.equals("value")) value = (float) jsonReader.nextDouble();
114 }
115 jsonReader.endObject();
116 mFloatValues.put(id, value);
117 }
118 }
119
120 Builder(JsonReader jsonReader) throws IOException {
121 jsonReader.beginObject();
Enrico Granata3a3850c2017-03-27 12:40:13 -0700122 while (jsonReader.hasNext()) {
123 String name = jsonReader.nextName();
124 switch (name) {
125 case "type":
Enrico Granatace7ee202017-04-05 14:31:41 -0700126 mType.write(jsonReader.nextString());
Enrico Granata3a3850c2017-03-27 12:40:13 -0700127 break;
128 case "timestamp":
129 mTimestamp.write(jsonReader.nextLong());
130 break;
131 case "intValues":
132 jsonReader.beginArray();
133 readIntValues(jsonReader);
134 jsonReader.endArray();
135 break;
136 case "floatValues":
137 jsonReader.beginArray();
138 readFloatValues(jsonReader);
139 jsonReader.endArray();
140 break;
141 case "stringValue":
142 mDtc.write(jsonReader.nextString());
143 break;
144 default:
145 Log.w(TAG, "Unknown name in diagnostic JSON: " + name);
146 }
147 }
148 jsonReader.endObject();
149 }
150
151 DiagnosticJson build() {
152 return new DiagnosticJson(
153 mType.get(), mTimestamp.get(), mIntValues, mFloatValues, mDtc.get(null));
154 }
Enrico Granatace7ee202017-04-05 14:31:41 -0700155 }
Enrico Granata3a3850c2017-03-27 12:40:13 -0700156
Enrico Granatace7ee202017-04-05 14:31:41 -0700157 public static DiagnosticJson build(JsonReader jsonReader) throws IOException {
158 return new Builder(jsonReader).build();
Enrico Granata3a3850c2017-03-27 12:40:13 -0700159 }
160}