public static final int FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8;
/**
+ * Indicates that this should only be handled if media is actively playing.
+ * @hide
+ */
+ public static final int FLAG_ACTIVE_MEDIA_ONLY = 1 << 9;
+
+ /**
* Ringer mode that will be silent and will not vibrate. (This overrides the
* vibrate setting.)
*
}
/**
+ * Return true if this is considered an active playback state.
+ *
+ * @hide
+ */
+ public static boolean isActiveState(int state) {
+ switch (state) {
+ case PlaybackState.STATE_FAST_FORWARDING:
+ case PlaybackState.STATE_REWINDING:
+ case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
+ case PlaybackState.STATE_SKIPPING_TO_NEXT:
+ case PlaybackState.STATE_BUFFERING:
+ case PlaybackState.STATE_CONNECTING:
+ case PlaybackState.STATE_PLAYING:
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Represents an ongoing session. This may be passed to apps by the session
* owner to allow them to create a {@link MediaController} to communicate with
* the session.
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.MediaMetadataEditor;
import android.media.MediaMetadataRetriever;
}
public void sendMediaButtonEvent(KeyEvent keyEvent, boolean needWakeLock) {
+ if (keyEvent == null) {
+ Log.w(TAG, "Tried to send a null key event. Ignoring.");
+ return;
+ }
mSessionManager.dispatchMediaKeyEvent(keyEvent, needWakeLock);
if (DEBUG) {
Log.d(TAG, "dispatched media key " + keyEvent);
}
}
+ public void sendVolumeKeyEvent(KeyEvent keyEvent, boolean musicOnly) {
+ if (keyEvent == null) {
+ Log.w(TAG, "Tried to send a null key event. Ignoring.");
+ return;
+ }
+ boolean down = keyEvent.getAction() == KeyEvent.ACTION_DOWN;
+ boolean up = keyEvent.getAction() == KeyEvent.ACTION_UP;
+ int direction = 0;
+ switch (keyEvent.getKeyCode()) {
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ direction = AudioManager.ADJUST_RAISE;
+ break;
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ direction = AudioManager.ADJUST_LOWER;
+ break;
+ case KeyEvent.KEYCODE_VOLUME_MUTE:
+ // TODO
+ break;
+ }
+ if ((down || up) && direction != 0) {
+ int flags;
+ // If this is action up we want to send a beep for non-music events
+ if (up) {
+ direction = 0;
+ }
+ if (musicOnly) {
+ // This flag is used when the screen is off to only affect
+ // active media
+ flags = AudioManager.FLAG_ACTIVE_MEDIA_ONLY;
+ } else {
+ // These flags are consistent with the home screen
+ if (up) {
+ flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE;
+ } else {
+ flags = AudioManager.FLAG_SHOW_UI;
+ }
+ }
+
+ mSessionManager.dispatchAdjustVolumeBy(AudioManager.USE_DEFAULT_STREAM_TYPE,
+ direction, flags);
+ }
+ }
+
public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) {
mSessionManager.dispatchAdjustVolumeBy(suggestedStream, delta, flags);
if (DEBUG) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
- getAudioManager().handleKeyDown(event, AudioManager.USE_DEFAULT_STREAM_TYPE);
+ MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(event, false);
return true;
}
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
if (!event.isCanceled()) {
- AudioManager audioManager = (AudioManager)mContext.getSystemService(
- Context.AUDIO_SERVICE);
- if (audioManager != null) {
- getAudioManager().handleKeyUp(event, AudioManager.USE_DEFAULT_STREAM_TYPE);
- }
+ MediaSessionLegacyHelper.getHelper(mContext).sendVolumeKeyEvent(event, false);
}
return true;
}
import android.media.IAudioService;
import android.media.Ringtone;
import android.media.RingtoneManager;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.FactoryTest;
import android.os.Handler;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
setHdmiPlugged(!mHdmiPlugged);
}
- /**
- * @return Whether music is being played right now "locally" (e.g. on the device's speakers
- * or wired headphones) or "remotely" (e.g. on a device using the Cast protocol and
- * controlled by this device, or through remote submix).
- */
- boolean isMusicActive() {
-
- final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
- if (am == null) {
- Log.w(TAG, "isMusicActive: couldn't get AudioManager reference");
- return false;
- }
- return am.isLocalOrRemoteMusicActive();
- }
-
final Object mScreenshotLock = new Object();
ServiceConnection mScreenshotConnection = null;
// the application, just pass it to the session service.
MediaSessionLegacyHelper.getHelper(mContext)
- .sendMediaButtonEvent(event, true);
+ .sendVolumeKeyEvent(event, false);
break;
}
}
// handled it send it to the session manager to figure
// out.
MediaSessionLegacyHelper.getHelper(mContext)
- .sendMediaButtonEvent(event, true);
+ .sendVolumeKeyEvent(event, true);
break;
}
}
private static final boolean DEBUG = false;
/**
- * These are the playback states that count as currently active.
- */
- private static final int[] ACTIVE_STATES = {
- PlaybackState.STATE_FAST_FORWARDING,
- PlaybackState.STATE_REWINDING,
- PlaybackState.STATE_SKIPPING_TO_PREVIOUS,
- PlaybackState.STATE_SKIPPING_TO_NEXT,
- PlaybackState.STATE_BUFFERING,
- PlaybackState.STATE_CONNECTING,
- PlaybackState.STATE_PLAYING };
-
- /**
* The length of time a session will still be considered active after
* pausing in ms.
*/
*/
public boolean isPlaybackActive(boolean includeRecentlyActive) {
int state = mPlaybackState == null ? 0 : mPlaybackState.getState();
- if (isActiveState(state)) {
+ if (MediaSession.isActiveState(state)) {
return true;
}
if (includeRecentlyActive && state == mPlaybackState.STATE_PAUSED) {
pw.println(indent + "params=" + (mRequest == null ? null : mRequest.toString()));
}
- private boolean isActiveState(int state) {
- for (int i = 0; i < ACTIVE_STATES.length; i++) {
- if (ACTIVE_STATES[i] == state) {
- return true;
- }
- }
- return false;
- }
-
private String getShortMetadataString() {
int fields = mMetadata == null ? 0 : mMetadata.size();
String title = mMetadata == null ? null : mMetadata
public void setPlaybackState(PlaybackState state) {
int oldState = mPlaybackState == null ? 0 : mPlaybackState.getState();
int newState = state == null ? 0 : state.getState();
- if (isActiveState(oldState) && newState == PlaybackState.STATE_PAUSED) {
+ if (MediaSession.isActiveState(oldState) && newState == PlaybackState.STATE_PAUSED) {
mLastActiveTime = SystemClock.elapsedRealtime();
}
mPlaybackState = state;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.media.AudioManager;
import android.media.IAudioService;
import android.media.IRemoteVolumeController;
import android.media.routeprovider.RouteRequest;
}
if (session == null) {
+ if ((flags & AudioManager.FLAG_ACTIVE_MEDIA_ONLY) != 0) {
+ if (DEBUG) {
+ Log.d(TAG, "No active session to adjust, skipping media only volume event");
+ return;
+ }
+ }
try {
if (delta == 0) {
mAudioService.adjustSuggestedStreamVolume(delta, suggestedStream, flags,