PhoneFallbackEventHandler.java revision 47e6b1b5eef8ee99872f278f66bc498c4fcca0d8
1/* 2 * Copyright (C) 2008 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.internal.policy.impl; 18 19import android.app.KeyguardManager; 20import android.app.SearchManager; 21import android.content.ActivityNotFoundException; 22import android.content.Context; 23import android.content.Intent; 24import android.content.res.Configuration; 25import android.media.AudioManager; 26import android.telephony.TelephonyManager; 27import android.util.EventLog; 28import android.util.Slog; 29import android.view.View; 30import android.view.HapticFeedbackConstants; 31import android.view.FallbackEventHandler; 32import android.view.KeyEvent; 33 34public class PhoneFallbackEventHandler implements FallbackEventHandler { 35 private static String TAG = "PhoneFallbackEventHandler"; 36 private static final boolean DEBUG = false; 37 38 Context mContext; 39 View mView; 40 41 AudioManager mAudioManager; 42 KeyguardManager mKeyguardManager; 43 SearchManager mSearchManager; 44 TelephonyManager mTelephonyManager; 45 46 public PhoneFallbackEventHandler(Context context) { 47 mContext = context; 48 } 49 50 public void setView(View v) { 51 mView = v; 52 } 53 54 public void preDispatchKeyEvent(KeyEvent event) { 55 getAudioManager().preDispatchKeyEvent(event.getKeyCode(), 56 AudioManager.USE_DEFAULT_STREAM_TYPE); 57 } 58 59 public boolean dispatchKeyEvent(KeyEvent event) { 60 61 final int action = event.getAction(); 62 final int keyCode = event.getKeyCode(); 63 64 if (action == KeyEvent.ACTION_DOWN) { 65 return onKeyDown(keyCode, event); 66 } else { 67 return onKeyUp(keyCode, event); 68 } 69 } 70 71 boolean onKeyDown(int keyCode, KeyEvent event) { 72 /* **************************************************************************** 73 * HOW TO DECIDE WHERE YOUR KEY HANDLING GOES. 74 * See the comment in PhoneWindow.onKeyDown 75 * ****************************************************************************/ 76 final KeyEvent.DispatcherState dispatcher = mView.getKeyDispatcherState(); 77 78 switch (keyCode) { 79 case KeyEvent.KEYCODE_VOLUME_UP: 80 case KeyEvent.KEYCODE_VOLUME_DOWN: 81 case KeyEvent.KEYCODE_VOLUME_MUTE: { 82 getAudioManager().handleKeyDown(keyCode, AudioManager.USE_DEFAULT_STREAM_TYPE); 83 return true; 84 } 85 86 87 case KeyEvent.KEYCODE_MEDIA_PLAY: 88 case KeyEvent.KEYCODE_MEDIA_PAUSE: 89 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 90 /* Suppress PLAY/PAUSE toggle when phone is ringing or in-call 91 * to avoid music playback */ 92 if (getTelephonyManager().getCallState() != TelephonyManager.CALL_STATE_IDLE) { 93 return true; // suppress key event 94 } 95 case KeyEvent.KEYCODE_MUTE: 96 case KeyEvent.KEYCODE_HEADSETHOOK: 97 case KeyEvent.KEYCODE_MEDIA_STOP: 98 case KeyEvent.KEYCODE_MEDIA_NEXT: 99 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 100 case KeyEvent.KEYCODE_MEDIA_REWIND: 101 case KeyEvent.KEYCODE_MEDIA_RECORD: 102 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: { 103 Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); 104 intent.putExtra(Intent.EXTRA_KEY_EVENT, event); 105 mContext.sendOrderedBroadcast(intent, null); 106 return true; 107 } 108 109 case KeyEvent.KEYCODE_CALL: { 110 if (getKeyguardManager().inKeyguardRestrictedInputMode() || dispatcher == null) { 111 break; 112 } 113 if (event.getRepeatCount() == 0) { 114 dispatcher.startTracking(event, this); 115 } else if (event.isLongPress() && dispatcher.isTracking(event)) { 116 dispatcher.performedLongPress(event); 117 mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 118 // launch the VoiceDialer 119 Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND); 120 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 121 try { 122 sendCloseSystemWindows(); 123 mContext.startActivity(intent); 124 } catch (ActivityNotFoundException e) { 125 startCallActivity(); 126 } 127 } 128 return true; 129 } 130 131 case KeyEvent.KEYCODE_CAMERA: { 132 if (getKeyguardManager().inKeyguardRestrictedInputMode() || dispatcher == null) { 133 break; 134 } 135 if (event.getRepeatCount() == 0) { 136 dispatcher.startTracking(event, this); 137 } else if (event.isLongPress() && dispatcher.isTracking(event)) { 138 dispatcher.performedLongPress(event); 139 mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 140 sendCloseSystemWindows(); 141 // Broadcast an intent that the Camera button was longpressed 142 Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null); 143 intent.putExtra(Intent.EXTRA_KEY_EVENT, event); 144 mContext.sendOrderedBroadcast(intent, null); 145 } 146 return true; 147 } 148 149 case KeyEvent.KEYCODE_SEARCH: { 150 if (getKeyguardManager().inKeyguardRestrictedInputMode() || dispatcher == null) { 151 break; 152 } 153 if (event.getRepeatCount() == 0) { 154 dispatcher.startTracking(event, this); 155 } else if (event.isLongPress() && dispatcher.isTracking(event)) { 156 Configuration config = mContext.getResources().getConfiguration(); 157 if (config.keyboard == Configuration.KEYBOARD_NOKEYS 158 || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) { 159 // launch the search activity 160 Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); 161 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 162 try { 163 mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 164 sendCloseSystemWindows(); 165 getSearchManager().stopSearch(); 166 mContext.startActivity(intent); 167 // Only clear this if we successfully start the 168 // activity; otherwise we will allow the normal short 169 // press action to be performed. 170 dispatcher.performedLongPress(event); 171 return true; 172 } catch (ActivityNotFoundException e) { 173 // Ignore 174 } 175 } 176 } 177 break; 178 } 179 } 180 return false; 181 } 182 183 boolean onKeyUp(int keyCode, KeyEvent event) { 184 if (DEBUG) { 185 Slog.d(TAG, "up " + keyCode); 186 } 187 final KeyEvent.DispatcherState dispatcher = mView.getKeyDispatcherState(); 188 if (dispatcher != null) { 189 dispatcher.handleUpEvent(event); 190 } 191 192 switch (keyCode) { 193 case KeyEvent.KEYCODE_VOLUME_UP: 194 case KeyEvent.KEYCODE_VOLUME_DOWN: 195 case KeyEvent.KEYCODE_VOLUME_MUTE: { 196 if (!event.isCanceled()) { 197 AudioManager audioManager = (AudioManager)mContext.getSystemService( 198 Context.AUDIO_SERVICE); 199 if (audioManager != null) { 200 getAudioManager().handleKeyUp(keyCode, 201 AudioManager.USE_DEFAULT_STREAM_TYPE); 202 } 203 } 204 return true; 205 } 206 207 case KeyEvent.KEYCODE_HEADSETHOOK: 208 case KeyEvent.KEYCODE_MUTE: 209 case KeyEvent.KEYCODE_MEDIA_PLAY: 210 case KeyEvent.KEYCODE_MEDIA_PAUSE: 211 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 212 case KeyEvent.KEYCODE_MEDIA_STOP: 213 case KeyEvent.KEYCODE_MEDIA_NEXT: 214 case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 215 case KeyEvent.KEYCODE_MEDIA_REWIND: 216 case KeyEvent.KEYCODE_MEDIA_RECORD: 217 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: { 218 Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); 219 intent.putExtra(Intent.EXTRA_KEY_EVENT, event); 220 mContext.sendOrderedBroadcast(intent, null); 221 return true; 222 } 223 224 case KeyEvent.KEYCODE_CAMERA: { 225 if (getKeyguardManager().inKeyguardRestrictedInputMode()) { 226 break; 227 } 228 if (event.isTracking() && !event.isCanceled()) { 229 // Add short press behavior here if desired 230 } 231 return true; 232 } 233 234 case KeyEvent.KEYCODE_CALL: { 235 if (getKeyguardManager().inKeyguardRestrictedInputMode()) { 236 break; 237 } 238 if (event.isTracking() && !event.isCanceled()) { 239 startCallActivity(); 240 } 241 return true; 242 } 243 } 244 return false; 245 } 246 247 void startCallActivity() { 248 sendCloseSystemWindows(); 249 Intent intent = new Intent(Intent.ACTION_CALL_BUTTON); 250 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 251 try { 252 mContext.startActivity(intent); 253 } catch (ActivityNotFoundException e) { 254 Slog.w(TAG, "No activity found for android.intent.action.CALL_BUTTON."); 255 } 256 } 257 258 SearchManager getSearchManager() { 259 if (mSearchManager == null) { 260 mSearchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); 261 } 262 return mSearchManager; 263 } 264 265 TelephonyManager getTelephonyManager() { 266 if (mTelephonyManager == null) { 267 mTelephonyManager = (TelephonyManager)mContext.getSystemService( 268 Context.TELEPHONY_SERVICE); 269 } 270 return mTelephonyManager; 271 } 272 273 KeyguardManager getKeyguardManager() { 274 if (mKeyguardManager == null) { 275 mKeyguardManager = (KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE); 276 } 277 return mKeyguardManager; 278 } 279 280 AudioManager getAudioManager() { 281 if (mAudioManager == null) { 282 mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); 283 } 284 return mAudioManager; 285 } 286 287 void sendCloseSystemWindows() { 288 PhoneWindowManager.sendCloseSystemWindows(mContext, null); 289 } 290} 291 292