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