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 availableUnitsId = configs.get(0).getConfigArray(); 98 99 Unit[] result = new Unit[availableUnitsId.size()]; 100 for (int unitId : availableUnitsId) { 101 if (UnitsMap.MAP.get(unitId) != null) { 102 Unit unit = UnitsMap.MAP.get(unitId); 103 units.add(unit); 104 } 105 } 106 for (int i = 0; i < result.length; i++) { 107 int unitId = availableUnitsId.get(i); 108 if (UnitsMap.MAP.get(unitId) != null) { 109 Unit unit = UnitsMap.MAP.get(unitId); 110 result[i] = unit; 111 } 112 } 113 return result; 114 } 115 getUnitUsedByProperty(int propertyId)116 protected Unit getUnitUsedByProperty(int propertyId) { 117 try { 118 int unitId = mCarPropertyManager.getIntProperty(propertyId, AREA_ID); 119 if (UnitsMap.MAP.get(unitId) != null) { 120 return UnitsMap.MAP.get(unitId); 121 } else { 122 return null; 123 } 124 } catch (CarNotConnectedException e) { 125 LOG.e("CarPropertyManager cannot get property because Car is not connected."); 126 return null; 127 } 128 } 129 setUnitUsedByProperty(int propertyId, int unitId)130 protected void setUnitUsedByProperty(int propertyId, int unitId) { 131 try { 132 mCarPropertyManager.setIntProperty(propertyId, AREA_ID, unitId); 133 } catch (CarNotConnectedException e) { 134 LOG.e("CarPropertyManager cannot set property because Car is not connected."); 135 } 136 } 137 138 /** 139 * Returns a boolean that indicates whether the unit is expressed in distance per volume (true) 140 * or volume per distance (false) for fuel consumption. Note that only distance over volume 141 * format is supported when Mile and Gallon (both US and UK) units are used. 142 */ isDistanceOverVolume()143 protected boolean isDistanceOverVolume() { 144 try { 145 return mCarPropertyManager.getBooleanProperty( 146 VehiclePropertyIds.FUEL_CONSUMPTION_UNITS_DISTANCE_OVER_VOLUME, AREA_ID); 147 } catch (CarNotConnectedException e) { 148 return true; // Defaults to True. 149 } 150 } 151 152 /** Defines callbacks that listen to {@link Car} service-related events. */ 153 public interface OnCarServiceListener { 154 /** 155 * Callback to be run when {@link Car} service is connected and {@link 156 * CarPropertyManager} becomes available. 157 */ handleServiceConnected(CarPropertyManager carPropertyManager)158 void handleServiceConnected(CarPropertyManager carPropertyManager); 159 160 /** Callback to be run when {@link Car} service is disconnected. */ handleServiceDisconnected()161 void handleServiceDisconnected(); 162 } 163 } 164