1 /* 2 * Copyright (C) 2019 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.car.settings.units; 18 19 import android.car.Car; 20 import android.car.CarNotConnectedException; 21 import android.car.VehiclePropertyIds; 22 import android.car.VehicleUnit; 23 import android.car.hardware.CarPropertyConfig; 24 import android.car.hardware.property.CarPropertyManager; 25 import android.content.Context; 26 import android.util.ArraySet; 27 28 import com.android.car.settings.common.Logger; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 /** Utility to read and write {@link Unit}-related properties in {@link CarPropertyManager}. */ 34 public class CarUnitsManager { 35 private static final Logger LOG = new Logger(CarUnitsManager.class); 36 private static final int AREA_ID = 0; 37 38 private Context mContext; 39 private Car mCar; 40 private CarPropertyManager mCarPropertyManager; 41 private OnCarServiceListener mCarServiceListener; 42 CarUnitsManager(Context context)43 public CarUnitsManager(Context context) { 44 mContext = context; 45 mCar = Car.createCar(mContext); 46 mCarPropertyManager = 47 (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE); 48 } 49 50 /** 51 * Registers {@link OnCarServiceListener} as a Callback for when connection to {@link Car} has 52 * been established. 53 */ registerCarServiceListener(OnCarServiceListener listener)54 public void registerCarServiceListener(OnCarServiceListener listener) { 55 mCarServiceListener = listener; 56 mCarServiceListener.handleServiceConnected(mCarPropertyManager); 57 } 58 59 /** 60 * Unregisters {@link OnCarServiceListener} as a Callback for when connection to {@link Car} has 61 * been terminated. 62 */ unregisterCarServiceListener()63 public void unregisterCarServiceListener() { 64 mCarServiceListener = null; 65 } 66 disconnect()67 protected void disconnect() { 68 mCar.disconnect(); 69 if (mCarServiceListener != null) { 70 mCarServiceListener.handleServiceDisconnected(); 71 } 72 } 73 isPropertyAvailable(int propertyId)74 protected boolean isPropertyAvailable(int propertyId) { 75 Integer intProperty = null; 76 77 try { 78 intProperty = mCarPropertyManager.getIntProperty(propertyId, AREA_ID); 79 } catch (CarNotConnectedException e) { 80 LOG.e("Property is unavailable because Car is not connected."); 81 } 82 83 return intProperty != null && intProperty != VehicleUnit.SHOULD_NOT_USE; 84 } 85 getUnitsSupportedByProperty(int propertyId)86 protected Unit[] getUnitsSupportedByProperty(int propertyId) { 87 ArraySet<Integer> propertyIdSet = new ArraySet<Integer>(); 88 propertyIdSet.add(propertyId); 89 List<CarPropertyConfig> configs = mCarPropertyManager.getPropertyList(propertyIdSet); 90 List<Integer> availableUnitsId = new ArrayList<Integer>(); 91 List<Unit> units = new ArrayList<Unit>(); 92 93 if (configs == null || configs.size() < 1 || configs.get(0) == null) { 94 return null; 95 } 96 97 // Checks if the property is read-write property 98 if (configs.get(0).getAccess() 99 != CarPropertyConfig.VEHICLE_PROPERTY_ACCESS_READ_WRITE) { 100 return null; 101 } 102 103 availableUnitsId = configs.get(0).getConfigArray(); 104 105 Unit[] result = new Unit[availableUnitsId.size()]; 106 for (int unitId : availableUnitsId) { 107 if (UnitsMap.MAP.get(unitId) != null) { 108 Unit unit = UnitsMap.MAP.get(unitId); 109 units.add(unit); 110 } 111 } 112 for (int i = 0; i < result.length; i++) { 113 int unitId = availableUnitsId.get(i); 114 if (UnitsMap.MAP.get(unitId) != null) { 115 Unit unit = UnitsMap.MAP.get(unitId); 116 result[i] = unit; 117 } 118 } 119 return result; 120 } 121 getUnitUsedByProperty(int propertyId)122 protected Unit getUnitUsedByProperty(int propertyId) { 123 try { 124 int unitId = mCarPropertyManager.getIntProperty(propertyId, AREA_ID); 125 if (UnitsMap.MAP.get(unitId) != null) { 126 return UnitsMap.MAP.get(unitId); 127 } else { 128 return null; 129 } 130 } catch (CarNotConnectedException e) { 131 LOG.e("CarPropertyManager cannot get property because Car is not connected."); 132 return null; 133 } 134 } 135 setUnitUsedByProperty(int propertyId, int unitId)136 protected void setUnitUsedByProperty(int propertyId, int unitId) { 137 try { 138 mCarPropertyManager.setIntProperty(propertyId, AREA_ID, unitId); 139 } catch (CarNotConnectedException e) { 140 LOG.e("CarPropertyManager cannot set property because Car is not connected."); 141 } 142 } 143 144 /** 145 * Returns a boolean that indicates whether the unit is expressed in distance per volume (true) 146 * or volume per distance (false) for fuel consumption. Note that only distance over volume 147 * format is supported when Mile and Gallon (both US and UK) units are used. 148 */ isDistanceOverVolume()149 protected boolean isDistanceOverVolume() { 150 try { 151 return mCarPropertyManager.getBooleanProperty( 152 VehiclePropertyIds.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, AREA_ID); 153 } catch (CarNotConnectedException e) { 154 return true; // Defaults to True. 155 } 156 } 157 158 /** Defines callbacks that listen to {@link Car} service-related events. */ 159 public interface OnCarServiceListener { 160 /** 161 * Callback to be run when {@link Car} service is connected and {@link 162 * CarPropertyManager} becomes available. 163 */ handleServiceConnected(CarPropertyManager carPropertyManager)164 void handleServiceConnected(CarPropertyManager carPropertyManager); 165 166 /** Callback to be run when {@link Car} service is disconnected. */ handleServiceDisconnected()167 void handleServiceDisconnected(); 168 } 169 } 170