1 /* 2 * Copyright 2018 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 */ 16 17 package androidx.media; 18 19 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20 21 import android.os.Build; 22 import android.support.v4.media.session.MediaSessionCompat; 23 24 import androidx.annotation.IntDef; 25 import androidx.annotation.RestrictTo; 26 27 import java.lang.annotation.Retention; 28 import java.lang.annotation.RetentionPolicy; 29 30 /** 31 * Handles requests to adjust or set the volume on a session. This is also used 32 * to push volume updates back to the session after a request has been handled. 33 * You can set a volume provider on a session by calling 34 * {@link MediaSessionCompat#setPlaybackToRemote}. 35 */ 36 public abstract class VolumeProviderCompat { 37 38 /** 39 * @hide 40 */ 41 @RestrictTo(LIBRARY_GROUP) 42 @IntDef({VOLUME_CONTROL_FIXED, VOLUME_CONTROL_RELATIVE, VOLUME_CONTROL_ABSOLUTE}) 43 @Retention(RetentionPolicy.SOURCE) 44 public @interface ControlType {} 45 46 /** 47 * The volume is fixed and can not be modified. Requests to change volume 48 * should be ignored. 49 */ 50 public static final int VOLUME_CONTROL_FIXED = 0; 51 52 /** 53 * The volume control uses relative adjustment via 54 * {@link #onAdjustVolume(int)}. Attempts to set the volume to a specific 55 * value should be ignored. 56 */ 57 public static final int VOLUME_CONTROL_RELATIVE = 1; 58 59 /** 60 * The volume control uses an absolute value. It may be adjusted using 61 * {@link #onAdjustVolume(int)} or set directly using 62 * {@link #onSetVolumeTo(int)}. 63 */ 64 public static final int VOLUME_CONTROL_ABSOLUTE = 2; 65 66 private final int mControlType; 67 private final int mMaxVolume; 68 private int mCurrentVolume; 69 private Callback mCallback; 70 71 private Object mVolumeProviderObj; 72 73 /** 74 * Create a new volume provider for handling volume events. You must specify 75 * the type of volume control and the maximum volume that can be used. 76 * 77 * @param volumeControl The method for controlling volume that is used by 78 * this provider. 79 * @param maxVolume The maximum allowed volume. 80 * @param currentVolume The current volume. 81 */ 82 public VolumeProviderCompat(@ControlType int volumeControl, int maxVolume, int currentVolume) { 83 mControlType = volumeControl; 84 mMaxVolume = maxVolume; 85 mCurrentVolume = currentVolume; 86 } 87 88 /** 89 * Get the current volume of the provider. 90 * 91 * @return The current volume. 92 */ 93 public final int getCurrentVolume() { 94 return mCurrentVolume; 95 } 96 97 /** 98 * Get the volume control type that this volume provider uses. 99 * 100 * @return The volume control type for this volume provider 101 */ 102 @ControlType 103 public final int getVolumeControl() { 104 return mControlType; 105 } 106 107 /** 108 * Get the maximum volume this provider allows. 109 * 110 * @return The max allowed volume. 111 */ 112 public final int getMaxVolume() { 113 return mMaxVolume; 114 } 115 116 /** 117 * Set the current volume and notify the system that the volume has been 118 * changed. 119 * 120 * @param currentVolume The current volume of the output. 121 */ 122 public final void setCurrentVolume(int currentVolume) { 123 mCurrentVolume = currentVolume; 124 Object volumeProviderObj = getVolumeProvider(); 125 if (volumeProviderObj != null && Build.VERSION.SDK_INT >= 21) { 126 VolumeProviderCompatApi21.setCurrentVolume(volumeProviderObj, currentVolume); 127 } 128 if (mCallback != null) { 129 mCallback.onVolumeChanged(this); 130 } 131 } 132 133 /** 134 * Override to handle requests to set the volume of the current output. 135 * 136 * @param volume The volume to set the output to. 137 */ 138 public void onSetVolumeTo(int volume) { 139 } 140 141 /** 142 * Override to handle requests to adjust the volume of the current output. 143 * 144 * @param direction The direction to adjust the volume in. 145 */ 146 public void onAdjustVolume(int direction) { 147 } 148 149 /** 150 * Sets a callback to receive volume changes. 151 * <p> 152 * Used internally by the support library. 153 * <p> 154 */ 155 public void setCallback(Callback callback) { 156 mCallback = callback; 157 } 158 159 /** 160 * Gets the underlying framework {@link android.media.VolumeProvider} object. 161 * <p> 162 * This method is only supported on API 21+. 163 * </p> 164 * 165 * @return An equivalent {@link android.media.VolumeProvider} object, or null if none. 166 */ 167 public Object getVolumeProvider() { 168 if (mVolumeProviderObj == null && Build.VERSION.SDK_INT >= 21) { 169 mVolumeProviderObj = VolumeProviderCompatApi21.createVolumeProvider( 170 mControlType, mMaxVolume, mCurrentVolume, 171 new VolumeProviderCompatApi21.Delegate() { 172 173 @Override 174 public void onSetVolumeTo(int volume) { 175 VolumeProviderCompat.this.onSetVolumeTo(volume); 176 } 177 178 @Override 179 public void onAdjustVolume(int direction) { 180 VolumeProviderCompat.this.onAdjustVolume(direction); 181 } 182 }); 183 } 184 return mVolumeProviderObj; 185 } 186 187 /** 188 * Listens for changes to the volume. 189 */ 190 public static abstract class Callback { 191 public abstract void onVolumeChanged(VolumeProviderCompat volumeProvider); 192 } 193 } 194