content: /*
   * Copyright (C) 2015 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.hardware.radio;
  
  import android.annotation.NonNull;
  import android.annotation.Nullable;
  import android.annotation.SystemApi;
  import android.graphics.Bitmap;
  import android.os.Handler;
  
  import java.util.List;
  import java.util.Map;
  
  /**
   * RadioTuner interface provides methods to control a radio tuner on the device: selecting and
   * configuring the active band, muting/unmuting, scanning and tuning, etc...
   *
   * Obtain a RadioTuner interface by calling {@link RadioManager#openTuner(int,
   * RadioManager.BandConfig, boolean, RadioTuner.Callback, Handler)}.
   * @hide
   */
  @SystemApi
  public abstract class RadioTuner {
  
      /** Scanning direction UP for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */
      public static final int DIRECTION_UP      = 0;
  
      /** Scanning directions DOWN for {@link #step(int, boolean)}, {@link #scan(int, boolean)} */
      public static final int DIRECTION_DOWN    = 1;
  
      /**
       * Close the tuner interface. The {@link Callback} callback will not be called
       * anymore and associated resources will be released.
       * Must be called when the tuner is not needed to make hardware resources available to others.
       * */
      public abstract void close();
  
      /**
       * Set the active band configuration for this module.
       * Must be a valid configuration obtained via buildConfig() from a valid BandDescriptor listed
       * in the ModuleProperties of the module with the specified ID.
       * @param config The desired band configuration (FmBandConfig or AmBandConfig).
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       * @deprecated Only applicable for HAL 1.x.
       */
      @Deprecated
      public abstract int setConfiguration(RadioManager.BandConfig config);
  
      /**
       * Get current configuration.
       * @param config a BandConfig array of lengh 1 where the configuration is returned.
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       *
       * @deprecated Only applicable for HAL 1.x.
       */
      @Deprecated
      public abstract int getConfiguration(RadioManager.BandConfig[] config);
  
  
      /**
       * Set mute state. When muted, the radio tuner audio source is not available for playback on
       * any audio device. when unmuted, the radio tuner audio source is output as a media source
       * and renderd over the audio device selected for media use case.
       * The radio tuner audio source is muted by default when the tuner is first attached.
       * Only effective if the tuner is attached with audio enabled.
       *
       * @param mute the requested mute state.
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       */
      public abstract int setMute(boolean mute);
  
      /**
       * Get mute state.
       *
       * @return {@code true} if the radio tuner audio source is muted or a problem occured
       * retrieving the mute state, {@code false} otherwise.
       */
      public abstract boolean getMute();
  
      /**
       * Step up or down by one channel spacing.
       * The operation is asynchronous and {@link Callback}
       * onProgramInfoChanged() will be called when step completes or
       * onError() when cancelled or timeout.
       * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}.
       * @param skipSubChannel indicates to skip sub channels when the configuration currently
       * selected supports sub channel (e.g HD Radio). N/A otherwise.
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       */
      public abstract int step(int direction, boolean skipSubChannel);
  
      /**
       * Scan up or down to next valid station.
       * The operation is asynchronous and {@link Callback}
       * onProgramInfoChanged() will be called when scan completes or
       * onError() when cancelled or timeout.
       * @param direction {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}.
       * @param skipSubChannel indicates to skip sub channels when the configuration currently
       * selected supports sub channel (e.g HD Radio). N/A otherwise.
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       */
      public abstract int scan(int direction, boolean skipSubChannel);
  
      /**
       * Tune to a specific frequency.
       * The operation is asynchronous and {@link Callback}
       * onProgramInfoChanged() will be called when tune completes or
       * onError() when cancelled or timeout.
       * @param channel the specific channel or frequency to tune to.
       * @param subChannel the specific sub-channel to tune to. N/A if the selected configuration
       * does not support cub channels.
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       * @deprecated Use {@link tune(ProgramSelector)} instead.
       */
      @Deprecated
      public abstract int tune(int channel, int subChannel);
  
      /**
       * Tune to a program.
       *
       * The operation is asynchronous and {@link Callback} onProgramInfoChanged() will be called
       * when tune completes or onError() when cancelled or on timeout.
       *
       * @throws IllegalArgumentException if the provided selector is invalid
       */
      public abstract void tune(@NonNull ProgramSelector selector);
  
      /**
       * Cancel a pending scan or tune operation.
       * If an operation is pending, {@link Callback} onError() will be called with
       * {@link #ERROR_CANCELLED}.
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       */
      public abstract int cancel();
  
      /**
       * Cancels traffic or emergency announcement.
       *
       * If there was no announcement to cancel, no action is taken.
       *
       * There is a race condition between calling cancelAnnouncement and the actual announcement
       * being finished, so onTrafficAnnouncement / onEmergencyAnnouncement callback should be
       * tracked with proper locking.
       */
      public abstract void cancelAnnouncement();
  
      /**
       * Get current station information.
       * @param info a ProgramInfo array of lengh 1 where the information is returned.
       * @return
       * <ul>
       *  <li>{@link RadioManager#STATUS_OK} in case of success, </li>
       *  <li>{@link RadioManager#STATUS_ERROR} in case of unspecified error, </li>
       *  <li>{@link RadioManager#STATUS_NO_INIT} if the native service cannot be reached, </li>
       *  <li>{@link RadioManager#STATUS_BAD_VALUE} if parameters are invalid, </li>
       *  <li>{@link RadioManager#STATUS_INVALID_OPERATION} if the call is out of sequence, </li>
       *  <li>{@link RadioManager#STATUS_DEAD_OBJECT} if the binder transaction to the native
       *  service fails, </li>
       * </ul>
       * @deprecated Use {@link onProgramInfoChanged} callback instead.
       */
      @Deprecated
      public abstract int getProgramInformation(RadioManager.ProgramInfo[] info);
  
      /**
       * Retrieves a {@link Bitmap} for the given image ID or null,
       * if the image was missing from the tuner.
       *
       * This involves doing a call to the tuner, so the bitmap should be cached
       * on the application side.
       *
       * If the method returns null for non-zero ID, it means the image was
       * updated on the tuner side. There is a race conditon between fetching
       * image for an old ID and tuner updating the image (and cleaning up the
       * old image). In such case, a new ProgramInfo with updated image id will
       * be sent with a {@link onProgramInfoChanged} callback.
       *
       * @param id The image identifier, retrieved with
       *           {@link RadioMetadata#getBitmapId(String)}.
       * @return A {@link Bitmap} or null.
       * @throws IllegalArgumentException if id==0
       * @hide This API is not thoroughly elaborated yet
       */
      public abstract @Nullable Bitmap getMetadataImage(int id);
  
      /**
       * Initiates a background scan to update internally cached program list.
       *
       * It may not be necessary to initiate the scan explicitly - the scan MAY be performed on boot.
       *
       * The operation is asynchronous and {@link Callback} backgroundScanComplete or onError will
       * be called if the return value of this call was {@code true}. As result of this call
       * programListChanged may be triggered (if the scanned list differs).
       *
       * @return {@code true} if the scan was properly scheduled, {@code false} if the scan feature
       * is unavailable; ie. temporarily due to ongoing foreground playback in single-tuner device
       * or permanently if the feature is not supported
       * (see ModuleProperties#isBackgroundScanningSupported()).
       */
      public abstract boolean startBackgroundScan();
  
      /**
       * Get the list of discovered radio stations.
       *
       * To get the full list, set filter to null or empty map.
       * Keys must be prefixed with unique vendor Java-style namespace,
       * eg. 'com.somecompany.parameter1'.
       *
       * @param vendorFilter vendor-specific selector for radio stations.
       * @return a list of radio stations.
       * @throws IllegalStateException if the scan is in progress or has not been started,
       *         startBackgroundScan() call may fix it.
       * @throws IllegalArgumentException if the vendorFilter argument is not valid.
       * @deprecated Use {@link getDynamicProgramList} instead.
       */
      @Deprecated
      public abstract @NonNull List<RadioManager.ProgramInfo>
              getProgramList(@Nullable Map<String, String> vendorFilter);
  
      /**
       * Get the dynamic list of discovered radio stations.
       *
       * The list object is updated asynchronously; to get the updates register
       * with {@link ProgramList#addListCallback}.
       *
       * When the returned object is no longer used, it must be closed.
       *
       * @param filter filter for the list, or null to get the full list.
       * @return the dynamic program list object, close it after use
       *         or {@code null} if program list is not supported by the tuner
       */
      public @Nullable ProgramList getDynamicProgramList(@Nullable ProgramList.Filter filter) {
          return null;
      }
  
      /**
       * Checks, if the analog playback is forced, see setAnalogForced.
       *
       * @throws IllegalStateException if the switch is not supported at current
       *         configuration.
       * @return {@code true} if analog is forced, {@code false} otherwise.
       * @deprecated Use {@link isConfigFlagSet(int)} instead.
       */
      @Deprecated
      public abstract boolean isAnalogForced();
  
      /**
       * Forces the analog playback for the supporting radio technology.
       *
       * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
       * this option. This is purely user choice, ie. does not reflect digital-
       * analog handover managed from the HAL implementation side.
       *
       * Some radio technologies may not support this, ie. DAB.
       *
       * @param isForced {@code true} to force analog, {@code false} for a default behaviour.
       * @throws IllegalStateException if the switch is not supported at current
       *         configuration.
       * @deprecated Use {@link setConfigFlag(int, boolean)} instead.
       */
      @Deprecated
      public abstract void setAnalogForced(boolean isForced);
  
      /**
       * Checks, if a given config flag is supported
       *
       * @param flag Flag to check.
       * @return True, if the flag is supported.
       */
      public boolean isConfigFlagSupported(@RadioManager.ConfigFlag int flag) {
          return false;
      }
  
      /**
       * Fetches the current setting of a given config flag.
       *
       * The success/failure result is consistent with isConfigFlagSupported.
       *
       * @param flag Flag to fetch.
       * @return The current value of the flag.
       * @throws IllegalStateException if the flag is not applicable right now.
       * @throws UnsupportedOperationException if the flag is not supported at all.
       */
      public boolean isConfigFlagSet(@RadioManager.ConfigFlag int flag) {
          throw new UnsupportedOperationException();
      }
  
      /**
       * Sets the config flag.
       *
       * The success/failure result is consistent with isConfigFlagSupported.
       *
       * @param flag Flag to set.
       * @param value The new value of a given flag.
       * @throws IllegalStateException if the flag is not applicable right now.
       * @throws UnsupportedOperationException if the flag is not supported at all.
       */
      public void setConfigFlag(@RadioManager.ConfigFlag int flag, boolean value) {
          throw new UnsupportedOperationException();
      }
  
      /**
       * Generic method for setting vendor-specific parameter values.
       * The framework does not interpret the parameters, they are passed
       * in an opaque manner between a vendor application and HAL.
       *
       * Framework does not make any assumptions on the keys or values, other than
       * ones stated in VendorKeyValue documentation (a requirement of key
       * prefixes).
       * See VendorKeyValue at hardware/interfaces/broadcastradio/2.0/types.hal.
       *
       * For each pair in the result map, the key will be one of the keys
       * contained in the input (possibly with wildcards expanded), and the value
       * will be a vendor-specific result status (such as "OK" or an error code).
       * The implementation may choose to return an empty map, or only return
       * a status for a subset of the provided inputs, at its discretion.
       *
       * Application and HAL must not use keys with unknown prefix. In particular,
       * it must not place a key-value pair in results vector for unknown key from
       * parameters vector - instead, an unknown key should simply be ignored.
       * In other words, results vector may contain a subset of parameter keys
       * (however, the framework doesn't enforce a strict subset - the only
       * formal requirement is vendor domain prefix for keys).
       *
       * @param parameters Vendor-specific key-value pairs.
       * @return Operation completion status for parameters being set.
       */
      public @NonNull Map<String, String>
              setParameters(@NonNull Map<String, String> parameters) {
          throw new UnsupportedOperationException();
      }
  
      /**
       * Generic method for retrieving vendor-specific parameter values.
       * The framework does not interpret the parameters, they are passed
       * in an opaque manner between a vendor application and HAL.
       *
       * Framework does not cache set/get requests, so it's possible for
       * getParameter to return a different value than previous setParameter call.
       *
       * The syntax and semantics of keys are up to the vendor (as long as prefix
       * rules are obeyed). For instance, vendors may include some form of
       * wildcard support. In such case, result vector may be of different size
       * than requested keys vector. However, wildcards are not recognized by
       * framework and they are passed as-is to the HAL implementation.
       *
       * Unknown keys must be ignored and not placed into results vector.
       *
       * @param keys Parameter keys to fetch.
       * @return Vendor-specific key-value pairs.
       */
      public @NonNull Map<String, String>
              getParameters(@NonNull List<String> keys) {
          throw new UnsupportedOperationException();
      }
  
      /**
       * Get current antenna connection state for current configuration.
       * Only valid if a configuration has been applied.
       * @return {@code true} if the antenna is connected, {@code false} otherwise.
       *
       * @deprecated Use {@link onAntennaState} callback instead
       */
      @Deprecated
      public abstract boolean isAntennaConnected();
  
      /**
       * Indicates if this client actually controls the tuner.
       * Control is always granted after
       * {@link RadioManager#openTuner(int,
       * RadioManager.BandConfig, boolean, Callback, Handler)}
       * returns a non null tuner interface.
       * Control is lost when another client opens an interface on the same tuner.
       * When this happens, {@link Callback#onControlChanged(boolean)} is received.
       * The client can either wait for control to be returned (which is indicated by the same
       * callback) or close and reopen the tuner interface.
       * @return {@code true} if this interface controls the tuner,
       * {@code false} otherwise or if a problem occured retrieving the state.
       */
      public abstract boolean hasControl();
  
      /** Indicates a failure of radio IC or driver.
       * The application must close and re open the tuner
       * @deprecated See {@link onError} callback.
       */
      @Deprecated
      public static final int ERROR_HARDWARE_FAILURE = 0;
      /** Indicates a failure of the radio service.
       * The application must close and re open the tuner
       * @deprecated See {@link onError} callback.
       */
      @Deprecated
      public static final  int ERROR_SERVER_DIED = 1;
      /** A pending seek or tune operation was cancelled
       * @deprecated See {@link onError} callback.
       */
      @Deprecated
      public static final  int ERROR_CANCELLED = 2;
      /** A pending seek or tune operation timed out
       * @deprecated See {@link onError} callback.
       */
      @Deprecated
      public static final  int ERROR_SCAN_TIMEOUT = 3;
      /** The requested configuration could not be applied
       * @deprecated See {@link onError} callback.
       */
      @Deprecated
      public static final  int ERROR_CONFIG = 4;
      /** Background scan was interrupted due to hardware becoming temporarily unavailable.
       * @deprecated See {@link onError} callback.
       */
      @Deprecated
      public static final int ERROR_BACKGROUND_SCAN_UNAVAILABLE = 5;
      /** Background scan failed due to other error, ie. HW failure.
       * @deprecated See {@link onError} callback.
       */
      @Deprecated
      public static final int ERROR_BACKGROUND_SCAN_FAILED = 6;
  
      /**
       * Callback provided by the client application when opening a {@link RadioTuner}
       * to receive asynchronous operation results, updates and error notifications.
       */
      public static abstract class Callback {
          /**
           * onError() is called when an error occured while performing an asynchronous
           * operation of when the hardware or system service experiences a problem.
           * status is one of {@link #ERROR_HARDWARE_FAILURE}, {@link #ERROR_SERVER_DIED},
           * {@link #ERROR_CANCELLED}, {@link #ERROR_SCAN_TIMEOUT},
           * {@link #ERROR_CONFIG}
           *
           * @deprecated Use {@link onTuneFailed} for tune, scan and step;
           *             other use cases (configuration, background scan) are already deprecated.
           */
          public void onError(int status) {}
  
          /**
           * Called when tune, scan or step operation fails.
           *
           * @param result cause of the failure
           * @param selector ProgramSelector argument of tune that failed;
           *                 null for scan and step.
           */
          public void onTuneFailed(int result, @Nullable ProgramSelector selector) {}
  
          /**
           * onConfigurationChanged() is called upon successful completion of
           * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)}
           * or {@link RadioTuner#setConfiguration(RadioManager.BandConfig)}
           *
           * @deprecated Only applicable for HAL 1.x.
           */
          @Deprecated
          public void onConfigurationChanged(RadioManager.BandConfig config) {}
  
          /**
           * Called when program info (including metadata) for the current program has changed.
           *
           * It happens either upon successful completion of {@link RadioTuner#step(int, boolean)},
           * {@link RadioTuner#scan(int, boolean)}, {@link RadioTuner#tune(int, int)}; when
           * a switching to alternate frequency occurs; or when metadata is updated.
           */
          public void onProgramInfoChanged(RadioManager.ProgramInfo info) {}
  
          /**
           * Called when metadata is updated for the current program.
           *
           * @deprecated Use {@link #onProgramInfoChanged(RadioManager.ProgramInfo)} instead.
           */
          @Deprecated
          public void onMetadataChanged(RadioMetadata metadata) {}
  
          /**
           * onTrafficAnnouncement() is called when a traffic announcement starts and stops.
           */
          public void onTrafficAnnouncement(boolean active) {}
          /**
           * onEmergencyAnnouncement() is called when an emergency annoucement starts and stops.
           */
          public void onEmergencyAnnouncement(boolean active) {}
          /**
           * onAntennaState() is called when the antenna is connected or disconnected.
           */
          public void onAntennaState(boolean connected) {}
          /**
           * onControlChanged() is called when the client loses or gains control of the radio tuner.
           * The control is always granted after a successful call to
           * {@link RadioManager#openTuner(int, RadioManager.BandConfig, boolean, Callback, Handler)}.
           * If another client opens the same tuner, onControlChanged() will be called with
           * control set to {@code false} to indicate loss of control.
           * At this point, RadioTuner APIs other than getters will return
           * {@link RadioManager#STATUS_INVALID_OPERATION}.
           * When the other client releases the tuner, onControlChanged() will be called
           * with control set to {@code true}.
           */
          public void onControlChanged(boolean control) {}
  
          /**
           * onBackgroundScanAvailabilityChange() is called when background scan
           * feature becomes available or not.
           *
           * @param isAvailable true, if the tuner turned temporarily background-
           *                    capable, false in the other case.
           */
          public void onBackgroundScanAvailabilityChange(boolean isAvailable) {}
  
          /**
           * Called when a background scan completes successfully.
           */
          public void onBackgroundScanComplete() {}
  
          /**
           * Called when available program list changed.
           *
           * Use {@link RadioTuner#getProgramList(String)} to get an actual list.
           */
          public void onProgramListChanged() {}
  
          /**
           * Generic callback for passing updates to vendor-specific parameter values.
           * The framework does not interpret the parameters, they are passed
           * in an opaque manner between a vendor application and HAL.
           *
           * It's up to the HAL implementation if and how to implement this callback,
           * as long as it obeys the prefix rule. In particular, only selected keys
           * may be notified this way. However, setParameters must not trigger
           * this callback, while an internal event can change parameters
           * asynchronously.
           *
           * @param parameters Vendor-specific key-value pairs.
           */
          public void onParametersUpdated(@NonNull Map<String, String> parameters) {}
      }
  
  }
  
  