1792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/*
2792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *
4792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * you may not use this file except in compliance with the License.
6792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * You may obtain a copy of the License at
7792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *
8792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *
10792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * See the License for the specific language governing permissions and
14792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * limitations under the License.
15792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */
16792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
17792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpackage com.android.music;
18792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
1922c36be119e377b40c9c8598e08e95975197b990Marco Nelissenimport android.content.BroadcastReceiver;
20792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Context;
21792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Intent;
22792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.media.AudioManager;
23792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Handler;
24792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.os.Message;
2522c36be119e377b40c9c8598e08e95975197b990Marco Nelissenimport android.view.KeyEvent;
26792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
27792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/**
28792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *
29792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */
30792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpublic class MediaButtonIntentReceiver extends BroadcastReceiver {
31792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
32792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static final int MSG_LONGPRESS_TIMEOUT = 1;
33792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static final int LONG_PRESS_DELAY = 1000;
34792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
35792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static long mLastClickTime = 0;
36792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static boolean mDown = false;
37792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static boolean mLaunched = false;
38792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
39792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static Handler mHandler = new Handler() {
40792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        @Override
41792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        public void handleMessage(Message msg) {
42792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            switch (msg.what) {
43792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                case MSG_LONGPRESS_TIMEOUT:
44792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    if (!mLaunched) {
45792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        Context context = (Context)msg.obj;
46792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        Intent i = new Intent();
47792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        i.putExtra("autoshuffle", "true");
48792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        i.setClass(context, MusicBrowserActivity.class);
49792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
50792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        context.startActivity(i);
51792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        mLaunched = true;
52792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    }
53792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
54792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
55792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
56792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    };
57792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
58792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    @Override
59792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public void onReceive(Context context, Intent intent) {
60792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        String intentAction = intent.getAction();
61792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intentAction)) {
62792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            Intent i = new Intent(context, MediaPlaybackService.class);
63792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            i.setAction(MediaPlaybackService.SERVICECMD);
64792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            i.putExtra(MediaPlaybackService.CMDNAME, MediaPlaybackService.CMDPAUSE);
65792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            context.startService(i);
66792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        } else if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
67792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            KeyEvent event = (KeyEvent)
68792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
69792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
70792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            if (event == null) {
71792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                return;
72792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
73792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
74792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            int keycode = event.getKeyCode();
75792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            int action = event.getAction();
76792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            long eventtime = event.getEventTime();
77792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
78792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            // single quick press: pause/resume.
79792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            // double press: next track
80792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            // long press: start auto-shuffle mode.
81792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
82792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            String command = null;
83792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            switch (keycode) {
8425078dab32659e384ee6607b476b5a3a96b3798aAndy Stadler                case KeyEvent.KEYCODE_MEDIA_STOP:
85792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    command = MediaPlaybackService.CMDSTOP;
86792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
87792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                case KeyEvent.KEYCODE_HEADSETHOOK:
8825078dab32659e384ee6607b476b5a3a96b3798aAndy Stadler                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
89792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    command = MediaPlaybackService.CMDTOGGLEPAUSE;
90792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
9125078dab32659e384ee6607b476b5a3a96b3798aAndy Stadler                case KeyEvent.KEYCODE_MEDIA_NEXT:
92792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    command = MediaPlaybackService.CMDNEXT;
93792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
9425078dab32659e384ee6607b476b5a3a96b3798aAndy Stadler                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
95792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    command = MediaPlaybackService.CMDPREVIOUS;
96792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
97fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                case KeyEvent.KEYCODE_MEDIA_PAUSE:
98fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                    command = MediaPlaybackService.CMDPAUSE;
99fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                    break;
100fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                case KeyEvent.KEYCODE_MEDIA_PLAY:
101fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                    command = MediaPlaybackService.CMDPLAY;
102fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                    break;
103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
104792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            if (command != null) {
106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                if (action == KeyEvent.ACTION_DOWN) {
10705a0cdbe327ce82165bf5fe4010414173fcdaae0Mike Lockwood                    if (mDown) {
108fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                        if ((MediaPlaybackService.CMDTOGGLEPAUSE.equals(command) ||
109fc1c0dc301b5cae2e8c5661e7a217dc57dacac1eMarco Nelissen                                MediaPlaybackService.CMDPLAY.equals(command))
11005a0cdbe327ce82165bf5fe4010414173fcdaae0Mike Lockwood                                && mLastClickTime != 0
11105a0cdbe327ce82165bf5fe4010414173fcdaae0Mike Lockwood                                && eventtime - mLastClickTime > LONG_PRESS_DELAY) {
11205a0cdbe327ce82165bf5fe4010414173fcdaae0Mike Lockwood                            mHandler.sendMessage(
11305a0cdbe327ce82165bf5fe4010414173fcdaae0Mike Lockwood                                    mHandler.obtainMessage(MSG_LONGPRESS_TIMEOUT, context));
114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
115f6e84b32a7d78ee23703b4db5913fea534362facMarco Nelissen                    } else if (event.getRepeatCount() == 0) {
116f6e84b32a7d78ee23703b4db5913fea534362facMarco Nelissen                        // only consider the first event in a sequence, not the repeat events,
117f6e84b32a7d78ee23703b4db5913fea534362facMarco Nelissen                        // so that we don't trigger in cases where the first event went to
118f6e84b32a7d78ee23703b4db5913fea534362facMarco Nelissen                        // a different app (e.g. when the user ends a phone call by
119f6e84b32a7d78ee23703b4db5913fea534362facMarco Nelissen                        // long pressing the headset button)
12005a0cdbe327ce82165bf5fe4010414173fcdaae0Mike Lockwood
121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        // The service may or may not be running, but we need to send it
122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        // a command.
123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        Intent i = new Intent(context, MediaPlaybackService.class);
124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        i.setAction(MediaPlaybackService.SERVICECMD);
125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        if (keycode == KeyEvent.KEYCODE_HEADSETHOOK &&
126792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                eventtime - mLastClickTime < 300) {
127792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            i.putExtra(MediaPlaybackService.CMDNAME, MediaPlaybackService.CMDNEXT);
128792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            context.startService(i);
129792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            mLastClickTime = 0;
130792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        } else {
131792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            i.putExtra(MediaPlaybackService.CMDNAME, command);
132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            context.startService(i);
133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            mLastClickTime = eventtime;
134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
136792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        mLaunched = false;
137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        mDown = true;
138792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    }
139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                } else {
140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    mHandler.removeMessages(MSG_LONGPRESS_TIMEOUT);
141792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    mDown = false;
142792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                }
1433d22fc22dd66be08df07c86edd533dfe3d06efc1Jean-Michel Trivi                if (isOrderedBroadcast()) {
1443d22fc22dd66be08df07c86edd533dfe3d06efc1Jean-Michel Trivi                    abortBroadcast();
1453d22fc22dd66be08df07c86edd533dfe3d06efc1Jean-Michel Trivi                }
146792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
147792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
148792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
149792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project}
150