首先找到开机键的响应事件frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager
@Override public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { if (!mSystemBooted) {
case KeyEvent.KEYCODE_POWER: { EventLogTags.writeInterceptPower( KeyEvent.actionToString(event.getAction()), mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter); // Any activity on the power button stops the accessibility shortcut cancelPendingAccessibilityShortcutAction(); result &= ~ACTION_PASS_TO_USER; isWakeKey = false; // wake-up will be handled separately if (down) { interceptPowerKeyDown(event, interactive); } else { interceptPowerKeyUp(event, interactive, canceled); } break;
进入方法interceptPowerKeyDown
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) { // Hold a wake lock until the power key is released. if (!mPowerKeyWakeLock.isHeld()) { mPowerKeyWakeLock.acquire(); } // Cancel multi-press detection timeout. if (mPowerKeyPressCounter != 0) { mHandler.removeMessages(MSG_POWER_DELAYED_PRESS); } mWindowManagerFuncs.onPowerKeyDown(interactive); // Latch power key state to detect screenshot chord. if (interactive && !mScreenshotChordPowerKeyTriggered && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { mScreenshotChordPowerKeyTriggered = true; mScreenshotChordPowerKeyTime = event.getDownTime(); interceptScreenshotChord(); interceptRingerToggleChord(); }
进入方法interceptRingerToggleChord
private void interceptRingerToggleChord() { if (mRingerToggleChord != Settings.Secure.VOLUME_HUSH_OFF && mScreenshotChordPowerKeyTriggered && mA11yShortcutChordVolumeUpKeyTriggered) { final long now = SystemClock.uptimeMillis(); if (now <= mA11yShortcutChordVolumeUpKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS && now <= mScreenshotChordPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) { mA11yShortcutChordVolumeUpKeyConsumed = true; cancelPendingPowerKeyAction(); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RINGER_TOGGLE_CHORD), getRingerToggleChordDelay()); } } }
进入mHandler
case MSG_RINGER_TOGGLE_CHORD: handleRingerChordGesture(); break;
private void handleRingerChordGesture() { if (mRingerToggleChord == VOLUME_HUSH_OFF) { return; } getAudioManagerInternal(); mAudioManagerInternal.silenceRingerModeInternal("volume_hush"); Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.HUSH_GESTURE_USED, 1); mLogger.action(MetricsProto.MetricsEvent.ACTION_HUSH_GESTURE, mRingerToggleChord); }
进入方法AudioService文件frameworks/base/services/core/java/com/android/server/audio/AudioService
public void silenceRingerModeInternal(String reason) { VibrationEffect effect = null; int ringerMode = AudioManager.RINGER_MODE_SILENT; int toastText = 0; int silenceRingerSetting = Settings.Secure.VOLUME_HUSH_OFF; if (mContext.getResources() .getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) { silenceRingerSetting = Settings.Secure.getIntForUser(mContentResolver, Settings.Secure.VOLUME_HUSH_GESTURE, VOLUME_HUSH_OFF, UserHandle.USER_CURRENT); } switch(silenceRingerSetting) { case VOLUME_HUSH_MUTE: effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK); ringerMode = AudioManager.RINGER_MODE_SILENT; toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent; break; case VOLUME_HUSH_VIBRATE: effect = VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK); ringerMode = AudioManager.RINGER_MODE_VIBRATE; toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate; break; } maybeVibrate(effect, reason); setRingerModeInternal(ringerMode, reason); Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show(); }
这个方法里修改了变量ringerMode,在上篇随笔里讲了这个ringerMode