1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package android.media;
17
18import android.annotation.IntDef;
19import android.media.session.MediaSession;
20
21import java.lang.annotation.Retention;
22import java.lang.annotation.RetentionPolicy;
23
24/**
25 * Handles requests to adjust or set the volume on a session. This is also used
26 * to push volume updates back to the session. The provider must call
27 * {@link #setCurrentVolume(int)} each time the volume being provided changes.
28 * <p>
29 * You can set a volume provider on a session by calling
30 * {@link MediaSession#setPlaybackToRemote}.
31 */
32public abstract class VolumeProvider {
33
34    /**
35     * @hide
36     */
37    @IntDef({VOLUME_CONTROL_FIXED, VOLUME_CONTROL_RELATIVE, VOLUME_CONTROL_ABSOLUTE})
38    @Retention(RetentionPolicy.SOURCE)
39    public @interface ControlType {}
40
41    /**
42     * The volume is fixed and can not be modified. Requests to change volume
43     * should be ignored.
44     */
45    public static final int VOLUME_CONTROL_FIXED = 0;
46
47    /**
48     * The volume control uses relative adjustment via
49     * {@link #onAdjustVolume(int)}. Attempts to set the volume to a specific
50     * value should be ignored.
51     */
52    public static final int VOLUME_CONTROL_RELATIVE = 1;
53
54    /**
55     * The volume control uses an absolute value. It may be adjusted using
56     * {@link #onAdjustVolume(int)} or set directly using
57     * {@link #onSetVolumeTo(int)}.
58     */
59    public static final int VOLUME_CONTROL_ABSOLUTE = 2;
60
61    private final int mControlType;
62    private final int mMaxVolume;
63    private int mCurrentVolume;
64    private Callback mCallback;
65
66    /**
67     * Create a new volume provider for handling volume events. You must specify
68     * the type of volume control, the maximum volume that can be used, and the
69     * current volume on the output.
70     *
71     * @param volumeControl The method for controlling volume that is used by
72     *            this provider.
73     * @param maxVolume The maximum allowed volume.
74     * @param currentVolume The current volume on the output.
75     */
76    public VolumeProvider(@ControlType int volumeControl, int maxVolume, int currentVolume) {
77        mControlType = volumeControl;
78        mMaxVolume = maxVolume;
79        mCurrentVolume = currentVolume;
80    }
81
82    /**
83     * Get the volume control type that this volume provider uses.
84     *
85     * @return The volume control type for this volume provider
86     */
87    @ControlType
88    public final int getVolumeControl() {
89        return mControlType;
90    }
91
92    /**
93     * Get the maximum volume this provider allows.
94     *
95     * @return The max allowed volume.
96     */
97    public final int getMaxVolume() {
98        return mMaxVolume;
99    }
100
101    /**
102     * Gets the current volume. This will be the last value set by
103     * {@link #setCurrentVolume(int)}.
104     *
105     * @return The current volume.
106     */
107    public final int getCurrentVolume() {
108        return mCurrentVolume;
109    }
110
111    /**
112     * Notify the system that the current volume has been changed. This must be
113     * called every time the volume changes to ensure it is displayed properly.
114     *
115     * @param currentVolume The current volume on the output.
116     */
117    public final void setCurrentVolume(int currentVolume) {
118        mCurrentVolume = currentVolume;
119        if (mCallback != null) {
120            mCallback.onVolumeChanged(this);
121        }
122    }
123
124    /**
125     * Override to handle requests to set the volume of the current output.
126     * After the volume has been modified {@link #setCurrentVolume} must be
127     * called to notify the system.
128     *
129     * @param volume The volume to set the output to.
130     */
131    public void onSetVolumeTo(int volume) {
132    }
133
134    /**
135     * Override to handle requests to adjust the volume of the current output.
136     * Direction will be one of {@link AudioManager#ADJUST_LOWER},
137     * {@link AudioManager#ADJUST_RAISE}, {@link AudioManager#ADJUST_SAME}.
138     * After the volume has been modified {@link #setCurrentVolume} must be
139     * called to notify the system.
140     *
141     * @param direction The direction to change the volume in.
142     */
143    public void onAdjustVolume(int direction) {
144    }
145
146    /**
147     * Sets a callback to receive volume changes.
148     * @hide
149     */
150    public void setCallback(Callback callback) {
151        mCallback = callback;
152    }
153
154    /**
155     * Listens for changes to the volume.
156     * @hide
157     */
158    public static abstract class Callback {
159        public abstract void onVolumeChanged(VolumeProvider volumeProvider);
160    }
161}
162