1deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon/* 2deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * Copyright 2014, The Android Open Source Project 3deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * 4deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 5deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * you may not use this file except in compliance with the License. 6deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * You may obtain a copy of the License at 7deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * 8deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * http://www.apache.org/licenses/LICENSE-2.0 9deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * 10deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * Unless required by applicable law or agreed to in writing, software 11deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 12deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * See the License for the specific language governing permissions and 14deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * limitations under the License. 15deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon */ 16deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 177cc70b4f0ad1064a4a0dce6056ad82b205887160Tyler Gunnpackage com.android.server.telecom; 18deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 19deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordonimport android.content.Context; 20deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordonimport android.content.Intent; 2107920f67c86e80fc78086e21fd446b2531c2defdRoboErikimport android.media.AudioAttributes; 22deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordonimport android.media.session.MediaSession; 23deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordonimport android.view.KeyEvent; 24deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 25deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon/** 26deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * Static class to handle listening to the headset media buttons. 27deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon */ 288128998af91646bae7ae858f60e05075776e0a5cSantos Cordonfinal class HeadsetMediaButton extends CallsManagerListenerBase { 29deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 30deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon // Types of media button presses 31deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon static final int SHORT_PRESS = 1; 32deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon static final int LONG_PRESS = 2; 33deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 3407920f67c86e80fc78086e21fd446b2531c2defdRoboErik private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder() 3507920f67c86e80fc78086e21fd446b2531c2defdRoboErik .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) 3607920f67c86e80fc78086e21fd446b2531c2defdRoboErik .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build(); 3707920f67c86e80fc78086e21fd446b2531c2defdRoboErik 38deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon private final MediaSession.Callback mSessionCallback = new MediaSession.Callback() { 39deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon @Override 40a6e9d758f02ec0654f489725e9b9442796d0b03fRoboErik public boolean onMediaButtonEvent(Intent intent) { 41deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 42deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon Log.v(this, "SessionCallback.onMediaButton()... event = %s.", event); 43deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon if ((event != null) && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) { 44deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon Log.v(this, "SessionCallback: HEADSETHOOK"); 45deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon boolean consumed = handleHeadsetHook(event); 46deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon Log.v(this, "==> handleHeadsetHook(): consumed = %b.", consumed); 47a6e9d758f02ec0654f489725e9b9442796d0b03fRoboErik return consumed; 48deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon } 49a6e9d758f02ec0654f489725e9b9442796d0b03fRoboErik return true; 50deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon } 51deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon }; 52deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 53deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon private final CallsManager mCallsManager; 54deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 55deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon private final MediaSession mSession; 56deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 57deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon HeadsetMediaButton(Context context, CallsManager callsManager) { 58deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon mCallsManager = callsManager; 59deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 60b771c432c5526ed54e5f07949ace2b99008bc341RoboErik // Create a MediaSession but don't enable it yet. This is a 61deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon // replacement for MediaButtonReceiver 62b771c432c5526ed54e5f07949ace2b99008bc341RoboErik mSession = new MediaSession(context, HeadsetMediaButton.class.getSimpleName()); 63a6e9d758f02ec0654f489725e9b9442796d0b03fRoboErik mSession.setCallback(mSessionCallback); 64deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon mSession.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY 65deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS); 6607920f67c86e80fc78086e21fd446b2531c2defdRoboErik mSession.setPlaybackToLocal(AUDIO_ATTRIBUTES); 67deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon } 68deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 69deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon /** 70deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * Handles the wired headset button while in-call. 71deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * 72deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon * @return true if we consumed the event. 73deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon */ 74deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon private boolean handleHeadsetHook(KeyEvent event) { 75deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon Log.d(this, "handleHeadsetHook()...%s %s", event.getAction(), event.getRepeatCount()); 76deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 77deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon if (event.isLongPress()) { 78deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon return mCallsManager.onMediaButton(LONG_PRESS); 79deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon } else if (event.getAction() == KeyEvent.ACTION_UP && event.getRepeatCount() == 0) { 80deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon return mCallsManager.onMediaButton(SHORT_PRESS); 81deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon } 82deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon 83deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon return true; 84deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon } 858128998af91646bae7ae858f60e05075776e0a5cSantos Cordon 868128998af91646bae7ae858f60e05075776e0a5cSantos Cordon /** ${inheritDoc} */ 878128998af91646bae7ae858f60e05075776e0a5cSantos Cordon @Override 888128998af91646bae7ae858f60e05075776e0a5cSantos Cordon public void onCallAdded(Call call) { 898128998af91646bae7ae858f60e05075776e0a5cSantos Cordon if (!mSession.isActive()) { 908128998af91646bae7ae858f60e05075776e0a5cSantos Cordon mSession.setActive(true); 918128998af91646bae7ae858f60e05075776e0a5cSantos Cordon } 928128998af91646bae7ae858f60e05075776e0a5cSantos Cordon } 938128998af91646bae7ae858f60e05075776e0a5cSantos Cordon 948128998af91646bae7ae858f60e05075776e0a5cSantos Cordon /** ${inheritDoc} */ 958128998af91646bae7ae858f60e05075776e0a5cSantos Cordon @Override 968128998af91646bae7ae858f60e05075776e0a5cSantos Cordon public void onCallRemoved(Call call) { 978128998af91646bae7ae858f60e05075776e0a5cSantos Cordon if (!mCallsManager.hasAnyCalls()) { 988128998af91646bae7ae858f60e05075776e0a5cSantos Cordon if (mSession.isActive()) { 998128998af91646bae7ae858f60e05075776e0a5cSantos Cordon mSession.setActive(false); 1008128998af91646bae7ae858f60e05075776e0a5cSantos Cordon } 1018128998af91646bae7ae858f60e05075776e0a5cSantos Cordon } 1028128998af91646bae7ae858f60e05075776e0a5cSantos Cordon } 103deb8c89707c604d4f9f32e476a58bd10a68293ffSantos Cordon} 104