1 /* 2 * Copyright (C) 2018 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 com.android.car.vehiclehal.test; 17 18 import static java.lang.Integer.toHexString; 19 20 import android.car.hardware.CarPropertyValue; 21 import android.hardware.automotive.vehicle.VehiclePropertyType; 22 23 import org.json.JSONArray; 24 import org.json.JSONException; 25 import org.json.JSONObject; 26 27 import java.io.BufferedReader; 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.InputStreamReader; 31 import java.nio.charset.StandardCharsets; 32 import java.util.ArrayList; 33 import java.util.List; 34 35 36 class VhalJsonReader { 37 38 /** 39 * Name of fields presented in JSON file. All of them are required. 40 */ 41 private static final String JSON_FIELD_PROP = "prop"; 42 private static final String JSON_FIELD_AREA_ID = "areaId"; 43 private static final String JSON_FIELD_TIMESTAMP = "timestamp"; 44 private static final String JSON_FIELD_VALUE = "value"; 45 private static final String JSON_FIELD_INT32_VALUES = "int32Values"; 46 private static final String JSON_FIELD_INT64_VALUES = "int64Values"; 47 private static final String JSON_FIELD_FLOAT_VALUES = "floatValues"; 48 private static final String JSON_FIELD_STRING_VALUE = "stringValue"; 49 readFromJson(InputStream in)50 public static List<CarPropertyValue> readFromJson(InputStream in) 51 throws IOException, JSONException { 52 JSONArray rawEvents = new JSONArray(readJsonString(in)); 53 List<CarPropertyValue> events = new ArrayList<>(); 54 for (int i = 0; i < rawEvents.length(); i++) { 55 events.add(getEvent(rawEvents.getJSONObject(i))); 56 } 57 return events; 58 } 59 readJsonString(InputStream in)60 private static String readJsonString(InputStream in) throws IOException { 61 StringBuilder builder = new StringBuilder(); 62 try (BufferedReader reader = new BufferedReader( 63 new InputStreamReader(in, StandardCharsets.UTF_8))) { 64 reader.lines().forEach(builder::append); 65 } 66 return builder.toString(); 67 } 68 getEvent(JSONObject rawEvent)69 private static CarPropertyValue<?> getEvent(JSONObject rawEvent) throws JSONException { 70 int prop = rawEvent.getInt(JSON_FIELD_PROP); 71 int areaId = rawEvent.getInt(JSON_FIELD_AREA_ID); 72 long timestamp = rawEvent.getLong(JSON_FIELD_TIMESTAMP); 73 74 switch (prop & VehiclePropertyType.MASK) { 75 case VehiclePropertyType.BOOLEAN: 76 return new CarPropertyValue<>(prop, areaId, CarPropertyValue.STATUS_AVAILABLE, 77 timestamp, rawEvent.getInt(JSON_FIELD_VALUE) != 0); 78 case VehiclePropertyType.INT32: 79 return new CarPropertyValue<>(prop, areaId, CarPropertyValue.STATUS_AVAILABLE, 80 timestamp, rawEvent.getInt(JSON_FIELD_VALUE)); 81 case VehiclePropertyType.INT64: 82 return new CarPropertyValue<>(prop, areaId, CarPropertyValue.STATUS_AVAILABLE, 83 timestamp, rawEvent.getLong(JSON_FIELD_VALUE)); 84 case VehiclePropertyType.FLOAT: 85 return new CarPropertyValue<>(prop, areaId, 86 CarPropertyValue.STATUS_AVAILABLE, timestamp, 87 (float) rawEvent.getDouble(JSON_FIELD_VALUE)); 88 case VehiclePropertyType.STRING: 89 return new CarPropertyValue<>(prop, areaId, CarPropertyValue.STATUS_AVAILABLE, 90 timestamp, rawEvent.getString(JSON_FIELD_VALUE)); 91 // TODO: CarPropertyValue API has not supported VehiclePropertyType.MIXED type yet. 92 // Here is a temporary solution to use VehiclePropValue.RawValue 93 case VehiclePropertyType.MIXED: 94 List<Object> valuesList = new ArrayList<>(); 95 JSONObject rawValueJson = rawEvent.getJSONObject(JSON_FIELD_VALUE); 96 97 copyValuesArray(valuesList, rawValueJson.optJSONArray(JSON_FIELD_INT32_VALUES), 98 Integer.class); 99 copyValuesArray(valuesList, rawValueJson.optJSONArray(JSON_FIELD_INT64_VALUES), 100 Long.class); 101 copyValuesArray(valuesList, rawValueJson.optJSONArray(JSON_FIELD_FLOAT_VALUES), 102 Float.class); 103 valuesList.add(rawValueJson.getString(JSON_FIELD_STRING_VALUE)); 104 105 return new CarPropertyValue<>(prop, areaId, CarPropertyValue.STATUS_AVAILABLE, 106 timestamp, valuesList.toArray()); 107 default: 108 throw new IllegalArgumentException("Property type 0x" 109 + toHexString(prop & VehiclePropertyType.MASK) 110 + " is not supported in the test."); 111 } 112 } 113 copyValuesArray(List valuesList, JSONArray jsonArray, Class clazz)114 private static void copyValuesArray(List valuesList, JSONArray jsonArray, Class clazz) 115 throws JSONException { 116 if (jsonArray == null) { 117 return; 118 } 119 for (int i = 0; i < jsonArray.length(); i++) { 120 if (clazz == Integer.class) { 121 valuesList.add(jsonArray.getInt(i)); 122 } else if (clazz == Long.class) { 123 valuesList.add(jsonArray.getLong(i)); 124 } else if (clazz == Float.class) { 125 valuesList.add((float) jsonArray.getDouble(i)); 126 } 127 } 128 } 129 } 130