diff options
3 files changed, 98 insertions, 18 deletions
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index d96fee6..98a43a8 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -153,11 +153,11 @@ public class AudioService extends IAudioService.Stub { private final AppOpsManager mAppOps; // the platform has no specific capabilities - private static final int PLATFORM_DEFAULT = 0; + public static final int PLATFORM_DEFAULT = 0; // the platform is voice call capable (a phone) - private static final int PLATFORM_VOICE = 1; + public static final int PLATFORM_VOICE = 1; // the platform is a television or a set-top box - private static final int PLATFORM_TELEVISION = 2; + public static final int PLATFORM_TELEVISION = 2; // the platform type affects volume and silent mode behavior private final int mPlatformType; @@ -546,15 +546,7 @@ public class AudioService extends IAudioService.Stub { mContentResolver = context.getContentResolver(); mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); - if (mContext.getResources().getBoolean( - com.android.internal.R.bool.config_voice_capable)) { - mPlatformType = PLATFORM_VOICE; - } else if (context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_LEANBACK)) { - mPlatformType = PLATFORM_TELEVISION; - } else { - mPlatformType = PLATFORM_DEFAULT; - } + mPlatformType = getPlatformType(context); PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent"); @@ -667,6 +659,26 @@ public class AudioService extends IAudioService.Stub { LocalServices.addService(AudioManagerInternal.class, new AudioServiceInternal()); } + /** + * Return the platform type that this is running on. One of: + * <ul> + * <li>{@link #PLATFORM_VOICE}</li> + * <li>{@link #PLATFORM_TELEVISION}</li> + * <li>{@link #PLATFORM_DEFAULT}</li> + * </ul> + */ + public static int getPlatformType(Context context) { + if (context.getResources().getBoolean( + com.android.internal.R.bool.config_voice_capable)) { + return PLATFORM_VOICE; + } else if (context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_LEANBACK)) { + return PLATFORM_TELEVISION; + } else { + return PLATFORM_DEFAULT; + } + } + public void systemReady() { sendMsg(mAudioHandler, MSG_SYSTEM_READY, SENDMSG_QUEUE, 0, 0, null, 0); diff --git a/media/java/android/media/session/MediaSessionLegacyHelper.java b/media/java/android/media/session/MediaSessionLegacyHelper.java index 9954de5..4ea22f9 100644 --- a/media/java/android/media/session/MediaSessionLegacyHelper.java +++ b/media/java/android/media/session/MediaSessionLegacyHelper.java @@ -221,7 +221,7 @@ public class MediaSessionLegacyHelper { mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, direction, flags); } else if (isMute) { - if (down) { + if (down && keyEvent.getRepeatCount() == 0) { mSessionManager.dispatchAdjustVolume(AudioManager.USE_DEFAULT_STREAM_TYPE, AudioManager.ADJUST_TOGGLE_MUTE, flags); } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index d4032cc..ac095e6 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -43,6 +43,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.media.AudioAttributes; import android.media.AudioManager; +import android.media.AudioService; import android.media.IAudioService; import android.media.Ringtone; import android.media.RingtoneManager; @@ -376,6 +377,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; boolean mHasSoftInput = false; boolean mTranslucentDecorEnabled = true; + boolean mUseTvRouting; + boolean mUseMasterVolume; int mPointerLocationMode = 0; // guarded by mLock @@ -1262,6 +1265,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { mTriplePressOnPowerBehavior = mContext.getResources().getInteger( com.android.internal.R.integer.config_triplePressOnPowerBehavior); + mUseTvRouting = AudioService.getPlatformType(mContext) == AudioService.PLATFORM_TELEVISION; + mUseMasterVolume = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_useMasterVolume); + readConfigurationDependentBehaviors(); mAccessibilityManager = (AccessibilityManager) context.getSystemService( @@ -4534,6 +4541,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_MUTE: { + if (mUseTvRouting) { + // On TVs volume keys never go to the foreground app + result &= ~ACTION_PASS_TO_USER; + } if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { if (down) { if (interactive && !mScreenshotChordVolumeDownKeyTriggered @@ -4595,11 +4606,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if ((result & ACTION_PASS_TO_USER) == 0) { - // If we aren't passing to the user and no one else - // handled it send it to the session manager to figure - // out. - MediaSessionLegacyHelper.getHelper(mContext) - .sendVolumeKeyEvent(event, true); + if (mUseTvRouting) { + dispatchDirectAudioEvent(event); + } else { + // If we aren't passing to the user and no one else + // handled it send it to the session manager to + // figure out. + MediaSessionLegacyHelper.getHelper(mContext) + .sendVolumeKeyEvent(event, true); + } break; } } @@ -4844,6 +4859,59 @@ public class PhoneWindowManager implements WindowManagerPolicy { return false; } + private void dispatchDirectAudioEvent(KeyEvent event) { + if (event.getAction() != KeyEvent.ACTION_DOWN) { + return; + } + int keyCode = event.getKeyCode(); + int flags = AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND; + String pkgName = mContext.getOpPackageName(); + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + try { + if (mUseMasterVolume) { + getAudioService().adjustMasterVolume(AudioManager.ADJUST_RAISE, flags, + pkgName); + } else { + getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_RAISE, + AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName); + } + } catch (RemoteException e) { + Log.e(TAG, "Error dispatching volume up in dispatchTvAudioEvent.", e); + } + break; + case KeyEvent.KEYCODE_VOLUME_DOWN: + try { + if (mUseMasterVolume) { + getAudioService().adjustMasterVolume(AudioManager.ADJUST_LOWER, flags, + pkgName); + } else { + getAudioService().adjustSuggestedStreamVolume(AudioManager.ADJUST_LOWER, + AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName); + } + } catch (RemoteException e) { + Log.e(TAG, "Error dispatching volume down in dispatchTvAudioEvent.", e); + } + break; + case KeyEvent.KEYCODE_VOLUME_MUTE: + try { + if (event.getRepeatCount() == 0) { + if (mUseMasterVolume) { + getAudioService().adjustMasterVolume(AudioManager.ADJUST_TOGGLE_MUTE, + flags, pkgName); + } else { + getAudioService().adjustSuggestedStreamVolume( + AudioManager.ADJUST_TOGGLE_MUTE, + AudioManager.USE_DEFAULT_STREAM_TYPE, flags, pkgName); + } + } + } catch (RemoteException e) { + Log.e(TAG, "Error dispatching mute in dispatchTvAudioEvent.", e); + } + break; + } + } + void dispatchMediaKeyWithWakeLock(KeyEvent event) { if (DEBUG_INPUT) { Slog.d(TAG, "dispatchMediaKeyWithWakeLock: " + event); |