13cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal/* 23cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * Copyright (C) 2015 The Android Open Source Project 33cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 43cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * Licensed under the Apache License, Version 2.0 (the "License"); 53cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * you may not use this file except in compliance with the License. 63cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * You may obtain a copy of the License at 73cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 83cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * http://www.apache.org/licenses/LICENSE-2.0 93cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 103cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * Unless required by applicable law or agreed to in writing, software 113cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * distributed under the License is distributed on an "AS IS" BASIS, 123cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * See the License for the specific language governing permissions and 143cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * limitations under the License. 153cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 163cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 173cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalpackage com.android.car.hal; 183cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 190d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsevimport android.annotation.Nullable; 20e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.car.hardware.radio.CarRadioEvent; 21e54ac276796c6535558f8444d882adecd19ce2bdKeun-young Parkimport android.car.hardware.radio.CarRadioPreset; 223cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport android.hardware.radio.RadioManager; 23cfe93105f637c2822da113308f113ed418d0b319Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehiclePropConfig; 24cfe93105f637c2822da113308f113ed418d0b319Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehiclePropValue; 25cfe93105f637c2822da113308f113ed418d0b319Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehicleProperty; 26cfe93105f637c2822da113308f113ed418d0b319Pavel Maltsevimport android.hardware.automotive.vehicle.V2_0.VehicleRadioConstants; 270d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsevimport android.util.Log; 283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport com.android.car.CarLog; 303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 310d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsevimport java.io.PrintWriter; 320d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsevimport java.util.Arrays; 330d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsevimport java.util.Collection; 343cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport java.util.LinkedList; 353cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalimport java.util.List; 363cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 373cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal/** 383cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * This class exposes the Radio related features in the HAL layer. 393cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * 403cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * The current set of features support radio presets. The rest of the radio functionality is already 413cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal * covered under RadioManager API. 423cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal */ 433cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwalpublic class RadioHalService extends HalServiceBase { 441b1247b5648975dd41ee73c25425825abb256234Vitalii Tomkiv public static boolean DBG = false; 453cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public static String TAG = CarLog.TAG_HAL + ".RadioHalService"; 463cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 473cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal private int mPresetCount = 0; 483cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal private VehicleHal mHal; 493cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal private RadioListener mListener; 503cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 513cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public interface RadioListener { 520d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev void onEvent(CarRadioEvent event); 533cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 543cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 553cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public RadioHalService(VehicleHal hal) { 563cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal mHal = hal; 573cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 583cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 593cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal @Override 603cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public synchronized void init() { 613cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 623cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 633cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal @Override 643cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public synchronized void release() { 653cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal mListener = null; 663cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 673cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 683cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal @Override 690d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev public synchronized Collection<VehiclePropConfig> takeSupportedProperties( 700d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev Collection<VehiclePropConfig> allProperties) { 710d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev Collection<VehiclePropConfig> supported = new LinkedList<>(); 723cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal for (VehiclePropConfig p : allProperties) { 733cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (handleRadioProperty(p)) { 743cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal supported.add(p); 753cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 763cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 773cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return supported; 783cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 793cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 803cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal @Override 813cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public void handleHalEvents(List<VehiclePropValue> values) { 823cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (DBG) { 833cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "handleHalEvents"); 843cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 850d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev RadioHalService.RadioListener radioListener; 863cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal synchronized (this) { 873cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal radioListener = mListener; 883cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 893cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 903cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (radioListener == null) { 913cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.e(TAG, "radio listener is null, ignoring event: " + values); 923cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return; 933cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 943cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 953cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal for (VehiclePropValue v : values) { 963cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal CarRadioEvent radioEvent = createCarRadioEvent(v); 973cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (radioEvent != null) { 983cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (DBG) { 993cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "Sending event to listener: " + radioEvent); 1003cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1013cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal radioListener.onEvent(radioEvent); 1023cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } else { 1033cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.w(TAG, "Value conversion failed: " + v); 1043cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1053cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1063cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1073cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1083cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal @Override 1093cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public void dump(PrintWriter writer) { 1103cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal writer.println("*RadioHal*"); 1113cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal writer.println("**Supported properties**"); 1120d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev writer.println(VehicleProperty.RADIO_PRESET); 1133cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (mListener != null) { 1143cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal writer.println("Hal service registered."); 1153cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1163cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1173cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1183cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public synchronized void registerListener(RadioListener listener) { 1193cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (DBG) { 1203cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "registerListener"); 1213cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1223cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal mListener = listener; 1233cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1243cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Subscribe to all radio properties. 12579d5e12ad8708c1f7f7f1a60aaeb349ac7ed0f7bPavel Maltsev mHal.subscribeProperty(this, VehicleProperty.RADIO_PRESET); 1263cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1273cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public synchronized void unregisterListener() { 1293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (DBG) { 1303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "unregisterListener"); 1313cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1323cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal mListener = null; 1333cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1340d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev // Unsubscribe from all properties. 1350d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev mHal.unsubscribeProperty(this, VehicleProperty.RADIO_PRESET); 1363cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1373cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1383cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public synchronized int getPresetCount() { 1393cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "get preset count: " + mPresetCount); 1403cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return mPresetCount; 1413cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1423cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1430d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev @Nullable 1443cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public CarRadioPreset getRadioPreset(int presetNumber) { 1453cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Check if the preset number is out of range. We should return NULL if that is the case. 1463cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (DBG) { 1473cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "getRadioPreset called with preset number " + presetNumber); 1483cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1493cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (!isValidPresetNumber(presetNumber)) { 1503cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw new IllegalArgumentException("Preset number not valid: " + presetNumber); 1513cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1523cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1530d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev VehiclePropValue presetNumberValue = new VehiclePropValue(); 1540d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev presetNumberValue.prop = VehicleProperty.RADIO_PRESET; 1550d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev presetNumberValue.value.int32Values.addAll(Arrays.asList(presetNumber, 0, 0, 0)); 1563cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 157ba48548a489950968d212ffbfd8772ef1349cd60Keun-young Park VehiclePropValue presetConfig; 158ba48548a489950968d212ffbfd8772ef1349cd60Keun-young Park try { 1590d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev presetConfig = mHal.get(presetNumberValue); 1600d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev } catch (PropertyTimeoutException e) { 1610d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev Log.e(TAG, "property VehicleProperty.RADIO_PRESET not ready", e); 162ba48548a489950968d212ffbfd8772ef1349cd60Keun-young Park return null; 163ba48548a489950968d212ffbfd8772ef1349cd60Keun-young Park } 1643cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Sanity check the output from HAL. 1650d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev if (presetConfig.value.int32Values.size() != 4) { 1663cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.e(TAG, "Return value does not have 4 elements: " + 1670d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev Arrays.toString(presetConfig.value.int32Values.toArray())); 1683cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal throw new IllegalStateException( 1690d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev "Invalid preset returned from service: " 1700d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev + Arrays.toString(presetConfig.value.int32Values.toArray())); 1713cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1723cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1730d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev int retPresetNumber = presetConfig.value.int32Values.get(0); 1740d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev int retBand = presetConfig.value.int32Values.get(1); 1750d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev int retChannel = presetConfig.value.int32Values.get(2); 1760d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev int retSubChannel = presetConfig.value.int32Values.get(3); 1773cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (retPresetNumber != presetNumber) { 1783cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.e(TAG, "Preset number is not the same: " + presetNumber + " vs " + retPresetNumber); 1793cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return null; 1803cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1813cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (!isValidBand(retBand)) return null; 1823cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1833cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Return the actual config. 1843cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal CarRadioPreset retConfig = 1853cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal new CarRadioPreset(retPresetNumber, retBand, retChannel, retSubChannel); 1863cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (DBG) { 1873cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "Preset obtained: " + retConfig); 1883cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1893cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return retConfig; 1903cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1913cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1923cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal public boolean setRadioPreset(CarRadioPreset preset) { 1933cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (DBG) { 1943cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "setRadioPreset with config " + preset); 1953cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 1963cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 1973cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (!isValidPresetNumber(preset.getPresetNumber()) || 1983cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal !isValidBand(preset.getBand())) { 1993cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return false; 2003cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2013cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 202e78bf53959151d07c90bbb69fd3f99240dd139b1Keun-young Park try { 2030d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev mHal.set(VehicleProperty.RADIO_PRESET).to(new int[] { 2040d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev preset.getPresetNumber(), 2050d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev preset.getBand(), 2060d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev preset.getChannel(), 2070d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev preset.getSubChannel()}); 2080d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev } catch (PropertyTimeoutException e) { 209e78bf53959151d07c90bbb69fd3f99240dd139b1Keun-young Park Log.e(CarLog.TAG_POWER, "cannot set to RADIO_PRESET", e); 210e78bf53959151d07c90bbb69fd3f99240dd139b1Keun-young Park return false; 211e78bf53959151d07c90bbb69fd3f99240dd139b1Keun-young Park } 2123cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return true; 2133cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2143cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 2153cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal private boolean isValidPresetNumber(int presetNumber) { 2163cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Check for preset number. 2170d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev if (presetNumber < VehicleRadioConstants.VEHICLE_RADIO_PRESET_MIN_VALUE 2183cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal || presetNumber > mPresetCount) { 2193cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.e(TAG, "Preset number not in range (1, " + mPresetCount + ") - " + presetNumber); 2203cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return false; 2213cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2223cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return true; 2233cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2243cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 2253cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal private boolean isValidBand(int band) { 2263cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Check for band info. 2273cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (band != RadioManager.BAND_AM && 2283cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal band != RadioManager.BAND_FM && 2293cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal band != RadioManager.BAND_FM_HD && 2303cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal band != RadioManager.BAND_AM_HD) { 2313cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.e(TAG, "Preset band is not valid: " + band); 2323cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return false; 2333cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2343cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return true; 2353cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2363cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 2373cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal private boolean handleRadioProperty(VehiclePropConfig property) { 2380d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev switch (property.prop) { 2390d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev case VehicleProperty.RADIO_PRESET: 2403cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Extract the count of presets. 2410d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev mPresetCount = property.configArray.get(0); 2423cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.d(TAG, "Read presets count: " + mPresetCount); 2433cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return true; 2443cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal default: 2453cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return false; 2463cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2473cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Should never come here. 2483cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2493cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 2503cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal private CarRadioEvent createCarRadioEvent(VehiclePropValue v) { 2510d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev switch (v.prop) { 2520d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev case VehicleProperty.RADIO_PRESET: 2530d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev int vecSize = v.value.int32Values.size(); 2540d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev if (vecSize != 4) { 2550d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev Log.e(TAG, "Returned a wrong array size: " + vecSize); 2563cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return null; 2573cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2583cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 2593cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Integer intValues[] = new Integer[4]; 2600d07c76bbc788fba8c77d8e932330ab22ec6ba27Pavel Maltsev v.value.int32Values.toArray(intValues); 2613cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 2623cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal // Verify the correctness of the values. 2633cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal if (!isValidPresetNumber(intValues[0]) && !isValidBand(intValues[1])) { 2643cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return null; 2653cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2663cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal 2673cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal CarRadioPreset preset = 2683cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal new CarRadioPreset(intValues[0], intValues[1], intValues[2], intValues[3]); 2693cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal CarRadioEvent event = new CarRadioEvent(CarRadioEvent.RADIO_PRESET, preset); 2703cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return event; 2713cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal default: 2723cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal Log.e(TAG, "createCarRadioEvent: Value not supported as event: " + v); 2733cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal return null; 2743cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2753cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal } 2763cf096ae0d992d22cfba1b0711af2211c511a9feSanket Agarwal} 277