frameworks/base/services/core/java/com/android/server/GestureLauncherService.java
@VisibleForTesting
static final long CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS = 300;
@VisibleForTesting
static final long POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS = 500;
/**
* Number of taps required to launch emergency gesture ui.
*/
private static final int EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD = 5;
/**
* Number of taps required to launch camera shortcut.
*/
private static final int CAMERA_POWER_TAP_COUNT_THRESHOLD = 2;
public boolean interceptPowerKeyDown (KeyEvent event, boolean interactive,MutableBoolean outLaunched) {
if (event.isLongPress()) {
// Long presses are sent as a second key down. If the long press threshold is set lower
// than the double tap of sequence interval thresholds, this could cause false double
// taps or consecutive taps, so we want to ignore the long press event.
return false;
}
boolean launchCamera = false;
boolean launchEmergencyGesture = false;
boolean intercept = false;
long powerTapInterval;synchronized (this) {
powerTapInterval = event.getEventTime() - mLastPowerDown;
mLastPowerDown = event.getEventTime();
if (powerTapInterval >= POWER_SHORT_TAP_SEQUENCE_MAX_INTERVAL_MS) {//500ms
// Tap too slow, reset consecutive tap counts.
mPowerButtonConsecutiveTaps = 1;
mPowerButtonSlowConsecutiveTaps = 1;
} else if (powerTapInterval >= CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS) {//300ms
// Tap too slow for shortcuts
mPowerButtonConsecutiveTaps = 1;
mPowerButtonSlowConsecutiveTaps++;
} else {
// Fast consecutive tap
mPowerButtonConsecutiveTaps++;
mPowerButtonSlowConsecutiveTaps++;
}
// Check if we need to launch camera or emergency gesture flows
if (mEmergencyGestureEnabled) {
// Commit to intercepting the powerkey event after the second "quick" tap to avoid
// lockscreen changes between launching camera and the emergency gesture flow.
if (mPowerButtonConsecutiveTaps > 1) {
intercept = interactive;
}
if (mPowerButtonConsecutiveTaps == EMERGENCY_GESTURE_POWER_TAP_COUNT_THRESHOLD) {//5 times
launchEmergencyGesture = true;
}}
if (mCameraDoubleTapPowerEnabled
&& powerTapInterval < CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS
&& mPowerButtonConsecutiveTaps == CAMERA_POWER_TAP_COUNT_THRESHOLD) {//2 times
launchCamera = true;
intercept = interactive;
}}
if (mPowerButtonConsecutiveTaps > 1 || mPowerButtonSlowConsecutiveTaps > 1) {
Slog.i(TAG, Long.valueOf(mPowerButtonConsecutiveTaps)
" consecutive power button taps detected, "
Long.valueOf(mPowerButtonSlowConsecutiveTaps)
" consecutive slow power button taps detected");
}
if (launchCamera ) {//打开相机
launchCamera = handleCameraGesture(false /* useWakelock */,
StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);} else if (launchEmergencyGesture ) {//打开紧急拨号
launchEmergencyGesture = handleEmergencyGesture();
}
outLaunched.value = launchCamera || launchEmergencyGesture;
return intercept && isUserSetupComplete();
}/**
* @return true if camera was launched, false otherwise.处理相机
*/
@VisibleForTesting
boolean handleCameraGesture (boolean useWakelock, int source) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "GestureLauncher:handleCameraGesture");
try {
boolean userSetupComplete = isUserSetupComplete ();
if (!userSetupComplete) {
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, ignoring camera gesture.",
userSetupComplete));
}
return false;
}
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, performing camera gesture.",
userSetupComplete));
}
if (useWakelock) {
// Make sure we don't sleep too early
mWakeLock.acquire(500L);
}
StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
service.onCameraLaunchGestureDetected(source);return true;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
/**
* @return true if emergency gesture UI was launched, false otherwise.处理紧急拨号
*/
@VisibleForTesting
boolean handleEmergencyGesture () {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"GestureLauncher:handleEmergencyGesture");
try {
boolean userSetupComplete = isUserSetupComplete ();
if (!userSetupComplete) {
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, ignoring emergency gesture.",
userSetupComplete));
}
return false;
}
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, performing emergency gesture.",
userSetupComplete));
}
StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
service.onEmergencyActionLaunchGestureDetected();return true;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
private boolean isUserSetupComplete () {
return Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
}
如果想要实现其他按键的紧急拨号?可以在此接受注册广播并处理
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
Resources resources = mContext.getResources();
if (!isGestureLauncherEnabled(resources)) {
if (DBG) Slog.d(TAG, "Gesture launcher is disabled in system properties.");
return;
}
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mPowerManager = (PowerManager) mContext.getSystemService(
Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"GestureLauncherService");
updateCameraRegistered();
updateCameraDoubleTapPowerEnabled();
updateEmergencyGestureEnabled();
mUserId = ActivityManager.getCurrentUser();
mContext.registerReceiver(mUserReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED));
//*/ add SOS for Emergency Number
mContext.registerReceiver(mUserReceiver, new IntentFilter("adnroid.intent.action.sos"));
//*/registerContentObservers();
}
}
private final BroadcastReceiver mUserReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
mUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
mContext.getContentResolver().unregisterContentObserver(mSettingObserver);
registerContentObservers();
updateCameraRegistered();
updateCameraDoubleTapPowerEnabled();
updateEmergencyGestureEnabled();
}
//*/add sos onEmergencyActionLaunchGestureDetected
else if (intent.getAction().equals("adnroid.intent.action.sos")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"GestureLauncher:handleEmergencyGesture");
try {
boolean userSetupComplete = isUserSetupComplete();
if (!userSetupComplete) {
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, ignoring emergency gesture.",
userSetupComplete));
}
}
if (DBG) {
Slog.d(TAG, String.format(
"userSetupComplete = %s, performing emergency gesture.",
userSetupComplete));
}
StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
service.onEmergencyActionLaunchGestureDetected();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
//*/}
};
其他触发广播的地方,只需在PhoneWindowManager里面拦截方法下添加对应的按键添加短按或长按的广播发送即可!!!
private void sendBC(String action){
Intent intent = new Intent();
intent.setAction(action);
android.util.Log.d("PWM","===== sendBC ===== "+action);
mContext.sendBroadcast(intent);}
sendBC("adnroid.intent.action.sos");
完结撒花!