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