HeadsetMediaButton.java revision b63b57e2c35c4769e756f47131c7ebbc0af42c59
1/*
2 * Copyright 2014, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.telecom;
18
19import android.annotation.TargetApi;
20import android.content.Context;
21import android.content.Intent;
22import android.media.AudioAttributes;
23import android.media.session.MediaSession;
24import android.view.KeyEvent;
25
26/**
27 * Static class to handle listening to the headset media buttons.
28 */
29public class HeadsetMediaButton extends CallsManagerListenerBase {
30
31    // Types of media button presses
32    static final int SHORT_PRESS = 1;
33    static final int LONG_PRESS = 2;
34
35    private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
36            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
37            .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build();
38
39    private final MediaSession.Callback mSessionCallback = new MediaSession.Callback() {
40        @Override
41        public boolean onMediaButtonEvent(Intent intent) {
42            KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
43            Log.v(this, "SessionCallback.onMediaButton()...  event = %s.", event);
44            if ((event != null) && (event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) {
45                Log.v(this, "SessionCallback: HEADSETHOOK");
46                boolean consumed = handleHeadsetHook(event);
47                Log.v(this, "==> handleHeadsetHook(): consumed = %b.", consumed);
48                return consumed;
49            }
50            return true;
51        }
52    };
53
54    private final CallsManager mCallsManager;
55
56    private final MediaSession mSession;
57
58    public HeadsetMediaButton(Context context, CallsManager callsManager) {
59        mCallsManager = callsManager;
60
61        // Create a MediaSession but don't enable it yet. This is a
62        // replacement for MediaButtonReceiver
63        mSession = new MediaSession(context, HeadsetMediaButton.class.getSimpleName());
64        mSession.setCallback(mSessionCallback);
65        mSession.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY
66                | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
67        mSession.setPlaybackToLocal(AUDIO_ATTRIBUTES);
68    }
69
70    /**
71     * Handles the wired headset button while in-call.
72     *
73     * @return true if we consumed the event.
74     */
75    private boolean handleHeadsetHook(KeyEvent event) {
76        Log.d(this, "handleHeadsetHook()...%s %s", event.getAction(), event.getRepeatCount());
77
78        if (event.isLongPress()) {
79            return mCallsManager.onMediaButton(LONG_PRESS);
80        } else if (event.getAction() == KeyEvent.ACTION_UP && event.getRepeatCount() == 0) {
81            return mCallsManager.onMediaButton(SHORT_PRESS);
82        }
83
84        return true;
85    }
86
87    /** ${inheritDoc} */
88    @Override
89    public void onCallAdded(Call call) {
90        if (!mSession.isActive()) {
91            mSession.setActive(true);
92        }
93    }
94
95    /** ${inheritDoc} */
96    @Override
97    public void onCallRemoved(Call call) {
98        if (!mCallsManager.hasAnyCalls()) {
99            if (mSession.isActive()) {
100                mSession.setActive(false);
101            }
102        }
103    }
104}
105