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