1/*
2 * Copyright (C) 2007 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.music;
18
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.media.AudioManager;
23import android.os.Handler;
24import android.os.Message;
25import android.view.KeyEvent;
26
27/**
28 *
29 */
30public class MediaButtonIntentReceiver extends BroadcastReceiver {
31
32    private static final int MSG_LONGPRESS_TIMEOUT = 1;
33    private static final int LONG_PRESS_DELAY = 1000;
34
35    private static long mLastClickTime = 0;
36    private static boolean mDown = false;
37    private static boolean mLaunched = false;
38
39    private static Handler mHandler = new Handler() {
40        @Override
41        public void handleMessage(Message msg) {
42            switch (msg.what) {
43                case MSG_LONGPRESS_TIMEOUT:
44                    if (!mLaunched) {
45                        Context context = (Context)msg.obj;
46                        Intent i = new Intent();
47                        i.putExtra("autoshuffle", "true");
48                        i.setClass(context, MusicBrowserActivity.class);
49                        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
50                        context.startActivity(i);
51                        mLaunched = true;
52                    }
53                    break;
54            }
55        }
56    };
57
58    @Override
59    public void onReceive(Context context, Intent intent) {
60        String intentAction = intent.getAction();
61        if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intentAction)) {
62            Intent i = new Intent(context, MediaPlaybackService.class);
63            i.setAction(MediaPlaybackService.SERVICECMD);
64            i.putExtra(MediaPlaybackService.CMDNAME, MediaPlaybackService.CMDPAUSE);
65            context.startService(i);
66        } else if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
67            KeyEvent event = (KeyEvent)
68                    intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
69
70            if (event == null) {
71                return;
72            }
73
74            int keycode = event.getKeyCode();
75            int action = event.getAction();
76            long eventtime = event.getEventTime();
77
78            // single quick press: pause/resume.
79            // double press: next track
80            // long press: start auto-shuffle mode.
81
82            String command = null;
83            switch (keycode) {
84                case KeyEvent.KEYCODE_MEDIA_STOP:
85                    command = MediaPlaybackService.CMDSTOP;
86                    break;
87                case KeyEvent.KEYCODE_HEADSETHOOK:
88                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
89                    command = MediaPlaybackService.CMDTOGGLEPAUSE;
90                    break;
91                case KeyEvent.KEYCODE_MEDIA_NEXT:
92                    command = MediaPlaybackService.CMDNEXT;
93                    break;
94                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
95                    command = MediaPlaybackService.CMDPREVIOUS;
96                    break;
97                case KeyEvent.KEYCODE_MEDIA_PAUSE:
98                    command = MediaPlaybackService.CMDPAUSE;
99                    break;
100                case KeyEvent.KEYCODE_MEDIA_PLAY:
101                    command = MediaPlaybackService.CMDPLAY;
102                    break;
103            }
104
105            if (command != null) {
106                if (action == KeyEvent.ACTION_DOWN) {
107                    if (mDown) {
108                        if ((MediaPlaybackService.CMDTOGGLEPAUSE.equals(command) ||
109                                MediaPlaybackService.CMDPLAY.equals(command))
110                                && mLastClickTime != 0
111                                && eventtime - mLastClickTime > LONG_PRESS_DELAY) {
112                            mHandler.sendMessage(
113                                    mHandler.obtainMessage(MSG_LONGPRESS_TIMEOUT, context));
114                        }
115                    } else if (event.getRepeatCount() == 0) {
116                        // only consider the first event in a sequence, not the repeat events,
117                        // so that we don't trigger in cases where the first event went to
118                        // a different app (e.g. when the user ends a phone call by
119                        // long pressing the headset button)
120
121                        // The service may or may not be running, but we need to send it
122                        // a command.
123                        Intent i = new Intent(context, MediaPlaybackService.class);
124                        i.setAction(MediaPlaybackService.SERVICECMD);
125                        if (keycode == KeyEvent.KEYCODE_HEADSETHOOK &&
126                                eventtime - mLastClickTime < 300) {
127                            i.putExtra(MediaPlaybackService.CMDNAME, MediaPlaybackService.CMDNEXT);
128                            context.startService(i);
129                            mLastClickTime = 0;
130                        } else {
131                            i.putExtra(MediaPlaybackService.CMDNAME, command);
132                            context.startService(i);
133                            mLastClickTime = eventtime;
134                        }
135
136                        mLaunched = false;
137                        mDown = true;
138                    }
139                } else {
140                    mHandler.removeMessages(MSG_LONGPRESS_TIMEOUT);
141                    mDown = false;
142                }
143                if (isOrderedBroadcast()) {
144                    abortBroadcast();
145                }
146            }
147        }
148    }
149}
150