public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) { ... KeyEvent fallbackEvent = null; if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { final KeyCharacterMap kcm = event.getKeyCharacterMap(); final int keyCode = event.getKeyCode(); final int metaState = event.getMetaState(); final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0;
// Check for fallback actions specified by the key character map. final FallbackAction fallbackAction; if (initialDown) { fallbackAction = kcm.getFallbackAction(keyCode, metaState); } else { fallbackAction = mFallbackActions.get(keyCode); }
if (fallbackAction != null) { if (DEBUG_INPUT) { Slog.d(TAG, "Fallback: keyCode=" + fallbackAction.keyCode + " metaState=" + Integer.toHexString(fallbackAction.metaState)); }
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { ... case KeyEvent.KEYCODE_POWER: { result &= ~ACTION_PASS_TO_USER; isWakeKey = false; // wake-up will be handled separately if (down) { interceptPowerKeyDown(event, interactive); } else { interceptPowerKeyUp(event, interactive, canceled); } break; } ...
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) { ... // Latch power key state to detect screenshot chord. if (interactive && !mScreenshotChordPowerKeyTriggered && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { mScreenshotChordPowerKeyTriggered = true; mScreenshotChordPowerKeyTime = event.getDownTime(); interceptScreenshotChord(); }
// Stop ringing or end call if configured to do so when power is pressed. TelecomManager telecomManager = getTelecommService(); boolean hungUp = false; if (telecomManager != null) { if (telecomManager.isRinging()) { // Pressing Power while there's a ringing incoming // call should silence the ringer. telecomManager.silenceRinger(); } else if ((mIncallPowerBehavior & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0 && telecomManager.isInCall() && interactive) { // Otherwise, if "Power button ends call" is enabled, // the Power button will hang up any current active call. hungUp = telecomManager.endCall(); } }
// If the power key has still not yet been handled, then detect short // press, long press, or multi press and decide what to do. mPowerKeyHandled = hungUp || mScreenshotChordVolumeDownKeyTriggered || mScreenshotChordVolumeUpKeyTriggered; if (!mPowerKeyHandled) { if (interactive) { // When interactive, we're already awake. // Wait for a long press or for the button to be released to decide what to do. if (hasLongPressOnPowerBehavior()) { Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); } } else { wakeUpFromPowerKey(event.getDownTime());
if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) { Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); mBeganFromNonInteractive = true; } else { final int maxCount = getMaxMultiPressPowerCount();
void showGlobalActionsInternal() { sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); if (mGlobalActions == null) { mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs); } final boolean keyguardShowing = isKeyguardShowingAndNotOccluded(); mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); if (keyguardShowing) { // since it took two seconds of long press to bring this up, // poke the wake lock so they have some time to see the dialog. mPowerManager.userActivity(SystemClock.uptimeMillis(), false); } }
// If we only have 1 item and it's a simple press action, just do this action. if (mAdapter.getCount() == 1 && mAdapter.getItem(0) instanceof SinglePressAction && !(mAdapter.getItem(0) instanceof LongPressAction)) { ((SinglePressAction) mAdapter.getItem(0)).onPress(); } else { WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes(); attrs.setTitle("GlobalActions"); mDialog.getWindow().setAttributes(attrs); mDialog.show(); mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND); }
@Override protected void changeStateFromPress(boolean buttonOn) { if (!mHasTelephony) return;
// In ECM mode airplane state cannot be changed if (!(Boolean.parseBoolean( SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) { mState = buttonOn ? State.TurningOn : State.TurningOff; mAirplaneState = mState; } }
public boolean showDuringKeyguard() { return true; }
public boolean showBeforeProvisioning() { return false; } }; onAirplaneModeChanged();
mItems = new ArrayList<Action>(); String[] defaultActions = mContext.getResources().getStringArray( com.android.internal.R.array.config_globalActionsList);
ArraySet<String> addedKeys = new ArraySet<String>(); for (int i = 0; i < defaultActions.length; i++) { String actionKey = defaultActions[i]; if (addedKeys.contains(actionKey)) { // If we already have added this, don't add it again. continue; } if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) { mItems.add(new PowerAction()); } else if (GLOBAL_ACTION_KEY_AIRPLANE.equals(actionKey)) { mItems.add(mAirplaneModeOn); } else if (GLOBAL_ACTION_KEY_BUGREPORT.equals(actionKey)) { if (Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) { mItems.add(getBugReportAction()); } } else if (GLOBAL_ACTION_KEY_SILENT.equals(actionKey)) { if (mShowSilentToggle) { mItems.add(mSilentModeAction); } } else if (GLOBAL_ACTION_KEY_USERS.equals(actionKey)) { if (SystemProperties.getBoolean("fw.power_user_switcher", false)) { addUsersToMenu(mItems); } } else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) { mItems.add(getSettingsAction()); } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) { mItems.add(getLockdownAction()); } else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) { mItems.add(getVoiceAssistAction()); } else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) { mItems.add(getAssistAction()); } else { Log.e(TAG, "Invalid global action key " + actionKey); } // Add here so we don't add more than one. addedKeys.add(actionKey); }
private final class PowerAction extends SinglePressAction implements LongPressAction { private PowerAction() { super(com.android.internal.R.drawable.ic_lock_power_off, R.string.global_action_power_off); }
@Override public boolean onLongPress() { UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE); if (!um.hasUserRestriction(UserManager.DISALLOW_SAFE_BOOT)) { mWindowManagerFuncs.rebootSafeMode(true); return true; } return false; }
@Override public boolean showDuringKeyguard() { return true; }
@Override public boolean showBeforeProvisioning() { return true; }
@Override public void onPress() { // shutdown by making sure radio and power are handled accordingly. mWindowManagerFuncs.shutdown(false /* confirm */); } }
static void shutdownInner(final Context context, boolean confirm) { // ensure that only one thread is trying to power down. // any additional calls are just returned synchronized (sIsStartedGuard) { if (sIsStarted) { Log.d(TAG, "Request to shutdown already running, returning."); return; } }
final int longPressBehavior = context.getResources().getInteger( com.android.internal.R.integer.config_longPressOnPowerBehavior); final int resourceId = mRebootSafeMode ? com.android.internal.R.string.reboot_safemode_confirm : (longPressBehavior == 2 ? com.android.internal.R.string.shutdown_confirm_question : com.android.internal.R.string.shutdown_confirm);
Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
if (confirm) { final CloseDialogReceiver closer = new CloseDialogReceiver(context); if (sConfirmDialog != null) { sConfirmDialog.dismiss(); } sConfirmDialog = new AlertDialog.Builder(context) .setTitle(mRebootSafeMode ? com.android.internal.R.string.reboot_safemode_title : com.android.internal.R.string.power_off) .setMessage(resourceId) .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { beginShutdownSequence(context); } }) .setNegativeButton(com.android.internal.R.string.no, null) .create(); closer.dialog = sConfirmDialog; sConfirmDialog.setOnDismissListener(closer); sConfirmDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); sConfirmDialog.show(); } else { beginShutdownSequence(context); } }
// make sure we never fall asleep again sInstance.mCpuWakeLock = null; try { sInstance.mCpuWakeLock = sInstance.mPowerManager.newWakeLock( PowerManager.PARTIAL_WAKE_LOCK, TAG + "-cpu"); sInstance.mCpuWakeLock.setReferenceCounted(false); sInstance.mCpuWakeLock.acquire(); } catch (SecurityException e) { Log.w(TAG, "No permission to acquire wake lock", e); sInstance.mCpuWakeLock = null; }
// also make sure the screen stays on for better user experience sInstance.mScreenWakeLock = null; if (sInstance.mPowerManager.isScreenOn()) { try { sInstance.mScreenWakeLock = sInstance.mPowerManager.newWakeLock( PowerManager.FULL_WAKE_LOCK, TAG + "-screen"); sInstance.mScreenWakeLock.setReferenceCounted(false); sInstance.mScreenWakeLock.acquire(); } catch (SecurityException e) { Log.w(TAG, "No permission to acquire wake lock", e); sInstance.mScreenWakeLock = null; } }
// start the thread that initiates shutdown sInstance.mHandler = new Handler() { }; sInstance.start(); }