RadioTuner.java revision 24250ef9481da08f26cdeb2ef7075783662f05ee
12035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent/* 22035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Copyright (C) 2015 The Android Open Source Project 32035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * 42035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 52035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * you may not use this file except in compliance with the License. 62035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * You may obtain a copy of the License at 72035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * 82035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * http://www.apache.org/licenses/LICENSE-2.0 92035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * 102035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Unless required by applicable law or agreed to in writing, software 112035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 122035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * See the License for the specific language governing permissions and 142035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * limitations under the License. 152035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 162035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 172035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurentpackage android.hardware.radio; 182035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 19d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczykimport android.annotation.NonNull; 20d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczykimport android.annotation.Nullable; 212035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurentimport android.annotation.SystemApi; 222035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurentimport android.os.Handler; 23c9a1ac78192e773d32462a3de899c7522c55ededTomasz Wasilczyk 24d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczykimport java.util.List; 252035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 262035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent/** 272035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * RadioTuner interface provides methods to control a radio tuner on the device: selecting and 282035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * configuring the active band, muting/unmuting, scanning and tuning, etc... 292035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * 302035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Obtain a RadioTuner interface by calling {@link RadioManager#openTuner(int, 312035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * RadioManager.BandConfig, boolean, RadioTuner.Callback, Handler)}. 322035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @hide 332035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 342035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent@SystemApi 352035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurentpublic abstract class RadioTuner { 362035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 372035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** Scanning direction UP for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */ 382035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static final int DIRECTION_UP = 0; 392035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 402035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** Scanning directions DOWN for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */ 412035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static final int DIRECTION_DOWN = 1; 422035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 432035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 442035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Close the tuner interface. The {@link Callback} callback will not be called 452035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * anymore and associated resources will be released. 462035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Must be called when the tuner is not needed to make hardware resources available to others. 472035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * */ 482035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract void close(); 492035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 502035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 512035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Set the active band configuration for this module. 522035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Must be a valid configuration obtained via buildConfig() from a valid BandDescriptor listed 532035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * in the ModuleProperties of the module with the specified ID. 542035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param config The desired band configuration (FmBandConfig or AmBandConfig). 552035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 562035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 572035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 582035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 592035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 602035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 612035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 622035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 632035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 642035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 652035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 662035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int setConfiguration(RadioManager.BandConfig config); 672035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 682035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 692035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Get current configuration. 702035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param config a BandConfig array of lengh 1 where the configuration is returned. 712035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 722035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 732035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 742035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 752035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 762035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 772035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 782035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 792035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 802035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 812035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 822035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int getConfiguration(RadioManager.BandConfig[] config); 832035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 842035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 852035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 862035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Set mute state. When muted, the radio tuner audio source is not available for playback on 872035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * any audio device. when unmuted, the radio tuner audio source is output as a media source 882035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * and renderd over the audio device selected for media use case. 892035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The radio tuner audio source is muted by default when the tuner is first attached. 902035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Only effective if the tuner is attached with audio enabled. 912035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * 922035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param mute the requested mute state. 932035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 942035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 952035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 962035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 972035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 982035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 992035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 1002035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 1012035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 1022035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 1032035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int setMute(boolean mute); 1042035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 1052035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 1062035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Get mute state. 1072035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * 1082035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return {@code true} if the radio tuner audio source is muted or a problem occured 1092035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * retrieving the mute state, {@code false} otherwise. 1102035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 1112035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract boolean getMute(); 1122035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 1132035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 1142035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Step up or down by one channel spacing. 1152035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The operation is asynchronous and {@link Callback} 1162035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onProgramInfoChanged() will be called when step completes or 1172035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onError() when cancelled or timeout. 1182035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}. 1192035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param skipSubChannel indicates to skip sub channels when the configuration currently 1202035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * selected supports sub channel (e.g HD Radio). N/A otherwise. 1212035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 1222035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 1232035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 1242035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 1252035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 1262035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 1272035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 1282035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 1292035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 1302035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 1312035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 1322035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int step(int direction, boolean skipSubChannel); 1332035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 1342035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 1352035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Scan up or down to next valid station. 1362035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The operation is asynchronous and {@link Callback} 1372035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onProgramInfoChanged() will be called when scan completes or 1382035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onError() when cancelled or timeout. 1392035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}. 1402035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param skipSubChannel indicates to skip sub channels when the configuration currently 1412035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * selected supports sub channel (e.g HD Radio). N/A otherwise. 1422035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 1432035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 1442035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 1452035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 1462035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 1472035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 1482035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 1492035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 1502035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 1512035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 1522035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 1532035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int scan(int direction, boolean skipSubChannel); 1542035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 1552035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 1562035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Tune to a specific frequency. 1572035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The operation is asynchronous and {@link Callback} 1582035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onProgramInfoChanged() will be called when tune completes or 1592035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onError() when cancelled or timeout. 1602035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param channel the specific channel or frequency to tune to. 1612035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param subChannel the specific sub-channel to tune to. N/A if the selected configuration 1622035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * does not support cub channels. 1632035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 1642035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 1652035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 1662035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 1672035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 1682035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 1692035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 1702035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 1712035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 1722035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 1738cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk * @deprecated Use {@link tune(ProgramSelector)} instead. 1742035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 1758cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk @Deprecated 1762035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int tune(int channel, int subChannel); 1772035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 1782035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 1798cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk * Tune to a program. 1808cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk * 1818cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk * The operation is asynchronous and {@link Callback} onProgramInfoChanged() will be called 1828cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk * when tune completes or onError() when cancelled or on timeout. 1838cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk * 1848cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk * @thows IllegalArgumentException if the provided selector is invalid 1858cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk */ 1868cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk public abstract void tune(@NonNull ProgramSelector selector); 1878cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk 1888cfb0e81fdd91b7fe1c02287394ac068287281d5Tomasz Wasilczyk /** 1892035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Cancel a pending scan or tune operation. 1902035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * If an operation is pending, {@link Callback} onError() will be called with 1912035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@link #ERROR_CANCELLED}. 1922035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 1932035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 1942035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 1952035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 1962035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 1972035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 1982035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 1992035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 2002035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 2012035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 2022035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 2032035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int cancel(); 2042035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 2052035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 2062035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Get current station information. 2072035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @param info a ProgramInfo array of lengh 1 where the information is returned. 2082035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return 2092035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <ul> 2102035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_OK} in case of success, </li> 2112035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li> 2122035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li> 2132035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li> 2142035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li> 2152035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native 2162035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * service fails, </li> 2172035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * </ul> 2182035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 2192035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract int getProgramInformation(RadioManager.ProgramInfo[] info); 2202035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 2212035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 222e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * Initiates a background scan to update internally cached program list. 223e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * 224e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot. 225e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * 226e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will 227e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * be called if the return value of this call was {@code true}. As result of this call 228e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * programListChanged may be triggered (if the scanned list differs). 229e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * 230e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature 231e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device 232e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * or permanently if the feature is not supported 233e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * (see ModuleProperties#isBackgroundScanningSupported()). 234e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk */ 235e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk public abstract boolean startBackgroundScan(); 236e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk 237e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk /** 238d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * Get the list of discovered radio stations. 239d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * 240d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * To get the full list, set filter to null or empty string. Otherwise, client application 241d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * must verify vendor product/name before setting this parameter to anything else. 242d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * 243d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * @param filter vendor-specific selector for radio stations. 244d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * @return a list of radio stations. 245e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * @throws IllegalStateException if the scan is in progress or has not been started, 246e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * startBackgroundScan() call may fix it. 247d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk * @throws IllegalArgumentException if the filter argument is not valid. 248d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk */ 249d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk public abstract @NonNull List<RadioManager.ProgramInfo> getProgramList(@Nullable String filter); 250d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk 251d44b2ea109d3039f2aeba237f86d0db51c3ba648Tomasz Wasilczyk /** 2525f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * Checks, if the analog playback is forced, see setAnalogForced. 2535f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * 2545f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * @throws IllegalStateException if the switch is not supported at current 2555f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * configuration. 2565f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * @return {@code true} if analog is forced, {@code false} otherwise. 2575f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk */ 2585f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk public abstract boolean isAnalogForced(); 2595f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk 2605f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk /** 2615f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * Forces the analog playback for the supporting radio technology. 2625f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * 2635f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * User may disable digital playback for FM HD Radio or hybrid FM/DAB with 2645f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * this option. This is purely user choice, ie. does not reflect digital- 2655f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * analog handover managed from the HAL implementation side. 2665f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * 2675f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * Some radio technologies may not support this, ie. DAB. 2685f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * 2695f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * @param isForced {@code true} to force analog, {@code false} for a default behaviour. 2705f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * @throws IllegalStateException if the switch is not supported at current 2715f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk * configuration. 2725f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk */ 2735f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk public abstract void setAnalogForced(boolean isForced); 2745f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk 2755f0fbaef380b6d462429c57f85a0e624c62aefbfTomasz Wasilczyk /** 2762035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Get current antenna connection state for current configuration. 2772035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Only valid if a configuration has been applied. 2782035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return {@code true} if the antenna is connected, {@code false} otherwise. 2792035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 2802035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract boolean isAntennaConnected(); 2812035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 2822035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 2832035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Indicates if this client actually controls the tuner. 2842035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Control is always granted after 2852035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@link RadioManager#openTuner(int, 2862035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * RadioManager.BandConfig, boolean, Callback, Handler)} 2872035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * returns a non null tuner interface. 2882035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Control is lost when another client opens an interface on the same tuner. 2892035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * When this happens, {@link Callback#onControlChanged(boolean)} is received. 2902035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The client can either wait for control to be returned (which is indicated by the same 2912035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * callback) or close and reopen the tuner interface. 2922035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * @return {@code true} if this interface controls the tuner, 2932035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@code false} otherwise or if a problem occured retrieving the state. 2942035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 2952035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public abstract boolean hasControl(); 2962035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 2972035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** Indicates a failure of radio IC or driver. 2982035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The application must close and re open the tuner */ 2992035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static final int ERROR_HARDWARE_FAILURE = 0; 3002035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** Indicates a failure of the radio service. 3012035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The application must close and re open the tuner */ 3022035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static final int ERROR_SERVER_DIED = 1; 3032035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** A pending seek or tune operation was cancelled */ 3042035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static final int ERROR_CANCELLED = 2; 3052035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** A pending seek or tune operation timed out */ 3062035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static final int ERROR_SCAN_TIMEOUT = 3; 3072035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** The requested configuration could not be applied */ 3082035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static final int ERROR_CONFIG = 4; 30905392d6360b89538aa8fcbb1afd50775adfadcf4Tomasz Wasilczyk /** Background scan was interrupted due to hardware becoming temporarily unavailable. */ 310c9a1ac78192e773d32462a3de899c7522c55ededTomasz Wasilczyk public static final int ERROR_BACKGROUND_SCAN_UNAVAILABLE = 5; 31105392d6360b89538aa8fcbb1afd50775adfadcf4Tomasz Wasilczyk /** Background scan failed due to other error, ie. HW failure. */ 312c9a1ac78192e773d32462a3de899c7522c55ededTomasz Wasilczyk public static final int ERROR_BACKGROUND_SCAN_FAILED = 6; 3132035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 3142035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 3152035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * Callback provided by the client application when opening a {@link RadioTuner} 3162035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * to receive asynchronous operation results, updates and error notifications. 3172035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 3182035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public static abstract class Callback { 3192035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 3202035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onError() is called when an error occured while performing an asynchronous 3212035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * operation of when the hardware or system service experiences a problem. 3222035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * status is one of {@link #ERROR_HARDWARE_FAILURE}, {@link #ERROR_SERVER_DIED}, 3232035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@link #ERROR_CANCELLED}, {@link #ERROR_SCAN_TIMEOUT}, 3242035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@link #ERROR_CONFIG} 3252035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 3262035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public void onError(int status) {} 3272035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 3282035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onConfigurationChanged() is called upon successful completion of 3292035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)} 3302035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * or {@link RadioTuner#setConfiguration(RadioManager.BandConfig)} 3312035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 3322035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public void onConfigurationChanged(RadioManager.BandConfig config) {} 33324250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk 3342035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 33524250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * Called when program info (including metadata) for the current program has changed. 33624250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * 33724250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * It happens either upon successful completion of {@link RadioTuner#step(int, boolean)}, 33824250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * {@link RadioTuner#scan(int, boolean)}, {@link RadioTuner#tune(int, int)}; when 33924250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * a switching to alternate frequency occurs; or when metadata is updated. 3402035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 3412035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public void onProgramInfoChanged(RadioManager.ProgramInfo info) {} 34224250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk 3432035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 34424250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * Called when metadata is updated for the current program. 34524250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * 34624250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * @deprecated Use {@link #onProgramInfoChanged(RadioManager.ProgramInfo)} instead. 3472035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 34824250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk @Deprecated 3492035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public void onMetadataChanged(RadioMetadata metadata) {} 35024250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk 3512035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 3522035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onTrafficAnnouncement() is called when a traffic announcement starts and stops. 3532035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 3542035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public void onTrafficAnnouncement(boolean active) {} 3552035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 3567058e4ca585a06462a495d021d61e1fd27f85cd2Sanket Agarwal * onEmergencyAnnouncement() is called when an emergency annoucement starts and stops. 3577058e4ca585a06462a495d021d61e1fd27f85cd2Sanket Agarwal */ 3587058e4ca585a06462a495d021d61e1fd27f85cd2Sanket Agarwal public void onEmergencyAnnouncement(boolean active) {} 3597058e4ca585a06462a495d021d61e1fd27f85cd2Sanket Agarwal /** 3602035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onAntennaState() is called when the antenna is connected or disconnected. 3612035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 3622035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public void onAntennaState(boolean connected) {} 3632035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent /** 3642035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * onControlChanged() is called when the client loses or gains control of the radio tuner. 3652035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * The control is always granted after a successful call to 3662035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)}. 3672035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * If another client opens the same tuner, onControlChanged() will be called with 3682035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * control set to {@code false} to indicate loss of control. 3692035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * At this point, RadioTuner APIs other than getters will return 3702035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * {@link RadioManager#STATUS_INVALID_OPERATION}. 3712035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * When the other client releases the tuner, onControlChanged() will be called 3722035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent * with control set to {@code true}. 3732035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent */ 3742035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent public void onControlChanged(boolean control) {} 375e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk 376e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk /** 377e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * onBackgroundScanAvailabilityChange() is called when background scan 378e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * feature becomes available or not. 379e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * 380e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * @param isAvailable true, if the tuner turned temporarily background- 381e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * capable, false in the other case. 382e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk */ 383e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk public void onBackgroundScanAvailabilityChange(boolean isAvailable) {} 384e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk 385e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk /** 386e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * Called when a background scan completes successfully. 387e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk */ 388e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk public void onBackgroundScanComplete() {} 389e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk 390e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk /** 391e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * Called when available program list changed. 392e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk * 39324250ef9481da08f26cdeb2ef7075783662f05eeTomasz Wasilczyk * Use {@link RadioTuner#getProgramList(String)} to get an actual list. 394e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk */ 395e597ce15b3c110036fcaff4fee8cfc94fd97b3ceTomasz Wasilczyk public void onProgramListChanged() {} 3962035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent } 3972035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 3982035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent} 3992035ac85f61b0e7fa384d52fcfa99766424c122cEric Laurent 400