OSDN Git Service

Eleven: Cleanup all the whitespace
[android-x86/packages-apps-Eleven.git] / src / com / cyanogenmod / eleven / MediaButtonIntentReceiver.java
1 /*
2  * Copyright (C) 2007 The Android Open Source Project Licensed under the Apache
3  * License, Version 2.0 (the "License"); you may not use this file except in
4  * compliance with the License. You may obtain a copy of the License at
5  * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
6  * or agreed to in writing, software distributed under the License is
7  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
8  * KIND, either express or implied. See the License for the specific language
9  * governing permissions and limitations under the License.
10  */
11
12 package com.cyanogenmod.eleven;
13
14 import android.content.Context;
15 import android.content.Intent;
16 import android.media.AudioManager;
17 import android.os.Handler;
18 import android.os.Message;
19 import android.os.PowerManager;
20 import android.os.PowerManager.WakeLock;
21 import android.support.v4.content.WakefulBroadcastReceiver;
22 import android.util.Log;
23 import android.view.KeyEvent;
24
25 import com.cyanogenmod.eleven.ui.activities.HomeActivity;
26
27 /**
28  * Used to control headset playback.
29  *   Single press: pause/resume
30  *   Double press: next track
31  *   Triple press: previous track
32  *   Long press: voice search
33  */
34 public class MediaButtonIntentReceiver extends WakefulBroadcastReceiver {
35     private static final boolean DEBUG = false;
36     private static final String TAG = "MediaButtonIntentReceiver";
37
38     private static final int MSG_LONGPRESS_TIMEOUT = 1;
39     private static final int MSG_HEADSET_DOUBLE_CLICK_TIMEOUT = 2;
40
41     private static final int LONG_PRESS_DELAY = 1000;
42     private static final int DOUBLE_CLICK = 800;
43
44     private static WakeLock mWakeLock = null;
45     private static int mClickCounter = 0;
46     private static long mLastClickTime = 0;
47     private static boolean mDown = false;
48     private static boolean mLaunched = false;
49
50     private static Handler mHandler = new Handler() {
51
52         /**
53          * {@inheritDoc}
54          */
55         @Override
56         public void handleMessage(final Message msg) {
57             switch (msg.what) {
58                 case MSG_LONGPRESS_TIMEOUT:
59                     if (DEBUG) Log.v(TAG, "Handling longpress timeout, launched " + mLaunched);
60                     if (!mLaunched) {
61                         final Context context = (Context)msg.obj;
62                         final Intent i = new Intent();
63                         i.setClass(context, HomeActivity.class);
64                         i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
65                         context.startActivity(i);
66                         mLaunched = true;
67                     }
68                     break;
69
70                 case MSG_HEADSET_DOUBLE_CLICK_TIMEOUT:
71                     final int clickCount = msg.arg1;
72                     final String command;
73
74                     if (DEBUG) Log.v(TAG, "Handling headset click, count = " + clickCount);
75                     switch (clickCount) {
76                         case 1: command = MusicPlaybackService.CMDTOGGLEPAUSE; break;
77                         case 2: command = MusicPlaybackService.CMDNEXT; break;
78                         case 3: command = MusicPlaybackService.CMDPREVIOUS; break;
79                         default: command = null; break;
80                     }
81
82                     if (command != null) {
83                         final Context context = (Context)msg.obj;
84                         startService(context, command);
85                     }
86                     break;
87             }
88             releaseWakeLockIfHandlerIdle();
89         }
90     };
91
92     /**
93      * {@inheritDoc}
94      */
95     @Override
96     public void onReceive(final Context context, final Intent intent) {
97         if (DEBUG) Log.v(TAG, "Received intent: " + intent);
98         final String intentAction = intent.getAction();
99         if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intentAction)) {
100             startService(context, MusicPlaybackService.CMDPAUSE);
101         } else if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
102             final KeyEvent event = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
103             if (event == null) {
104                 return;
105             }
106
107             final int keycode = event.getKeyCode();
108             final int action = event.getAction();
109             final long eventtime = event.getEventTime();
110
111             String command = null;
112             switch (keycode) {
113                 case KeyEvent.KEYCODE_MEDIA_STOP:
114                     command = MusicPlaybackService.CMDSTOP;
115                     break;
116                 case KeyEvent.KEYCODE_HEADSETHOOK:
117                 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
118                     command = MusicPlaybackService.CMDTOGGLEPAUSE;
119                     break;
120                 case KeyEvent.KEYCODE_MEDIA_NEXT:
121                     command = MusicPlaybackService.CMDNEXT;
122                     break;
123                 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
124                     command = MusicPlaybackService.CMDPREVIOUS;
125                     break;
126                 case KeyEvent.KEYCODE_MEDIA_PAUSE:
127                     command = MusicPlaybackService.CMDPAUSE;
128                     break;
129                 case KeyEvent.KEYCODE_MEDIA_PLAY:
130                     command = MusicPlaybackService.CMDPLAY;
131                     break;
132             }
133             if (command != null) {
134                 if (action == KeyEvent.ACTION_DOWN) {
135                     if (mDown) {
136                         if (MusicPlaybackService.CMDTOGGLEPAUSE.equals(command)
137                                 || MusicPlaybackService.CMDPLAY.equals(command)) {
138                             if (mLastClickTime != 0
139                                     && eventtime - mLastClickTime > LONG_PRESS_DELAY) {
140                                 acquireWakeLockAndSendMessage(context,
141                                         mHandler.obtainMessage(MSG_LONGPRESS_TIMEOUT, context), 0);
142                             }
143                         }
144                     } else if (event.getRepeatCount() == 0) {
145                         // Only consider the first event in a sequence, not the repeat events,
146                         // so that we don't trigger in cases where the first event went to
147                         // a different app (e.g. when the user ends a phone call by
148                         // long pressing the headset button)
149
150                         // The service may or may not be running, but we need to send it
151                         // a command.
152                         if (keycode == KeyEvent.KEYCODE_HEADSETHOOK) {
153                             if (eventtime - mLastClickTime >= DOUBLE_CLICK) {
154                                 mClickCounter = 0;
155                             }
156
157                             mClickCounter++;
158                             if (DEBUG) Log.v(TAG, "Got headset click, count = " + mClickCounter);
159                             mHandler.removeMessages(MSG_HEADSET_DOUBLE_CLICK_TIMEOUT);
160
161                             Message msg = mHandler.obtainMessage(
162                                     MSG_HEADSET_DOUBLE_CLICK_TIMEOUT, mClickCounter, 0, context);
163
164                             long delay = mClickCounter < 3 ? DOUBLE_CLICK : 0;
165                             if (mClickCounter >= 3) {
166                                 mClickCounter = 0;
167                             }
168                             mLastClickTime = eventtime;
169                             acquireWakeLockAndSendMessage(context, msg, delay);
170                         } else {
171                             startService(context, command);
172                         }
173                         mLaunched = false;
174                         mDown = true;
175                     }
176                 } else {
177                     mHandler.removeMessages(MSG_LONGPRESS_TIMEOUT);
178                     mDown = false;
179                 }
180                 if (isOrderedBroadcast()) {
181                     abortBroadcast();
182                 }
183                 releaseWakeLockIfHandlerIdle();
184             }
185         }
186     }
187
188     private static void startService(Context context, String command) {
189         final Intent i = new Intent(context, MusicPlaybackService.class);
190         i.setAction(MusicPlaybackService.SERVICECMD);
191         i.putExtra(MusicPlaybackService.CMDNAME, command);
192         i.putExtra(MusicPlaybackService.FROM_MEDIA_BUTTON, true);
193         startWakefulService(context, i);
194     }
195
196     private static void acquireWakeLockAndSendMessage(Context context, Message msg, long delay) {
197         if (mWakeLock == null) {
198             Context appContext = context.getApplicationContext();
199             PowerManager pm = (PowerManager) appContext.getSystemService(Context.POWER_SERVICE);
200             mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Eleven headset button");
201             mWakeLock.setReferenceCounted(false);
202         }
203         if (DEBUG) Log.v(TAG, "Acquiring wake lock and sending " + msg.what);
204         // Make sure we don't indefinitely hold the wake lock under any circumstances
205         mWakeLock.acquire(10000);
206
207         mHandler.sendMessageDelayed(msg, delay);
208     }
209
210     private static void releaseWakeLockIfHandlerIdle() {
211         if (mHandler.hasMessages(MSG_LONGPRESS_TIMEOUT)
212                 || mHandler.hasMessages(MSG_HEADSET_DOUBLE_CLICK_TIMEOUT)) {
213             if (DEBUG) Log.v(TAG, "Handler still has messages pending, not releasing wake lock");
214             return;
215         }
216
217         if (mWakeLock != null) {
218             if (DEBUG) Log.v(TAG, "Releasing wake lock");
219             mWakeLock.release();
220             mWakeLock = null;
221         }
222     }
223 }