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