OSDN Git Service

Pipe volume keys to adjustVolume instead of sendMediaKeyEvent
authorRoboErik <epastern@google.com>
Tue, 8 Jul 2014 23:47:31 +0000 (16:47 -0700)
committerErik Pasternak <roboerik@android.com>
Thu, 10 Jul 2014 16:15:45 +0000 (16:15 +0000)
We were calling sendMediaKeyEvent with a KEYCODE_VOLUME key, which was being
ignored because it's not a media key. This redirects the volume keys to use
the adjustVolume methods instead. It also sends the appropriate flags to
make the lock screen consistent with the home screen and the volume keys
only affect active playback when the screen is off.

bug:15900519
Change-Id: I9f3853a2385869353a58debae6e6ca9933ba06ce

media/java/android/media/AudioManager.java
media/java/android/media/session/MediaSession.java
media/java/android/media/session/MediaSessionLegacyHelper.java
policy/src/com/android/internal/policy/impl/PhoneFallbackEventHandler.java
policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
services/core/java/com/android/server/media/MediaSessionRecord.java
services/core/java/com/android/server/media/MediaSessionService.java

index ffbe2cb..5bcbc3c 100644 (file)
@@ -346,6 +346,12 @@ public class AudioManager {
     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.)
      *
index dbe13dd..2cbdc96 100644 (file)
@@ -699,6 +699,25 @@ public final class MediaSession {
     }
 
     /**
+     * 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.
index 0b04485..5d1a7e0 100644 (file)
@@ -21,6 +21,7 @@ import android.app.PendingIntent.CanceledException;
 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;
@@ -157,12 +158,59 @@ public class MediaSessionLegacyHelper {
     }
 
     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) {
index 4ad45a8..f291e89 100644 (file)
@@ -83,7 +83,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler {
             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;
             }
 
@@ -198,11 +198,7 @@ public class PhoneFallbackEventHandler implements FallbackEventHandler {
             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;
             }
index c668f5a..0b1252e 100644 (file)
@@ -45,7 +45,11 @@ import android.media.AudioManager;
 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;
@@ -113,6 +117,7 @@ import java.io.IOException;
 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;
@@ -4006,21 +4011,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         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;
 
@@ -4210,7 +4200,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                             // the application, just pass it to the session service.
 
                             MediaSessionLegacyHelper.getHelper(mContext)
-                                    .sendMediaButtonEvent(event, true);
+                                    .sendVolumeKeyEvent(event, false);
                             break;
                         }
                     }
@@ -4220,7 +4210,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                         // handled it send it to the session manager to figure
                         // out.
                         MediaSessionLegacyHelper.getHelper(mContext)
-                                .sendMediaButtonEvent(event, true);
+                                .sendVolumeKeyEvent(event, true);
                         break;
                     }
                 }
index aeade50..0fbcd7e 100644 (file)
@@ -68,18 +68,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
     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.
      */
@@ -402,7 +390,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
      */
     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) {
@@ -555,15 +543,6 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
         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
@@ -804,7 +783,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
         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;
index 5a16e4d..310f3e9 100644 (file)
@@ -27,6 +27,7 @@ import android.content.ContentResolver;
 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;
@@ -948,6 +949,12 @@ public class MediaSessionService extends SystemService implements Monitor {
 
             }
             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,