Merge "frameworks/base: Fix to release references in ActivityManagerService" into gingerbread
diff --git a/api/current.xml b/api/current.xml
index e987335..f0aebeb 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -87206,6 +87206,17 @@
deprecated="not deprecated"
visibility="public"
>
+<field name="AAC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="AMR_NB"
type="int"
transient="false"
@@ -87217,6 +87228,17 @@
visibility="public"
>
</field>
+<field name="AMR_WB"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="DEFAULT"
type="int"
transient="false"
@@ -87373,6 +87395,28 @@
deprecated="not deprecated"
visibility="public"
>
+<field name="AMR_NB"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="AMR_WB"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="DEFAULT"
type="int"
transient="false"
@@ -224703,7 +224747,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 1fd31a3..1a341e1 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -544,16 +544,18 @@
* Generally, it's best to keep as little as possible in the queue thread
* because it's the most fragile.
* @param whenNanos The event time in uptime nanoseconds.
+ * @param action The key event action.
+ * @param flags The key event flags.
* @param keyCode The key code.
- * @param down True if the key is down.
+ * @param scanCode The key's scan code.
* @param policyFlags The policy flags associated with the key.
* @param isScreenOn True if the screen is already on
*
* @return The bitwise or of the {@link #ACTION_PASS_TO_USER},
* {@link #ACTION_POKE_USER_ACTIVITY} and {@link #ACTION_GO_TO_SLEEP} flags.
*/
- public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down, int policyFlags,
- boolean isScreenOn);
+ public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
+ int keyCode, int scanCode, int policyFlags, boolean isScreenOn);
/**
* Called from the input dispatcher thread before a key is dispatched to a window.
@@ -571,6 +573,7 @@
* @param action The key event action.
* @param flags The key event flags.
* @param keyCode The key code.
+ * @param scanCode The key's scan code.
* @param metaState bit mask of meta keys that are held.
* @param repeatCount Number of times a key down has repeated.
* @param policyFlags The policy flags associated with the key.
@@ -578,7 +581,7 @@
* not be further dispatched.
*/
public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
- int keyCode, int metaState, int repeatCount, int policyFlags);
+ int keyCode, int scanCode, int metaState, int repeatCount, int policyFlags);
/**
* Called when layout of the windows is about to start.
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 8e8b830..35ef4cb 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -974,8 +974,16 @@
ss.position = getSelectedItemPosition();
ss.firstId = INVALID_POSITION;
} else {
- if (haveChildren) {
- // Remember the position of the first child
+ if (haveChildren && mFirstPosition > 0) {
+ // Remember the position of the first child.
+ // We only do this if we are not currently at the top of
+ // the list, for two reasons:
+ // (1) The list may be in the process of becoming empty, in
+ // which case mItemCount may not be 0, but if we try to
+ // ask for any information about position 0 we will crash.
+ // (2) Being "at the top" seems like a special case, anyway,
+ // and the user wouldn't expect to end up somewhere else when
+ // they revisit the list even if its content has changed.
View v = getChildAt(0);
ss.viewTop = v.getTop();
int firstPos = mFirstPosition;
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 28ccc43..421ad663 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -1405,8 +1405,13 @@
void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
- if (eventEntry->type == EventEntry::TYPE_MOTION) {
+ switch (eventEntry->type) {
+ case EventEntry::TYPE_MOTION: {
const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
+ if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
+ return;
+ }
+
if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
switch (motionEntry->action) {
case AMOTION_EVENT_ACTION_DOWN:
@@ -1424,6 +1429,15 @@
break;
}
}
+ break;
+ }
+ case EventEntry::TYPE_KEY: {
+ const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
+ if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
+ return;
+ }
+ break;
+ }
}
CommandEntry* commandEntry = postCommandLocked(
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index ecabae8..32c02bc 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -178,11 +178,12 @@
/** The following formats are audio only .aac or .amr formats **/
/** @deprecated Deprecated in favor of AMR_NB */
- /** TODO: change link when AMR_NB is exposed. Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB */
+ /** Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB */
+ /** AMR NB file format */
public static final int RAW_AMR = 3;
- /** @hide AMR NB file format */
+ /** AMR NB file format */
public static final int AMR_NB = 3;
- /** @hide AMR WB file format */
+ /** AMR WB file format */
public static final int AMR_WB = 4;
/** @hide AAC ADIF file format */
public static final int AAC_ADIF = 5;
@@ -208,9 +209,9 @@
public static final int DEFAULT = 0;
/** AMR (Narrowband) audio codec */
public static final int AMR_NB = 1;
- /** @hide AMR (Wideband) audio codec */
+ /** AMR (Wideband) audio codec */
public static final int AMR_WB = 2;
- /** @hide AAC audio codec */
+ /** AAC audio codec */
public static final int AAC = 3;
/** @hide enhanced AAC audio codec */
public static final int AAC_PLUS = 4;
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index a5ef1fa..635b7d3 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -333,7 +333,12 @@
mSelector.setRightHintText(mSilentMode ? R.string.lockscreen_sound_on_label
: R.string.lockscreen_sound_off_label);
}
- mCallback.pokeWakelock();
+ // Don't poke the wake lock when returning to a state where the handle is
+ // not grabbed since that can happen when the system (instead of the user)
+ // cancels the grab.
+ if (grabbedState != SlidingTab.OnTriggerListener.NO_HANDLE) {
+ mCallback.pokeWakelock();
+ }
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 43936a4..92c41d8 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -61,6 +61,7 @@
import android.view.HapticFeedbackConstants;
import android.view.IWindowManager;
import android.view.InputChannel;
+import android.view.InputDevice;
import android.view.InputQueue;
import android.view.InputHandler;
import android.view.KeyEvent;
@@ -204,7 +205,7 @@
WindowState mKeyguard = null;
KeyguardViewMediator mKeyguardMediator;
GlobalActions mGlobalActions;
- boolean mShouldTurnOffOnKeyUp;
+ volatile boolean mPowerKeyHandled;
RecentApplicationsDialog mRecentAppsDialog;
Handler mHandler;
@@ -456,12 +457,31 @@
}
}
- Runnable mPowerLongPress = new Runnable() {
+ private void interceptPowerKeyDown(boolean handled) {
+ mPowerKeyHandled = handled;
+ if (!handled) {
+ mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
+ }
+ }
+
+ private boolean interceptPowerKeyUp(boolean canceled) {
+ if (!mPowerKeyHandled) {
+ mHandler.removeCallbacks(mPowerLongPress);
+ return !canceled;
+ } else {
+ mPowerKeyHandled = true;
+ return false;
+ }
+ }
+
+ private final Runnable mPowerLongPress = new Runnable() {
public void run() {
- mShouldTurnOffOnKeyUp = false;
- performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
- showGlobalActionsDialog();
+ if (!mPowerKeyHandled) {
+ mPowerKeyHandled = true;
+ performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
+ showGlobalActionsDialog();
+ }
}
};
@@ -1041,12 +1061,22 @@
com.android.internal.R.anim.lock_screen_behind_enter);
}
- static ITelephony getPhoneInterface() {
- return ITelephony.Stub.asInterface(ServiceManager.checkService(Context.TELEPHONY_SERVICE));
+ static ITelephony getTelephonyService() {
+ ITelephony telephonyService = ITelephony.Stub.asInterface(
+ ServiceManager.checkService(Context.TELEPHONY_SERVICE));
+ if (telephonyService == null) {
+ Log.w(TAG, "Unable to find ITelephony interface.");
+ }
+ return telephonyService;
}
- static IAudioService getAudioInterface() {
- return IAudioService.Stub.asInterface(ServiceManager.checkService(Context.AUDIO_SERVICE));
+ static IAudioService getAudioService() {
+ IAudioService audioService = IAudioService.Stub.asInterface(
+ ServiceManager.checkService(Context.AUDIO_SERVICE));
+ if (audioService == null) {
+ Log.w(TAG, "Unable to find IAudioService interface.");
+ }
+ return audioService;
}
boolean keyguardOn() {
@@ -1061,7 +1091,7 @@
/** {@inheritDoc} */
@Override
public boolean interceptKeyBeforeDispatching(WindowState win, int action, int flags,
- int keyCode, int metaState, int repeatCount, int policyFlags) {
+ int keyCode, int scanCode, int metaState, int repeatCount, int policyFlags) {
final boolean keyguardOn = keyguardOn();
final boolean down = (action == KeyEvent.ACTION_DOWN);
final boolean canceled = ((flags & KeyEvent.FLAG_CANCELED) != 0);
@@ -1094,11 +1124,9 @@
// and his ONLY options are to answer or reject the call.)
boolean incomingRinging = false;
try {
- ITelephony phoneServ = getPhoneInterface();
- if (phoneServ != null) {
- incomingRinging = phoneServ.isRinging();
- } else {
- Log.w(TAG, "Unable to find ITelephony interface");
+ ITelephony telephonyService = getTelephonyService();
+ if (telephonyService != null) {
+ incomingRinging = telephonyService.isRinging();
}
} catch (RemoteException ex) {
Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
@@ -1667,23 +1695,6 @@
}
/**
- * @return Whether a telephone call is in progress right now.
- */
- boolean isInCall() {
- final ITelephony phone = getPhoneInterface();
- if (phone == null) {
- Log.w(TAG, "couldn't get ITelephony reference");
- return false;
- }
- try {
- return phone.isOffhook();
- } catch (RemoteException e) {
- Log.w(TAG, "ITelephony.isOffhhook threw RemoteException " + e);
- return false;
- }
- }
-
- /**
* @return Whether music is being played right now.
*/
boolean isMusicActive() {
@@ -1700,9 +1711,8 @@
* @param keycode
*/
void handleVolumeKey(int stream, int keycode) {
- final IAudioService audio = getAudioInterface();
- if (audio == null) {
- Log.w(TAG, "handleVolumeKey: couldn't get IAudioService reference");
+ IAudioService audioService = getAudioService();
+ if (audioService == null) {
return;
}
try {
@@ -1710,7 +1720,7 @@
// during the call, but we do it as a precaution for the rare possibility
// that the music stops right before we call this
mBroadcastWakeLock.acquire();
- audio.adjustStreamVolume(stream,
+ audioService.adjustStreamVolume(stream,
keycode == KeyEvent.KEYCODE_VOLUME_UP
? AudioManager.ADJUST_RAISE
: AudioManager.ADJUST_LOWER,
@@ -1721,39 +1731,15 @@
mBroadcastWakeLock.release();
}
}
-
- static boolean isMediaKey(int code) {
- if (code == KeyEvent.KEYCODE_HEADSETHOOK ||
- code == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE ||
- code == KeyEvent.KEYCODE_MEDIA_STOP ||
- code == KeyEvent.KEYCODE_MEDIA_NEXT ||
- code == KeyEvent.KEYCODE_MEDIA_PREVIOUS ||
- code == KeyEvent.KEYCODE_MEDIA_REWIND ||
- code == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) {
- return true;
- }
- return false;
- }
/** {@inheritDoc} */
@Override
- public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
- int policyFlags, boolean isScreenOn) {
- int result = ACTION_PASS_TO_USER;
+ public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
+ int keyCode, int scanCode, int policyFlags, boolean isScreenOn) {
+ final boolean down = action == KeyEvent.ACTION_DOWN;
+ final boolean canceled = (flags & KeyEvent.FLAG_CANCELED) != 0;
- if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
- performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
- }
-
- final boolean isWakeKey = (policyFlags
- & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
-
- // If the key is injected, pretend that the screen is on and don't let the
- // device go to sleep. This feature is mainly used for testing purposes.
final boolean isInjected = (policyFlags & WindowManagerPolicy.FLAG_INJECTED) != 0;
- if (isInjected) {
- isScreenOn = true;
- }
// If screen is off then we treat the case where the keyguard is open but hidden
// the same as if it were open and in front.
@@ -1768,202 +1754,192 @@
+ " screenIsOn=" + isScreenOn + " keyguardActive=" + keyguardActive);
}
- if (keyguardActive) {
- if (isScreenOn) {
- // when the screen is on, always give the event to the keyguard
- result |= ACTION_PASS_TO_USER;
- } else {
- // otherwise, don't pass it to the user
- result &= ~ACTION_PASS_TO_USER;
+ if (down && (policyFlags & WindowManagerPolicy.FLAG_VIRTUAL) != 0) {
+ performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
+ }
- if (isWakeKey && down) {
+ // Basic policy based on screen state and keyguard.
+ // FIXME: This policy isn't quite correct. We shouldn't care whether the screen
+ // is on or off, really. We should care about whether the device is in an
+ // interactive state or is in suspend pretending to be "off".
+ // The primary screen might be turned off due to proximity sensor or
+ // because we are presenting media on an auxiliary screen or remotely controlling
+ // the device some other way (which is why we have an exemption here for injected
+ // events).
+ int result;
+ if (isScreenOn || isInjected) {
+ // When the screen is on or if the key is injected pass the key to the application.
+ result = ACTION_PASS_TO_USER;
+ } else {
+ // When the screen is off and the key is not injected, determine whether
+ // to wake the device but don't pass the key to the application.
+ result = 0;
- // tell the mediator about a wake key, it may decide to
- // turn on the screen depending on whether the key is
- // appropriate.
- if (!mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode)
- && (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
- || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
- // when keyguard is showing and screen off, we need
- // to handle the volume key for calls and music here
- if (isInCall()) {
- handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
- } else if (isMusicActive()) {
- handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode);
- }
- }
+ final boolean isWakeKey = (policyFlags
+ & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
+ if (down && isWakeKey) {
+ if (keyguardActive) {
+ // If the keyguard is showing, let it decide what to do with the wake key.
+ mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode);
+ } else {
+ // Otherwise, wake the device ourselves.
+ result |= ACTION_POKE_USER_ACTIVITY;
}
}
- } else if (!isScreenOn) {
- // If we are in-call with screen off and keyguard is not showing,
- // then handle the volume key ourselves.
- // This is necessary because the phone app will disable the keyguard
- // when the proximity sensor is in use.
- if (isInCall() &&
- (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
- || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) {
- result &= ~ACTION_PASS_TO_USER;
- handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
- }
- if (isWakeKey) {
- // a wake key has a sole purpose of waking the device; don't pass
- // it to the user
- result |= ACTION_POKE_USER_ACTIVITY;
- result &= ~ACTION_PASS_TO_USER;
- }
}
- if (keyCode == KeyEvent.KEYCODE_ENDCALL
- || keyCode == KeyEvent.KEYCODE_POWER) {
- if (down) {
- boolean handled = false;
- boolean hungUp = false;
- // key repeats are generated by the window manager, and we don't see them
- // here, so unless the driver is doing something it shouldn't be, we know
- // this is the real press event.
- ITelephony phoneServ = getPhoneInterface();
- if (phoneServ != null) {
- try {
- if (keyCode == KeyEvent.KEYCODE_ENDCALL) {
- handled = hungUp = phoneServ.endCall();
- } else if (keyCode == KeyEvent.KEYCODE_POWER) {
- if (phoneServ.isRinging()) {
- // Pressing Power while there's a ringing incoming
- // call should silence the ringer.
- phoneServ.silenceRinger();
- handled = true;
- } else if (phoneServ.isOffhook() &&
- ((mIncallPowerBehavior
- & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP)
- != 0)) {
- // Otherwise, if "Power button ends call" is enabled,
- // the Power button will hang up any current active call.
- handled = hungUp = phoneServ.endCall();
+ // Handle special keys.
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_UP: {
+ if (down) {
+ ITelephony telephonyService = getTelephonyService();
+ if (telephonyService != null) {
+ try {
+ if (telephonyService.isRinging()) {
+ // If an incoming call is ringing, either VOLUME key means
+ // "silence ringer". We handle these keys here, rather than
+ // in the InCallScreen, to make sure we'll respond to them
+ // even if the InCallScreen hasn't come to the foreground yet.
+ // Look for the DOWN event here, to agree with the "fallback"
+ // behavior in the InCallScreen.
+ Log.i(TAG, "interceptKeyBeforeQueueing:"
+ + " VOLUME key-down while ringing: Silence ringer!");
+
+ // Silence the ringer. (It's safe to call this
+ // even if the ringer has already been silenced.)
+ telephonyService.silenceRinger();
+
+ // And *don't* pass this key thru to the current activity
+ // (which is probably the InCallScreen.)
+ result &= ~ACTION_PASS_TO_USER;
+ break;
+ }
+ if (telephonyService.isOffhook()
+ && (result & ACTION_PASS_TO_USER) == 0) {
+ // If we are in call but we decided not to pass the key to
+ // the application, handle the volume change here.
+ handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
+ break;
+ }
+ } catch (RemoteException ex) {
+ Log.w(TAG, "ITelephony threw RemoteException", ex);
+ }
+ }
+
+ if (isMusicActive() && (result & ACTION_PASS_TO_USER) == 0) {
+ // If music is playing but we decided not to pass the key to the
+ // application, handle the volume change here.
+ handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode);
+ break;
+ }
+ }
+ break;
+ }
+
+ case KeyEvent.KEYCODE_ENDCALL: {
+ result &= ~ACTION_PASS_TO_USER;
+ if (down) {
+ ITelephony telephonyService = getTelephonyService();
+ boolean hungUp = false;
+ if (telephonyService != null) {
+ try {
+ hungUp = telephonyService.endCall();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "ITelephony threw RemoteException", ex);
+ }
+ }
+ interceptPowerKeyDown(!isScreenOn || hungUp);
+ } else {
+ if (interceptPowerKeyUp(canceled)) {
+ if ((mEndcallBehavior
+ & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) {
+ if (goHome()) {
+ break;
}
}
- } catch (RemoteException ex) {
- Log.w(TAG, "ITelephony threw RemoteException" + ex);
+ if ((mEndcallBehavior
+ & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) {
+ result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
+ }
}
+ }
+ break;
+ }
+
+ case KeyEvent.KEYCODE_POWER: {
+ result &= ~ACTION_PASS_TO_USER;
+ if (down) {
+ ITelephony telephonyService = getTelephonyService();
+ boolean hungUp = false;
+ if (telephonyService != null) {
+ try {
+ if (telephonyService.isRinging()) {
+ // Pressing Power while there's a ringing incoming
+ // call should silence the ringer.
+ telephonyService.silenceRinger();
+ } else if ((mIncallPowerBehavior
+ & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
+ && telephonyService.isOffhook()) {
+ // Otherwise, if "Power button ends call" is enabled,
+ // the Power button will hang up any current active call.
+ hungUp = telephonyService.endCall();
+ }
+ } catch (RemoteException ex) {
+ Log.w(TAG, "ITelephony threw RemoteException", ex);
+ }
+ }
+ interceptPowerKeyDown(!isScreenOn || hungUp);
} else {
- Log.w(TAG, "!!! Unable to find ITelephony interface !!!");
- }
-
- if (!isScreenOn
- || (handled && keyCode != KeyEvent.KEYCODE_POWER)
- || (handled && hungUp && keyCode == KeyEvent.KEYCODE_POWER)) {
- mShouldTurnOffOnKeyUp = false;
- } else {
- // Only try to turn off the screen if we didn't already hang up.
- mShouldTurnOffOnKeyUp = true;
- mHandler.postDelayed(mPowerLongPress,
- ViewConfiguration.getGlobalActionKeyTimeout());
- result &= ~ACTION_PASS_TO_USER;
- }
- } else {
- mHandler.removeCallbacks(mPowerLongPress);
- if (mShouldTurnOffOnKeyUp) {
- mShouldTurnOffOnKeyUp = false;
- boolean gohome, sleeps;
- if (keyCode == KeyEvent.KEYCODE_ENDCALL) {
- gohome = (mEndcallBehavior
- & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0;
- sleeps = (mEndcallBehavior
- & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0;
- } else {
- gohome = false;
- sleeps = true;
+ if (interceptPowerKeyUp(canceled)) {
+ result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
}
- if (keyguardActive
- || (sleeps && !gohome)
- || (gohome && !goHome() && sleeps)) {
- // They must already be on the keyguard or home screen,
- // go to sleep instead unless the event was injected.
- if (!isInjected) {
- Log.d(TAG, "I'm tired mEndcallBehavior=0x"
- + Integer.toHexString(mEndcallBehavior));
- result &= ~ACTION_POKE_USER_ACTIVITY;
- result |= ACTION_GO_TO_SLEEP;
+ }
+ break;
+ }
+
+ case KeyEvent.KEYCODE_HEADSETHOOK:
+ case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+ case KeyEvent.KEYCODE_MEDIA_STOP:
+ case KeyEvent.KEYCODE_MEDIA_NEXT:
+ case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+ case KeyEvent.KEYCODE_MEDIA_REWIND:
+ case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
+ if ((result & ACTION_PASS_TO_USER) == 0) {
+ // Only do this if we would otherwise not pass it to the user. In that
+ // case, the PhoneWindow class will do the same thing, except it will
+ // only do it if the showing app doesn't process the key on its own.
+ long when = whenNanos / 1000000;
+ KeyEvent keyEvent = new KeyEvent(when, when, action, keyCode, 0, 0,
+ 0, scanCode, flags, InputDevice.SOURCE_KEYBOARD);
+ mBroadcastWakeLock.acquire();
+ mHandler.post(new PassHeadsetKey(keyEvent));
+ }
+ break;
+ }
+
+ case KeyEvent.KEYCODE_CALL: {
+ if (down) {
+ ITelephony telephonyService = getTelephonyService();
+ if (telephonyService != null) {
+ try {
+ if (telephonyService.isRinging()) {
+ Log.i(TAG, "interceptKeyBeforeQueueing:"
+ + " CALL key-down while ringing: Answer the call!");
+ telephonyService.answerRingingCall();
+
+ // And *don't* pass this key thru to the current activity
+ // (which is presumably the InCallScreen.)
+ result &= ~ACTION_PASS_TO_USER;
+ }
+ } catch (RemoteException ex) {
+ Log.w(TAG, "ITelephony threw RemoteException", ex);
}
}
- result &= ~ACTION_PASS_TO_USER;
}
- }
- } else if (isMediaKey(keyCode)) {
- // This key needs to be handled even if the screen is off.
- // If others need to be handled while it's off, this is a reasonable
- // pattern to follow.
- if ((result & ACTION_PASS_TO_USER) == 0) {
- // Only do this if we would otherwise not pass it to the user. In that
- // case, the PhoneWindow class will do the same thing, except it will
- // only do it if the showing app doesn't process the key on its own.
- long when = whenNanos / 1000000;
- KeyEvent keyEvent = new KeyEvent(when, when,
- down ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP,
- keyCode, 0);
- mBroadcastWakeLock.acquire();
- mHandler.post(new PassHeadsetKey(keyEvent));
- }
- } else if (keyCode == KeyEvent.KEYCODE_CALL) {
- // If an incoming call is ringing, answer it!
- // (We handle this key here, rather than in the InCallScreen, to make
- // sure we'll respond to the key even if the InCallScreen hasn't come to
- // the foreground yet.)
-
- // We answer the call on the DOWN event, to agree with
- // the "fallback" behavior in the InCallScreen.
- if (down) {
- try {
- ITelephony phoneServ = getPhoneInterface();
- if (phoneServ != null) {
- if (phoneServ.isRinging()) {
- Log.i(TAG, "interceptKeyTq:"
- + " CALL key-down while ringing: Answer the call!");
- phoneServ.answerRingingCall();
-
- // And *don't* pass this key thru to the current activity
- // (which is presumably the InCallScreen.)
- result &= ~ACTION_PASS_TO_USER;
- }
- } else {
- Log.w(TAG, "CALL button: Unable to find ITelephony interface");
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "CALL button: RemoteException from getPhoneInterface()", ex);
- }
- }
- } else if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP)
- || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) {
- // If an incoming call is ringing, either VOLUME key means
- // "silence ringer". We handle these keys here, rather than
- // in the InCallScreen, to make sure we'll respond to them
- // even if the InCallScreen hasn't come to the foreground yet.
-
- // Look for the DOWN event here, to agree with the "fallback"
- // behavior in the InCallScreen.
- if (down) {
- try {
- ITelephony phoneServ = getPhoneInterface();
- if (phoneServ != null) {
- if (phoneServ.isRinging()) {
- Log.i(TAG, "interceptKeyTq:"
- + " VOLUME key-down while ringing: Silence ringer!");
- // Silence the ringer. (It's safe to call this
- // even if the ringer has already been silenced.)
- phoneServ.silenceRinger();
-
- // And *don't* pass this key thru to the current activity
- // (which is probably the InCallScreen.)
- result &= ~ACTION_PASS_TO_USER;
- }
- } else {
- Log.w(TAG, "VOLUME button: Unable to find ITelephony interface");
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex);
- }
+ break;
}
}
-
return result;
}
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index df41264..b44fe00 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -379,17 +379,18 @@
}
@SuppressWarnings("unused")
- public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
- int policyFlags, boolean isScreenOn) {
+ public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
+ int keyCode, int scanCode, int policyFlags, boolean isScreenOn) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeQueueing(
- whenNanos, keyCode, down, policyFlags, isScreenOn);
+ whenNanos, action, flags, keyCode, scanCode, policyFlags, isScreenOn);
}
@SuppressWarnings("unused")
public boolean interceptKeyBeforeDispatching(InputChannel focus, int action,
- int flags, int keyCode, int metaState, int repeatCount, int policyFlags) {
+ int flags, int keyCode, int scanCode, int metaState, int repeatCount,
+ int policyFlags) {
return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching(focus,
- action, flags, keyCode, metaState, repeatCount, policyFlags);
+ action, flags, keyCode, scanCode, metaState, repeatCount, policyFlags);
}
@SuppressWarnings("unused")
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 1b2ddcc..f28bae0 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -5250,20 +5250,20 @@
/* Provides an opportunity for the window manager policy to intercept early key
* processing as soon as the key has been read from the device. */
- public int interceptKeyBeforeQueueing(long whenNanos, int keyCode, boolean down,
- int policyFlags, boolean isScreenOn) {
- return mPolicy.interceptKeyBeforeQueueing(whenNanos,
- keyCode, down, policyFlags, isScreenOn);
+ public int interceptKeyBeforeQueueing(long whenNanos, int action, int flags,
+ int keyCode, int scanCode, int policyFlags, boolean isScreenOn) {
+ return mPolicy.interceptKeyBeforeQueueing(whenNanos, action, flags,
+ keyCode, scanCode, policyFlags, isScreenOn);
}
/* Provides an opportunity for the window manager policy to process a key before
* ordinary dispatch. */
public boolean interceptKeyBeforeDispatching(InputChannel focus,
- int action, int flags, int keyCode, int metaState, int repeatCount,
+ int action, int flags, int keyCode, int scanCode, int metaState, int repeatCount,
int policyFlags) {
WindowState windowState = getWindowStateForInputChannel(focus);
return mPolicy.interceptKeyBeforeDispatching(windowState, action, flags,
- keyCode, metaState, repeatCount, policyFlags);
+ keyCode, scanCode, metaState, repeatCount, policyFlags);
}
/* Called when the current input focus changes.
@@ -6003,6 +6003,11 @@
// Input channel
InputChannel mInputChannel;
+ // Used to improve performance of toString()
+ String mStringNameCache;
+ CharSequence mLastTitle;
+ boolean mWasPaused;
+
WindowState(Session s, IWindow c, WindowToken token,
WindowState attachedWindow, WindowManager.LayoutParams a,
int viewVisibility) {
@@ -7260,9 +7265,14 @@
@Override
public String toString() {
- return "Window{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
+ if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
+ || mWasPaused != mToken.paused) {
+ mLastTitle = mAttrs.getTitle();
+ mWasPaused = mToken.paused;
+ mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
+ + " " + mLastTitle + " paused=" + mWasPaused + "}";
+ }
+ return mStringNameCache;
}
}
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 1bd1874..693d630 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -857,7 +857,7 @@
JNIEnv* env = jniEnv();
jint wmActions = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing,
- when, keyCode, action == AKEY_EVENT_ACTION_DOWN, policyFlags, isScreenOn);
+ when, action, flags, keyCode, scanCode, policyFlags, isScreenOn);
if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
wmActions = 0;
}
@@ -926,7 +926,7 @@
jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeDispatching,
inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
- keyEvent->getKeyCode(), keyEvent->getMetaState(),
+ keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
keyEvent->getRepeatCount(), policyFlags);
bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
@@ -1337,10 +1337,10 @@
"notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
- "interceptKeyBeforeQueueing", "(JIZIZ)I");
+ "interceptKeyBeforeQueueing", "(JIIIIIZ)I");
GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
- "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIII)Z");
+ "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIIII)Z");
GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
"checkInjectEventsPermission", "(II)Z");
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 2328717..53f4eb7 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -66,7 +66,7 @@
boolean showCallScreenWithDialpad(boolean showDialpad);
/**
- * End call or go to the Home screen
+ * End call if there is a call in progress, otherwise does nothing.
*
* @return whether it hung up
*/