Add SDK 29 sources.

Test: N/A
Change-Id: Iedb7a31029e003928eb16f7e69ed147e72bb6235
diff --git a/android/media/HwAudioSource.java b/android/media/HwAudioSource.java
new file mode 100644
index 0000000..01a02f1
--- /dev/null
+++ b/android/media/HwAudioSource.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2019 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.media;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+import com.android.internal.util.Preconditions;
+
+/**
+ * The HwAudioSource represents the audio playback directly from a source audio device.
+ * It currently supports {@link HwAudioSource#start()} and {@link HwAudioSource#stop()} only
+ * corresponding to {@link AudioSystem#startAudioSource(AudioPortConfig, AudioAttributes)}
+ * and {@link AudioSystem#stopAudioSource(int)}.
+ *
+ * @hide
+ */
+@SystemApi
+public class HwAudioSource extends PlayerBase {
+    private final AudioDeviceInfo mAudioDeviceInfo;
+    private final AudioAttributes mAudioAttributes;
+
+    private int mNativeHandle;
+
+    /**
+     * Class constructor for a hardware audio source based player.
+     *
+     * Use the {@link Builder} class to construct a {@link HwAudioSource} instance.
+     *
+     * @param device {@link AudioDeviceInfo} instance of the source audio device.
+     * @param attributes {@link AudioAttributes} instance for this player.
+     */
+    private HwAudioSource(@NonNull AudioDeviceInfo device, @NonNull AudioAttributes attributes) {
+        super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_HW_SOURCE);
+        Preconditions.checkNotNull(device);
+        Preconditions.checkNotNull(attributes);
+        Preconditions.checkArgument(device.isSource(), "Requires a source device");
+        mAudioDeviceInfo = device;
+        mAudioAttributes = attributes;
+        baseRegisterPlayer();
+    }
+
+    /**
+     * TODO: sets the gain on {@link #mAudioDeviceInfo}.
+     *
+     * @param muting if true, the player is to be muted, and the volume values can be ignored
+     * @param leftVolume the left volume to use if muting is false
+     * @param rightVolume the right volume to use if muting is false
+     */
+    @Override
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+    }
+
+    /**
+     * TODO: applies {@link VolumeShaper} on {@link #mAudioDeviceInfo}.
+     *
+     * @param configuration a {@code VolumeShaper.Configuration} object
+     *        created by {@link VolumeShaper.Configuration.Builder} or
+     *        an created from a {@code VolumeShaper} id
+     *        by the {@link VolumeShaper.Configuration} constructor.
+     * @param operation a {@code VolumeShaper.Operation}.
+     * @return
+     */
+    @Override
+    int playerApplyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation) {
+        return 0;
+    }
+
+    /**
+     * TODO: gets the {@link VolumeShaper} by a given id.
+     *
+     * @param id the {@code VolumeShaper} id returned from
+     *           sending a fully specified {@code VolumeShaper.Configuration}
+     *           through {@link #playerApplyVolumeShaper}
+     * @return
+     */
+    @Override
+    @Nullable
+    VolumeShaper.State playerGetVolumeShaperState(int id) {
+        return new VolumeShaper.State(1f, 1f);
+    }
+
+    /**
+     * TODO: sets the level on {@link #mAudioDeviceInfo}.
+     *
+     * @param muting
+     * @param level
+     * @return
+     */
+    @Override
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        return AudioSystem.SUCCESS;
+    }
+
+    @Override
+    void playerStart() {
+        start();
+    }
+
+    @Override
+    void playerPause() {
+        // Pause is equivalent to stop for hardware audio source based players.
+        stop();
+    }
+
+    @Override
+    void playerStop() {
+        stop();
+    }
+
+    /**
+     * Starts the playback from {@link AudioDeviceInfo}.
+     */
+    public void start() {
+        Preconditions.checkState(!isPlaying(), "HwAudioSource is currently playing");
+        baseStart();
+        mNativeHandle = AudioSystem.startAudioSource(
+                mAudioDeviceInfo.getPort().activeConfig(),
+                mAudioAttributes);
+    }
+
+    /**
+     * Checks whether the HwAudioSource player is playing.
+     * @return true if currently playing, false otherwise
+     */
+    public boolean isPlaying() {
+        return mNativeHandle != 0;
+    }
+
+    /**
+     * Stops the playback from {@link AudioDeviceInfo}.
+     */
+    public void stop() {
+        baseStop();
+        if (mNativeHandle > 0) {
+            AudioSystem.stopAudioSource(mNativeHandle);
+            mNativeHandle = 0;
+        }
+    }
+
+    /**
+     * Builder class for {@link HwAudioSource} objects.
+     * Use this class to configure and create a <code>HwAudioSource</code> instance.
+     * <p>Here is an example where <code>Builder</code> is used to specify an audio
+     * playback directly from a source device as media usage, to be used by a new
+     * <code>HwAudioSource</code> instance:
+     *
+     * <pre class="prettyprint">
+     * HwAudioSource player = new HwAudioSource.Builder()
+     *              .setAudioAttributes(new AudioAttributes.Builder()
+     *                       .setUsage(AudioAttributes.USAGE_MEDIA)
+     *                       .build())
+     *              .setAudioDeviceInfo(device)
+     *              .build()
+     * </pre>
+     * <p>
+     * If the audio attributes are not set with {@link #setAudioAttributes(AudioAttributes)},
+     * attributes comprising {@link AudioAttributes#USAGE_MEDIA} will be used.
+     */
+    public static final class Builder {
+        private AudioAttributes mAudioAttributes;
+        private AudioDeviceInfo mAudioDeviceInfo;
+
+        /**
+         * Constructs a new Builder with default values.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets the {@link AudioAttributes}.
+         * @param attributes a non-null {@link AudioAttributes} instance that describes the audio
+         *     data to be played.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes) {
+            Preconditions.checkNotNull(attributes);
+            mAudioAttributes = attributes;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioDeviceInfo}.
+         * @param info a non-null {@link AudioDeviceInfo} instance that describes the audio
+         *     data come from.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setAudioDeviceInfo(@NonNull AudioDeviceInfo info) {
+            Preconditions.checkNotNull(info);
+            Preconditions.checkArgument(info.isSource());
+            mAudioDeviceInfo = info;
+            return this;
+        }
+
+        /**
+         * Builds an {@link HwAudioSource} instance initialized with all the parameters set
+         * on this <code>Builder</code>.
+         * @return a new successfully initialized {@link HwAudioSource} instance.
+         */
+        public @NonNull HwAudioSource build() {
+            Preconditions.checkNotNull(mAudioDeviceInfo);
+            if (mAudioAttributes == null) {
+                mAudioAttributes = new AudioAttributes.Builder()
+                        .setUsage(AudioAttributes.USAGE_MEDIA)
+                        .build();
+            }
+            return new HwAudioSource(mAudioDeviceInfo, mAudioAttributes);
+        }
+    }
+}