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 com.android.server.uwb.multchip; 18 19 import android.content.Context; 20 import android.util.Log; 21 22 import com.android.uwb.ChipGroupInfo; 23 import com.android.uwb.ChipInfo; 24 import com.android.uwb.Coordinates; 25 import com.android.uwb.UwbChipConfig; 26 import com.android.uwb.XmlParser; 27 import com.android.uwb.resources.R; 28 29 import com.google.common.base.Strings; 30 import com.google.uwb.support.multichip.ChipInfoParams; 31 32 import org.xmlpull.v1.XmlPullParserException; 33 34 import java.io.BufferedInputStream; 35 import java.io.FileInputStream; 36 import java.io.IOException; 37 import java.io.InputStream; 38 import java.util.ArrayList; 39 import java.util.List; 40 41 import javax.xml.datatype.DatatypeConfigurationException; 42 43 /** 44 * Manages UWB chip information (such as id and position) for a multi-chip device. 45 */ 46 public class UwbMultichipData { 47 private static final String TAG = "UwbMultichipData"; 48 private final Context mContext; 49 private String mDefaultChipId = "default"; 50 private List<ChipInfoParams> mChipInfoParamsList = 51 List.of(ChipInfoParams.createBuilder().setChipId(mDefaultChipId).build()); 52 UwbMultichipData(Context context)53 public UwbMultichipData(Context context) { 54 mContext = context; 55 } 56 57 /** 58 * Reads in a configuration file to initialize chip info, if the device is a multi-chip system 59 * a configuration file is defined and available. 60 * 61 * <p>If the device is single-chip, or if no configuration file is available, default values are 62 * used. 63 */ initialize()64 public void initialize() { 65 if (mContext.getResources().getBoolean(R.bool.config_isMultichip)) { 66 String filePath = 67 mContext.getResources().getString(R.string.config_multichipConfigPath); 68 if (Strings.isNullOrEmpty(filePath)) { 69 Log.w(TAG, "Multichip is set to true, but configuration file is not defined."); 70 } else { 71 readConfigurationFile(filePath); 72 } 73 } 74 } 75 76 /** 77 * Returns a list of UWB chip infos in a {@link ChipInfoParams} object. 78 * 79 * Callers can invoke methods on a specific UWB chip by passing its {@code chipId} to the 80 * method, which can be determined by calling: 81 * <pre> 82 * {@code 83 * List<ChipInfoParams> chipInfos = getChipInfos(); 84 * for (ChipInfoParams chipInfo : chipInfos) { 85 * String chipId = chipInfo.getChipId(); 86 * } 87 * } 88 * </pre> 89 * 90 * @return list of {@link ChipInfoParams} containing info about UWB chips for a multi-HAL 91 * system, or a list of info for a single chip for a single HAL system. 92 */ getChipInfos()93 public List<ChipInfoParams> getChipInfos() { 94 return mChipInfoParamsList; 95 } 96 97 /** 98 * Returns the default UWB chip identifier. 99 * 100 * If callers do not pass a specific {@code chipId} to UWB methods, then the method will be 101 * invoked on the default chip, which is determined at system initialization from a 102 * configuration file. 103 * 104 * @return default UWB chip identifier for a multi-HAL system, or the identifier of the only UWB 105 * chip in a single HAL system. 106 */ getDefaultChipId()107 public String getDefaultChipId() { 108 return mDefaultChipId; 109 } 110 readConfigurationFile(String filePath)111 private void readConfigurationFile(String filePath) { 112 try { 113 InputStream stream = new BufferedInputStream(new FileInputStream(filePath)); 114 UwbChipConfig uwbChipConfig = XmlParser.read(stream); 115 mDefaultChipId = uwbChipConfig.getDefaultChipId(); 116 // Reset mChipInfoParamsList so that it can be populated with values from configuration 117 // file. 118 mChipInfoParamsList = new ArrayList<>(); 119 List<ChipGroupInfo> chipGroups = uwbChipConfig.getChipGroup(); 120 for (ChipGroupInfo chipGroup : chipGroups) { 121 List<ChipInfo> chips = chipGroup.getChip(); 122 for (ChipInfo chip : chips) { 123 String chipId = chip.getId(); 124 Coordinates position = chip.getPosition(); 125 double x, y, z; 126 if (position == null) { 127 x = 0.0; 128 y = 0.0; 129 z = 0.0; 130 } else { 131 x = position.getX() == null ? 0.0 : position.getX().doubleValue(); 132 y = position.getY() == null ? 0.0 : position.getY().doubleValue(); 133 z = position.getZ() == null ? 0.0 : position.getZ().doubleValue(); 134 } 135 Log.d(TAG, 136 "Chip with id " + chipId + " has position " + x + ", " + y + ", " + z); 137 mChipInfoParamsList 138 .add(ChipInfoParams.createBuilder() 139 .setChipId(chipId) 140 .setPositionX(x) 141 .setPositionY(y) 142 .setPositionZ(z).build()); 143 } 144 } 145 } catch (XmlPullParserException | IOException | DatatypeConfigurationException e) { 146 Log.e(TAG, "Cannot read file " + filePath, e); 147 } 148 } 149 } 150