diff options
33 files changed, 422 insertions, 245 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 2be515376453..45a42e44f1cd 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -57,8 +57,8 @@ import java.util.Set; * * <p>An Intent provides a facility for performing late runtime binding between the code in * different applications. Its most significant use is in the launching of activities, where it - * can be thought of as the glue between activities. It is basically a passive data structure - * holding an abstract description of an action to be performed.</p> + * can be thought of as the glue between activities. It is basically a passive data structure + * holding an abstract description of an action to be performed.</p> * * <div class="special reference"> * <h3>Developer Guides</h3> @@ -2566,7 +2566,7 @@ public class Intent implements Parcelable, Cloneable { */ public static final String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY"; - + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Intent flags (see mFlags variable). @@ -5291,7 +5291,7 @@ public class Intent implements Parcelable, Cloneable { if (r != null) { mSourceBounds = new Rect(r); } else { - r = null; + mSourceBounds = null; } } diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 3bd0f76dfc3b..ad2283ea9285 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -117,6 +117,11 @@ public class Display { outSize.x = getRawWidth(); outSize.y = getRawHeight(); } + if (false) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.v(TAG, "Returning display size: " + outSize, here); + } if (DEBUG_DISPLAY_SIZE && doCompat) Slog.v( TAG, "Returning display size: " + outSize); } catch (RemoteException e) { diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index bfd29595b2dc..17bdff2c9628 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -104,23 +104,23 @@ public interface WindowManagerPolicy { */ public final static String EXTRA_HDMI_PLUGGED_STATE = "state"; - // flags for interceptKeyTq /** - * Pass this event to the user / app. To be returned from {@link #interceptKeyTq}. + * Pass this event to the user / app. To be returned from + * {@link #interceptKeyBeforeQueueing}. */ public final static int ACTION_PASS_TO_USER = 0x00000001; /** * This key event should extend the user activity timeout and turn the lights on. - * To be returned from {@link #interceptKeyTq}. Do not return this and - * {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}. + * To be returned from {@link #interceptKeyBeforeQueueing}. + * Do not return this and {@link #ACTION_GO_TO_SLEEP} or {@link #ACTION_PASS_TO_USER}. */ public final static int ACTION_POKE_USER_ACTIVITY = 0x00000002; /** * This key event should put the device to sleep (and engage keyguard if necessary) - * To be returned from {@link #interceptKeyTq}. Do not return this and - * {@link #ACTION_POKE_USER_ACTIVITY} or {@link #ACTION_PASS_TO_USER}. + * To be returned from {@link #interceptKeyBeforeQueueing}. + * Do not return this and {@link #ACTION_POKE_USER_ACTIVITY} or {@link #ACTION_PASS_TO_USER}. */ public final static int ACTION_GO_TO_SLEEP = 0x00000004; @@ -677,10 +677,12 @@ public interface WindowManagerPolicy { * event will normally go. * @param event The key event. * @param policyFlags The policy flags associated with the key. - * @return Returns true if the policy consumed the event and it should - * not be further dispatched. + * @return 0 if the key should be dispatched immediately, -1 if the key should + * not be dispatched ever, or a positive value indicating the number of + * milliseconds by which the key dispatch should be delayed before trying + * again. */ - public boolean interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags); + public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags); /** * Called from the input dispatcher thread when an application did not handle diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java index 5b49bffd8f02..a2fc6e2efdcd 100644 --- a/core/java/com/android/internal/widget/LockPatternView.java +++ b/core/java/com/android/internal/widget/LockPatternView.java @@ -32,9 +32,9 @@ import android.os.Debug; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; -import android.os.Vibrator; import android.util.AttributeSet; import android.util.Log; +import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; @@ -59,9 +59,6 @@ public class LockPatternView extends View { private static final int ASPECT_LOCK_WIDTH = 1; // Fixed width; height will be minimum of (w,h) private static final int ASPECT_LOCK_HEIGHT = 2; // Fixed height; width will be minimum of (w,h) - // Vibrator pattern for creating a tactile bump - private static final long[] DEFAULT_VIBE_PATTERN = {0, 1, 40, 41}; - private static final boolean PROFILE_DRAWING = false; private boolean mDrawingProfilingStarted = false; @@ -102,7 +99,7 @@ public class LockPatternView extends View { private DisplayMode mPatternDisplayMode = DisplayMode.Correct; private boolean mInputEnabled = true; private boolean mInStealthMode = false; - private boolean mTactileFeedbackEnabled = true; + private boolean mEnableHapticFeedback = true; private boolean mPatternInProgress = false; private float mDiameterFactor = 0.10f; // TODO: move to attrs @@ -127,11 +124,6 @@ public class LockPatternView extends View { private int mBitmapWidth; private int mBitmapHeight; - - private Vibrator vibe; // Vibrator for creating tactile feedback - - private long[] mVibePattern; - private int mAspect; private final Matrix mArrowMatrix = new Matrix(); private final Matrix mCircleMatrix = new Matrix(); @@ -250,7 +242,6 @@ public class LockPatternView extends View { public LockPatternView(Context context, AttributeSet attrs) { super(context, attrs); - vibe = new Vibrator(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.LockPatternView); @@ -295,26 +286,6 @@ public class LockPatternView extends View { mBitmapHeight = Math.max(mBitmapHeight, bitmap.getHeight()); } - // allow vibration pattern to be customized - mVibePattern = loadVibratePattern(com.android.internal.R.array.config_virtualKeyVibePattern); - } - - private long[] loadVibratePattern(int id) { - int[] pattern = null; - try { - pattern = getResources().getIntArray(id); - } catch (Resources.NotFoundException e) { - Log.e(TAG, "Vibrate pattern missing, using default", e); - } - if (pattern == null) { - return DEFAULT_VIBE_PATTERN; - } - - long[] tmpPattern = new long[pattern.length]; - for (int i = 0; i < pattern.length; i++) { - tmpPattern[i] = pattern[i]; - } - return tmpPattern; } private Bitmap getBitmapFor(int resId) { @@ -332,7 +303,7 @@ public class LockPatternView extends View { * @return Whether the view has tactile feedback enabled. */ public boolean isTactileFeedbackEnabled() { - return mTactileFeedbackEnabled; + return mEnableHapticFeedback; } /** @@ -352,7 +323,7 @@ public class LockPatternView extends View { * @param tactileFeedbackEnabled Whether tactile feedback is enabled */ public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) { - mTactileFeedbackEnabled = tactileFeedbackEnabled; + mEnableHapticFeedback = tactileFeedbackEnabled; } /** @@ -573,8 +544,10 @@ public class LockPatternView extends View { addCellToPattern(fillInGapCell); } addCellToPattern(cell); - if (mTactileFeedbackEnabled){ - vibe.vibrate(mVibePattern, -1); // Generate tactile feedback + if (mEnableHapticFeedback) { + performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, + HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING + | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); } return cell; } @@ -1114,7 +1087,7 @@ public class LockPatternView extends View { return new SavedState(superState, LockPatternUtils.patternToString(mPattern), mPatternDisplayMode.ordinal(), - mInputEnabled, mInStealthMode, mTactileFeedbackEnabled); + mInputEnabled, mInStealthMode, mEnableHapticFeedback); } @Override @@ -1127,7 +1100,7 @@ public class LockPatternView extends View { mPatternDisplayMode = DisplayMode.values()[ss.getDisplayMode()]; mInputEnabled = ss.isInputEnabled(); mInStealthMode = ss.isInStealthMode(); - mTactileFeedbackEnabled = ss.isTactileFeedbackEnabled(); + mEnableHapticFeedback = ss.isTactileFeedbackEnabled(); } /** diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java index 01df48acd144..2e7810fa1139 100644 --- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java +++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java @@ -26,6 +26,7 @@ import android.os.SystemClock; import android.os.Vibrator; import android.provider.Settings; import android.util.Log; +import android.view.HapticFeedbackConstants; import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.View; @@ -52,7 +53,7 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { private final View mTargetView; private final KeyboardView mKeyboardView; private long[] mVibratePattern; - private final Vibrator mVibrator; + private boolean mEnableHaptics = false; public PasswordEntryKeyboardHelper(Context context, KeyboardView keyboardView, View targetView) { this(context, keyboardView, targetView, true); @@ -71,7 +72,10 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { mKeyboardView.getLayoutParams().height); } mKeyboardView.setOnKeyboardActionListener(this); - mVibrator = new Vibrator(); + } + + public void setEnableHaptics(boolean enabled) { + mEnableHaptics = enabled; } public boolean isAlpha() { @@ -230,6 +234,7 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { public void handleBackspace() { sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); + performHapticFeedback(); } private void handleShift() { @@ -272,8 +277,14 @@ public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener { } public void onPress(int primaryCode) { - if (mVibratePattern != null) { - mVibrator.vibrate(mVibratePattern, -1); + performHapticFeedback(); + } + + private void performHapticFeedback() { + if (mEnableHaptics) { + mKeyboardView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, + HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING + | HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); } } diff --git a/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png b/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png Binary files differindex 9e1c42a675ba..f8092ea3d40c 100755..100644 --- a/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png +++ b/core/res/res/drawable-hdpi/list_selector_background_disabled.9.png diff --git a/core/res/res/drawable-hdpi/list_selector_background_focus.9.png b/core/res/res/drawable-hdpi/list_selector_background_focus.9.png Binary files differindex 5563c80d1e98..3a21d356fb65 100755..100644 --- a/core/res/res/drawable-hdpi/list_selector_background_focus.9.png +++ b/core/res/res/drawable-hdpi/list_selector_background_focus.9.png diff --git a/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png b/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png Binary files differindex 72d3a08484f9..19558e93c8bd 100755..100644 --- a/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png +++ b/core/res/res/drawable-hdpi/list_selector_background_longpress.9.png diff --git a/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png b/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png Binary files differindex 7568b30c22e2..0f3b4443c530 100755..100644 --- a/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png +++ b/core/res/res/drawable-hdpi/list_selector_background_pressed.9.png diff --git a/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png b/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png Binary files differindex 43c36cb9e1d2..dbe395377615 100644 --- a/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png +++ b/core/res/res/drawable-mdpi/list_selector_background_disabled.9.png diff --git a/core/res/res/drawable-mdpi/list_selector_background_focus.9.png b/core/res/res/drawable-mdpi/list_selector_background_focus.9.png Binary files differindex 53a7eaccbee3..da625af3b817 100644 --- a/core/res/res/drawable-mdpi/list_selector_background_focus.9.png +++ b/core/res/res/drawable-mdpi/list_selector_background_focus.9.png diff --git a/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png b/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png Binary files differindex 0818761cb2c8..fbf7ef031a90 100644 --- a/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png +++ b/core/res/res/drawable-mdpi/list_selector_background_longpress.9.png diff --git a/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png b/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png Binary files differindex 8bd86b2b81b3..dd2a02477db7 100644 --- a/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png +++ b/core/res/res/drawable-mdpi/list_selector_background_pressed.9.png diff --git a/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png b/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png Binary files differindex d599976c634c..980bbd73775c 100644 --- a/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png +++ b/core/res/res/drawable-xhdpi/list_selector_background_disabled.9.png diff --git a/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png b/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png Binary files differindex 17987f39a093..79c457756aad 100644 --- a/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png +++ b/core/res/res/drawable-xhdpi/list_selector_background_focus.9.png diff --git a/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png b/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png Binary files differindex 5a64592d3784..73fc7839d559 100644 --- a/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png +++ b/core/res/res/drawable-xhdpi/list_selector_background_longpress.9.png diff --git a/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png b/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png Binary files differindex 1593577a406c..5b3ebe1b940b 100644 --- a/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png +++ b/core/res/res/drawable-xhdpi/list_selector_background_pressed.9.png diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 2f50ce7ccb08..f3540e272e96 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -233,23 +233,32 @@ </ul> <ul> - <li class="toggle-list"> + <li class="toggle-list"> <div><a href="<?cs var:toroot ?>guide/topics/graphics/index.html"> <span class="en">Graphics</span> - </a></div> + </a><span class="new-child">new!</span></div> <ul> <li><a href="<?cs var:toroot ?>guide/topics/graphics/2d-graphics.html"> - <span class="en">2D Graphics</span> - </a></li> + <span class="en">Canvas and Drawables</span></a></li> + <li><a href="<?cs var:toroot ?>guide/topics/graphics/hardware-accel.html"> + <span class="en">Hardware Acceleration</span></a> + <span class="new">new!</span></li> <li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html"> - <span class="en">3D with OpenGL</span> - </a></li> - <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html"> - <span class="en">Property Animation</span> - </a></li> + <span class="en">OpenGL</span> + </a><span class="new">updated</span></li> + </ul> + </li> + <li class="toggle-list"> + <div><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html"> + <span class="en">Animation</span> + </a></div> + <ul> + <li><a href="<?cs var:toroot ?>guide/topics/graphics/prop-animation.html"> + <span class="en">Property Animation</span></a></li> <li><a href="<?cs var:toroot ?>guide/topics/graphics/view-animation.html"> - <span class="en">View Animation</span> - </a></li> + <span class="en">View Animation</span></a></li> + <li><a href="<?cs var:toroot ?>guide/topics/graphics/drawable-animation.html"> + <span class="en">Drawable Animation</span></a></li> </ul> </li> <li class="toggle-list"> @@ -258,7 +267,7 @@ </a></div> <ul> <li><a href="<?cs var:toroot ?>guide/topics/renderscript/graphics.html"> - <span class="en">3D Graphics</span> + <span class="en">Graphics</span> </a> </li> <li><a href="<?cs var:toroot ?>guide/topics/renderscript/compute.html"> diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java index ec0072c3c210..3ad716b7117d 100644 --- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java +++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java @@ -28,6 +28,7 @@ import com.android.internal.widget.PasswordEntryKeyboardView; import android.os.CountDownTimer; import android.os.SystemClock; +import android.provider.Settings; import android.security.KeyStore; import android.text.Editable; import android.text.InputType; @@ -109,6 +110,10 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen mPasswordEntry.setOnEditorActionListener(this); mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false); + mKeyboardHelper.setEnableHaptics( + Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 0) + != 0); if (mIsAlpha) { // We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); @@ -150,9 +155,6 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen //KeyguardStatusViewManager.LOCK_ICON); } - mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ? - com.android.internal.R.array.config_virtualKeyVibePattern : 0); - // Poke the wakelock any time the text is selected or modified mPasswordEntry.setOnClickListener(new OnClickListener() { public void onClick(View v) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 487063d2907b..3eb04cb304a1 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -267,7 +267,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mKeyguard = null; KeyguardViewMediator mKeyguardMediator; GlobalActions mGlobalActions; - volatile boolean mPowerKeyHandled; + volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread + boolean mPendingPowerKeyUpCanceled; RecentApplicationsDialog mRecentAppsDialog; Handler mHandler; @@ -403,8 +404,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { private int mLongPressOnHomeBehavior = -1; // Screenshot trigger states - private boolean mVolumeDownTriggered; - private boolean mPowerDownTriggered; + // Time to volume and power must be pressed within this interval of each other. + private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150; + private boolean mVolumeDownKeyTriggered; + private long mVolumeDownKeyTime; + private boolean mVolumeDownKeyConsumedByScreenshotChord; + private boolean mVolumeUpKeyTriggered; + private boolean mPowerKeyTriggered; + private long mPowerKeyTime; ShortcutManager mShortcutManager; PowerManager.WakeLock mBroadcastWakeLock; @@ -552,40 +559,67 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (!mPowerKeyHandled) { mHandler.removeCallbacks(mPowerLongPress); return !canceled; - } else { - mPowerKeyHandled = true; - return false; + } + return false; + } + + private void cancelPendingPowerKeyAction() { + if (!mPowerKeyHandled) { + mHandler.removeCallbacks(mPowerLongPress); + } + mPendingPowerKeyUpCanceled = true; + } + + private void interceptScreenshotChord() { + if (mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) { + final long now = SystemClock.uptimeMillis(); + if (now <= mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS + && now <= mPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) { + mVolumeDownKeyConsumedByScreenshotChord = true; + cancelPendingPowerKeyAction(); + + mHandler.postDelayed(mScreenshotChordLongPress, + ViewConfiguration.getGlobalActionKeyTimeout()); + } } } + private void cancelPendingScreenshotChordAction() { + mHandler.removeCallbacks(mScreenshotChordLongPress); + } + private final Runnable mPowerLongPress = new Runnable() { public void run() { - if (!mPowerKeyHandled) { - // The context isn't read - if (mLongPressOnPowerBehavior < 0) { - mLongPressOnPowerBehavior = mContext.getResources().getInteger( - com.android.internal.R.integer.config_longPressOnPowerBehavior); - } - switch (mLongPressOnPowerBehavior) { - case LONG_PRESS_POWER_NOTHING: - break; - case LONG_PRESS_POWER_GLOBAL_ACTIONS: - mPowerKeyHandled = true; - performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); - showGlobalActionsDialog(); - break; - case LONG_PRESS_POWER_SHUT_OFF: - mPowerKeyHandled = true; - performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); - ShutdownThread.shutdown(mContext, true); - break; - } + // The context isn't read + if (mLongPressOnPowerBehavior < 0) { + mLongPressOnPowerBehavior = mContext.getResources().getInteger( + com.android.internal.R.integer.config_longPressOnPowerBehavior); + } + switch (mLongPressOnPowerBehavior) { + case LONG_PRESS_POWER_NOTHING: + break; + case LONG_PRESS_POWER_GLOBAL_ACTIONS: + mPowerKeyHandled = true; + performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); + sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); + showGlobalActionsDialog(); + break; + case LONG_PRESS_POWER_SHUT_OFF: + mPowerKeyHandled = true; + performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); + sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); + ShutdownThread.shutdown(mContext, true); + break; } } }; + private final Runnable mScreenshotChordLongPress = new Runnable() { + public void run() { + takeScreenshot(); + } + }; + void showGlobalActionsDialog() { if (mGlobalActions == null) { mGlobalActions = new GlobalActions(mContext); @@ -1381,11 +1415,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ @Override - public boolean interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) { + public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) { final boolean keyguardOn = keyguardOn(); final int keyCode = event.getKeyCode(); final int repeatCount = event.getRepeatCount(); final int metaState = event.getMetaState(); + final int flags = event.getFlags(); final boolean down = event.getAction() == KeyEvent.ACTION_DOWN; final boolean canceled = event.isCanceled(); @@ -1394,6 +1429,26 @@ public class PhoneWindowManager implements WindowManagerPolicy { + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed); } + // If we think we might have a volume down & power key chord on the way + // but we're not sure, then tell the dispatcher to wait a little while and + // try again later before dispatching. + if ((flags & KeyEvent.FLAG_FALLBACK) == 0) { + if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) { + final long now = SystemClock.uptimeMillis(); + final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS; + if (now < timeoutTime) { + return timeoutTime - now; + } + } + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN + && mVolumeDownKeyConsumedByScreenshotChord) { + if (!down) { + mVolumeDownKeyConsumedByScreenshotChord = false; + } + return -1; + } + } + // First we always handle the home key here, so applications // can never break it, although if keyguard is on, we do let // it handle it, because that gives us the correct 5 second @@ -1425,7 +1480,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } else { Log.i(TAG, "Ignoring HOME; event canceled."); } - return true; + return -1; } // If a system window has focus, then it doesn't make sense @@ -1436,13 +1491,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (type == WindowManager.LayoutParams.TYPE_KEYGUARD || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) { // the "app" is keyguard, so give it the key - return false; + return 0; } final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length; for (int i=0; i<typeCount; i++) { if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) { // don't do anything, but also don't pass it to the app - return true; + return -1; } } } @@ -1456,7 +1511,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } } - return true; + return -1; } else if (keyCode == KeyEvent.KEYCODE_MENU) { // Hijack modified menu keys for debugging features final int chordBug = KeyEvent.META_SHIFT_ON; @@ -1465,7 +1520,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) { Intent intent = new Intent(Intent.ACTION_BUG_REPORT); mContext.sendOrderedBroadcast(intent, null); - return true; + return -1; } else if (SHOW_PROCESSES_ON_ALT_MENU && (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) { Intent service = new Intent(); @@ -1480,7 +1535,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } Settings.System.putInt( res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1); - return true; + return -1; } } } else if (keyCode == KeyEvent.KEYCODE_SEARCH) { @@ -1493,15 +1548,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { mShortcutKeyPressed = -1; if (mConsumeShortcutKeyUp) { mConsumeShortcutKeyUp = false; - return true; + return -1; } } - return false; + return 0; } else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) { if (down && repeatCount == 0) { showOrHideRecentAppsDialog(0, true /*dismissIfShown*/); } - return true; + return -1; } // Shortcuts are invoked through Search+key, so intercept those here @@ -1531,11 +1586,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { + "+" + KeyEvent.keyCodeToString(keyCode)); } } - return true; + return -1; } } - return false; + return 0; } /** {@inheritDoc} */ @@ -1606,7 +1661,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { flags, event.getSource(), null); int actions = interceptKeyBeforeQueueing(fallbackEvent, policyFlags, true); if ((actions & ACTION_PASS_TO_USER) != 0) { - if (!interceptKeyBeforeDispatching(win, fallbackEvent, policyFlags)) { + long delayMillis = interceptKeyBeforeDispatching( + win, fallbackEvent, policyFlags); + if (delayMillis == 0) { if (DEBUG_FALLBACK) { Slog.d(TAG, "Performing fallback."); } @@ -2472,76 +2529,65 @@ public class PhoneWindowManager implements WindowManagerPolicy { final Object mScreenshotLock = new Object(); ServiceConnection mScreenshotConnection = null; - Runnable mScreenshotTimeout = null; - void finishScreenshotLSS(ServiceConnection conn) { - if (mScreenshotConnection == conn) { - mContext.unbindService(conn); - mScreenshotConnection = null; - if (mScreenshotTimeout != null) { - mHandler.removeCallbacks(mScreenshotTimeout); - mScreenshotTimeout = null; + final Runnable mScreenshotTimeout = new Runnable() { + @Override public void run() { + synchronized (mScreenshotLock) { + if (mScreenshotConnection != null) { + mContext.unbindService(mScreenshotConnection); + mScreenshotConnection = null; + } } } - } + }; + // Assume this is called from the Handler thread. private void takeScreenshot() { - mHandler.post(new Runnable() { - @Override - public void run() { - synchronized (mScreenshotLock) { - if (mScreenshotConnection != null) { - return; - } - ComponentName cn = new ComponentName("com.android.systemui", - "com.android.systemui.screenshot.TakeScreenshotService"); - Intent intent = new Intent(); - intent.setComponent(cn); - ServiceConnection conn = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - synchronized (mScreenshotLock) { - if (mScreenshotConnection != this) { - return; - } - Messenger messenger = new Messenger(service); - Message msg = Message.obtain(null, 1); - final ServiceConnection myConn = this; - Handler h = new Handler(mHandler.getLooper()) { - @Override - public void handleMessage(Message msg) { - synchronized (mScreenshotLock) { - finishScreenshotLSS(myConn); - } - } - }; - msg.replyTo = new Messenger(h); - try { - messenger.send(msg); - } catch (RemoteException e) { - } - } + synchronized (mScreenshotLock) { + if (mScreenshotConnection != null) { + return; + } + ComponentName cn = new ComponentName("com.android.systemui", + "com.android.systemui.screenshot.TakeScreenshotService"); + Intent intent = new Intent(); + intent.setComponent(cn); + ServiceConnection conn = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + synchronized (mScreenshotLock) { + if (mScreenshotConnection != this) { + return; } - @Override - public void onServiceDisconnected(ComponentName name) {} - }; - if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) { - mScreenshotConnection = conn; - mScreenshotTimeout = new Runnable() { - @Override public void run() { + Messenger messenger = new Messenger(service); + Message msg = Message.obtain(null, 1); + final ServiceConnection myConn = this; + Handler h = new Handler(mHandler.getLooper()) { + @Override + public void handleMessage(Message msg) { synchronized (mScreenshotLock) { - if (mScreenshotConnection != null) { - finishScreenshotLSS(mScreenshotConnection); + if (mScreenshotConnection == myConn) { + mContext.unbindService(mScreenshotConnection); + mScreenshotConnection = null; + mHandler.removeCallbacks(mScreenshotTimeout); } } } - }; - mHandler.postDelayed(mScreenshotTimeout, 10000); + msg.replyTo = new Messenger(h); + try { + messenger.send(msg); + } catch (RemoteException e) { + } } } + @Override + public void onServiceDisconnected(ComponentName name) {} + }; + if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) { + mScreenshotConnection = conn; + mHandler.postDelayed(mScreenshotTimeout, 10000); } - }); + } } /** {@inheritDoc} */ @@ -2609,28 +2655,35 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Handle special keys. switch (keyCode) { case KeyEvent.KEYCODE_VOLUME_DOWN: - if (down) { - if (isScreenOn) { - // If the power key down was already triggered, take the screenshot - if (mPowerDownTriggered) { - // Dismiss the power-key longpress - mHandler.removeCallbacks(mPowerLongPress); - mPowerKeyHandled = true; - - // Take the screenshot - takeScreenshot(); - - // Prevent the event from being passed through to the current activity - result &= ~ACTION_PASS_TO_USER; - break; + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_MUTE: { + if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + if (down) { + if (isScreenOn && !mVolumeDownKeyTriggered + && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { + mVolumeDownKeyTriggered = true; + mVolumeDownKeyTime = event.getDownTime(); + mVolumeDownKeyConsumedByScreenshotChord = false; + cancelPendingPowerKeyAction(); + interceptScreenshotChord(); + } + } else { + mVolumeDownKeyTriggered = false; + cancelPendingScreenshotChordAction(); + } + } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + if (down) { + if (isScreenOn && !mVolumeUpKeyTriggered + && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { + mVolumeUpKeyTriggered = true; + cancelPendingPowerKeyAction(); + cancelPendingScreenshotChordAction(); } - mVolumeDownTriggered = true; + } else { + mVolumeUpKeyTriggered = false; + cancelPendingScreenshotChordAction(); } - } else { - mVolumeDownTriggered = false; } - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_MUTE: { if (down) { ITelephony telephonyService = getTelephonyService(); if (telephonyService != null) { @@ -2709,17 +2762,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { case KeyEvent.KEYCODE_POWER: { result &= ~ACTION_PASS_TO_USER; if (down) { - if (isScreenOn) { - // If the volume down key has been triggered, then just take the screenshot - if (mVolumeDownTriggered) { - // Take the screenshot - takeScreenshot(); - mPowerKeyHandled = true; - - // Prevent the event from being passed through to the current activity - break; - } - mPowerDownTriggered = true; + if (isScreenOn && !mPowerKeyTriggered + && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { + mPowerKeyTriggered = true; + mPowerKeyTime = event.getDownTime(); + interceptScreenshotChord(); } ITelephony telephonyService = getTelephonyService(); @@ -2741,12 +2788,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { Log.w(TAG, "ITelephony threw RemoteException", ex); } } - interceptPowerKeyDown(!isScreenOn || hungUp); + interceptPowerKeyDown(!isScreenOn || hungUp + || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered); } else { - mPowerDownTriggered = false; - if (interceptPowerKeyUp(canceled)) { + mPowerKeyTriggered = false; + cancelPendingScreenshotChordAction(); + if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) { result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP; } + mPendingPowerKeyUpCanceled = false; } break; } diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index 1eb5f0e73e50..04b4855d6238 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -804,6 +804,18 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry, logOutboundKeyDetailsLocked("dispatchKey - ", entry); } + // Handle case where the policy asked us to try again later last time. + if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) { + if (currentTime < entry->interceptKeyWakeupTime) { + if (entry->interceptKeyWakeupTime < *nextWakeupTime) { + *nextWakeupTime = entry->interceptKeyWakeupTime; + } + return false; // wait until next wakeup + } + entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN; + entry->interceptKeyWakeupTime = 0; + } + // Give the policy a chance to intercept the key. if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) { if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) { @@ -3827,14 +3839,19 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible( mLock.unlock(); - bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle, + nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle, &event, entry->policyFlags); mLock.lock(); - entry->interceptKeyResult = consumed - ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP - : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE; + if (delay < 0) { + entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP; + } else if (!delay) { + entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE; + } else { + entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER; + entry->interceptKeyWakeupTime = now() + delay; + } entry->release(); } @@ -4156,7 +4173,8 @@ InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime, deviceId(deviceId), source(source), action(action), flags(flags), keyCode(keyCode), scanCode(scanCode), metaState(metaState), repeatCount(repeatCount), downTime(downTime), - syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) { + syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN), + interceptKeyWakeupTime(0) { } InputDispatcher::KeyEntry::~KeyEntry() { @@ -4168,6 +4186,7 @@ void InputDispatcher::KeyEntry::recycle() { dispatchInProgress = false; syntheticRepeat = false; interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN; + interceptKeyWakeupTime = 0; } diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h index e78f7bd0a4cd..8ae5a56ba837 100644 --- a/services/input/InputDispatcher.h +++ b/services/input/InputDispatcher.h @@ -242,7 +242,7 @@ public: virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0; /* Allows the policy a chance to intercept a key before dispatching. */ - virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle, + virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle, const KeyEvent* keyEvent, uint32_t policyFlags) = 0; /* Allows the policy a chance to perform default processing for an unhandled key. @@ -481,8 +481,10 @@ private: INTERCEPT_KEY_RESULT_UNKNOWN, INTERCEPT_KEY_RESULT_SKIP, INTERCEPT_KEY_RESULT_CONTINUE, + INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER, }; InterceptKeyResult interceptKeyResult; // set based on the interception result + nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER KeyEntry(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, diff --git a/services/input/tests/InputDispatcher_test.cpp b/services/input/tests/InputDispatcher_test.cpp index 8dfb44b376a0..961566fe8157 100644 --- a/services/input/tests/InputDispatcher_test.cpp +++ b/services/input/tests/InputDispatcher_test.cpp @@ -75,9 +75,9 @@ private: virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) { } - virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle, + virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle, const KeyEvent* keyEvent, uint32_t policyFlags) { - return false; + return 0; } virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle, diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java index 25cc259ac776..73cd64e9f735 100644 --- a/services/java/com/android/server/wm/DragState.java +++ b/services/java/com/android/server/wm/DragState.java @@ -274,7 +274,8 @@ class DragState { final int myPid = Process.myPid(); // Move the surface to the given touch - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw"); + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( + WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw"); Surface.openTransaction(); try { mSurface.setPosition(x - mThumbOffsetX, y - mThumbOffsetY); @@ -283,7 +284,8 @@ class DragState { (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")"); } finally { Surface.closeTransaction(); - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw"); + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( + WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw"); } // Tell the affected window diff --git a/services/java/com/android/server/wm/InputManager.java b/services/java/com/android/server/wm/InputManager.java index 60333a3bf3f3..df7e0e18b7f5 100644 --- a/services/java/com/android/server/wm/InputManager.java +++ b/services/java/com/android/server/wm/InputManager.java @@ -575,7 +575,7 @@ public class InputManager implements Watchdog.Monitor { } @SuppressWarnings("unused") - public boolean interceptKeyBeforeDispatching(InputWindowHandle focus, + public long interceptKeyBeforeDispatching(InputWindowHandle focus, KeyEvent event, int policyFlags) { return mWindowManagerService.mInputMonitor.interceptKeyBeforeDispatching( focus, event, policyFlags); diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java index 9a559e004412..fb74d2764280 100644 --- a/services/java/com/android/server/wm/InputMonitor.java +++ b/services/java/com/android/server/wm/InputMonitor.java @@ -288,7 +288,7 @@ final class InputMonitor { /* Provides an opportunity for the window manager policy to process a key before * ordinary dispatch. */ - public boolean interceptKeyBeforeDispatching( + public long interceptKeyBeforeDispatching( InputWindowHandle focus, KeyEvent event, int policyFlags) { WindowState windowState = focus != null ? (WindowState) focus.windowState : null; return mService.mPolicy.interceptKeyBeforeDispatching(windowState, event, policyFlags); diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java index e25638f24888..91576e7ac0d6 100644 --- a/services/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java @@ -81,7 +81,7 @@ class ScreenRotationAnimation { mOriginalHeight = originalHeight; if (!inTransaction) { - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation"); Surface.openTransaction(); } @@ -117,7 +117,7 @@ class ScreenRotationAnimation { mSurface = null; return; } - + Paint paint = new Paint(0); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); c.drawBitmap(screenshot, 0, 0, paint); @@ -127,7 +127,7 @@ class ScreenRotationAnimation { } finally { if (!inTransaction) { Surface.closeTransaction(); - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation"); } @@ -254,7 +254,7 @@ class ScreenRotationAnimation { mEnterAnimation.restrictDuration(maxAnimationDuration); mEnterAnimation.scaleCurrentDuration(animationScale); - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.dismiss"); Surface.openTransaction(); @@ -266,7 +266,7 @@ class ScreenRotationAnimation { Slog.w(TAG, "Unable to allocate black surface", e); } finally { Surface.closeTransaction(); - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.dismiss"); } diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java index 10882f9cbd34..03b7546f8a7c 100644 --- a/services/java/com/android/server/wm/Session.java +++ b/services/java/com/android/server/wm/Session.java @@ -278,7 +278,8 @@ final class Session extends IWindowSession.Stub // Make the surface visible at the proper location final Surface surface = mService.mDragState.mSurface; - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag"); + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( + WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag"); Surface.openTransaction(); try { surface.setPosition(touchX - thumbCenterX, @@ -288,7 +289,8 @@ final class Session extends IWindowSession.Stub surface.show(); } finally { Surface.closeTransaction(); - if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag"); + if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( + WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag"); } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 595c256fb8eb..0a9ef3d6711f 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -169,6 +169,7 @@ public class WindowManagerService extends IWindowManager.Stub static final boolean DEBUG_SCREENSHOT = false; static final boolean SHOW_SURFACE_ALLOC = false; static final boolean SHOW_TRANSACTIONS = false; + static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS; static final boolean HIDE_STACK_CRAWLS = true; static final boolean PROFILE_ORIENTATION = false; @@ -2369,7 +2370,7 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { WindowState w = windowForClientLocked(session, client, false); if ((w != null) && (w.mSurface != null)) { - if (SHOW_TRANSACTIONS) Slog.i(TAG, + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion"); Surface.openTransaction(); try { @@ -2378,7 +2379,7 @@ public class WindowManagerService extends IWindowManager.Stub w.mSurface.setTransparentRegionHint(region); } finally { Surface.closeTransaction(); - if (SHOW_TRANSACTIONS) Slog.i(TAG, + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setTransparentRegion"); } } @@ -4905,7 +4906,8 @@ public class WindowManagerService extends IWindowManager.Stub } } - if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showStrictModeViolation"); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + ">>> OPEN TRANSACTION showStrictModeViolation"); Surface.openTransaction(); try { if (mStrictModeFlash == null) { @@ -4914,7 +4916,8 @@ public class WindowManagerService extends IWindowManager.Stub mStrictModeFlash.setVisibility(on); } finally { Surface.closeTransaction(); - if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showStrictModeViolation"); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + "<<< CLOSE TRANSACTION showStrictModeViolation"); } } } @@ -5231,7 +5234,7 @@ public class WindowManagerService extends IWindowManager.Stub mInputManager.setDisplayOrientation(0, rotation); if (!inTransaction) { - if (SHOW_TRANSACTIONS) Slog.i(TAG, + if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked"); Surface.openTransaction(); } @@ -5246,7 +5249,7 @@ public class WindowManagerService extends IWindowManager.Stub } finally { if (!inTransaction) { Surface.closeTransaction(); - if (SHOW_TRANSACTIONS) Slog.i(TAG, + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked"); } } @@ -5843,6 +5846,10 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayMetrics dm = mDisplayMetrics; mAppDisplayWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation); mAppDisplayHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation); + if (false) { + Slog.i(TAG, "Set app display size: " + mAppDisplayWidth + + " x " + mAppDisplayHeight); + } mDisplay.getMetricsWithSize(dm, mAppDisplayWidth, mAppDisplayHeight); mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm, @@ -5860,8 +5867,8 @@ public class WindowManagerService extends IWindowManager.Stub // Compute the screen layout size class. int screenLayout; - int longSize = dw; - int shortSize = dh; + int longSize = mAppDisplayWidth; + int shortSize = mAppDisplayHeight; if (longSize < shortSize) { int tmp = longSize; longSize = shortSize; @@ -6847,7 +6854,7 @@ public class WindowManagerService extends IWindowManager.Stub private void rebuildBlackFrame(boolean inTransaction) { if (!inTransaction) { - if (SHOW_TRANSACTIONS) Slog.i(TAG, + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION rebuildBlackFrame"); Surface.openTransaction(); } @@ -6882,7 +6889,7 @@ public class WindowManagerService extends IWindowManager.Stub } finally { if (!inTransaction) { Surface.closeTransaction(); - if (SHOW_TRANSACTIONS) Slog.i(TAG, + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION rebuildBlackFrame"); } } @@ -7354,7 +7361,8 @@ public class WindowManagerService extends IWindowManager.Stub createWatermark = true; } - if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); Surface.openTransaction(); @@ -8463,7 +8471,8 @@ public class WindowManagerService extends IWindowManager.Stub Surface.closeTransaction(); - if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, + "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); if (mWatermark != null) { mWatermark.drawIfNeeded(); diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 47f74fb4a676..e9218181ab87 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -57,6 +57,7 @@ import java.util.ArrayList; final class WindowState implements WindowManagerPolicy.WindowState { static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY; static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS; + static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS; static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC; final WindowManagerService mService; @@ -671,7 +672,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { WindowManagerService.TAG, "Got surface: " + mSurface + ", set left=" + mFrame.left + " top=" + mFrame.top + ", animLayer=" + mAnimLayer); - if (SHOW_TRANSACTIONS) { + if (SHOW_LIGHT_TRANSACTIONS) { Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked"); WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" + @@ -700,7 +701,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { mLastHidden = true; } finally { Surface.closeTransaction(); - if (SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION createSurfaceLocked"); + if (SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, + "<<< CLOSE TRANSACTION createSurfaceLocked"); } if (WindowManagerService.localLOGV) Slog.v( WindowManagerService.TAG, "Created surface " + this); diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp index f9763016ceba..7e9fba891946 100644 --- a/services/jni/com_android_server_InputManager.cpp +++ b/services/jni/com_android_server_InputManager.cpp @@ -149,6 +149,12 @@ static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t styl } } +enum { + WM_ACTION_PASS_TO_USER = 1, + WM_ACTION_POKE_USER_ACTIVITY = 2, + WM_ACTION_GO_TO_SLEEP = 4, +}; + // --- NativeInputManager --- @@ -199,7 +205,8 @@ public: virtual bool isKeyRepeatEnabled(); virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags); virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags); - virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle, + virtual nsecs_t interceptKeyBeforeDispatching( + const sp<InputWindowHandle>& inputWindowHandle, const KeyEvent* keyEvent, uint32_t policyFlags); virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle, const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent); @@ -819,12 +826,6 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags) { - enum { - WM_ACTION_PASS_TO_USER = 1, - WM_ACTION_POKE_USER_ACTIVITY = 2, - WM_ACTION_GO_TO_SLEEP = 4, - }; - if (wmActions & WM_ACTION_GO_TO_SLEEP) { #if DEBUG_INPUT_DISPATCHER_POLICY LOGD("handleInterceptActions: Going to sleep."); @@ -848,14 +849,14 @@ void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when, } } -bool NativeInputManager::interceptKeyBeforeDispatching( +nsecs_t NativeInputManager::interceptKeyBeforeDispatching( const sp<InputWindowHandle>& inputWindowHandle, const KeyEvent* keyEvent, uint32_t policyFlags) { // Policy: // - Ignore untrusted events and pass them along. // - Filter normal events and trusted injected events through the window manager policy to // handle the HOME key and the like. - bool result = false; + nsecs_t result = 0; if (policyFlags & POLICY_FLAG_TRUSTED) { JNIEnv* env = jniEnv(); @@ -863,13 +864,19 @@ bool NativeInputManager::interceptKeyBeforeDispatching( jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle); jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); if (keyEventObj) { - jboolean consumed = env->CallBooleanMethod(mCallbacksObj, + jlong delayMillis = env->CallLongMethod(mCallbacksObj, gCallbacksClassInfo.interceptKeyBeforeDispatching, inputWindowHandleObj, keyEventObj, policyFlags); bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching"); android_view_KeyEvent_recycle(env, keyEventObj); env->DeleteLocalRef(keyEventObj); - result = consumed && !error; + if (!error) { + if (delayMillis < 0) { + result = -1; + } else if (delayMillis > 0) { + result = milliseconds_to_nanoseconds(delayMillis); + } + } } else { LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching."); } @@ -1433,7 +1440,7 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz, "interceptKeyBeforeDispatching", - "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z"); + "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)J"); GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz, "dispatchUnhandledKey", diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java index c2b9e4f3b22e..4f50d2483f26 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMALTEPhone.java @@ -18,13 +18,17 @@ package com.android.internal.telephony.cdma; import android.content.ContentValues; import android.content.Context; +import android.content.SharedPreferences; import android.database.SQLException; import android.net.Uri; +import android.os.AsyncResult; import android.os.Message; +import android.preference.PreferenceManager; import android.provider.Telephony; import android.util.Log; import com.android.internal.telephony.CommandsInterface; +import com.android.internal.telephony.OperatorInfo; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneNotifier; import com.android.internal.telephony.PhoneProxy; @@ -41,6 +45,18 @@ public class CDMALTEPhone extends CDMAPhone { /** Secondary SMSDispatcher for 3GPP format messages. */ SMSDispatcher m3gppSMS; + /** + * Small container class used to hold information relevant to + * the carrier selection process. operatorNumeric can be "" + * if we are looking for automatic selection. operatorAlphaLong is the + * corresponding operator name. + */ + private static class NetworkSelectMessage { + public Message message; + public String operatorNumeric; + public String operatorAlphaLong; + } + // Constructors public CDMALTEPhone(Context context, CommandsInterface ci, PhoneNotifier notifier) { super(context, ci, notifier, false); @@ -48,6 +64,20 @@ public class CDMALTEPhone extends CDMAPhone { } @Override + public void handleMessage (Message msg) { + AsyncResult ar; + Message onComplete; + switch (msg.what) { + // handle the select network completion callbacks. + case EVENT_SET_NETWORK_MANUAL_COMPLETE: + handleSetSelectNetwork((AsyncResult) msg.obj); + break; + default: + super.handleMessage(msg); + } + } + + @Override protected void initSstIcc() { mSST = new CdmaLteServiceStateTracker(this); mIccRecords = new CdmaLteUiccRecords(this); @@ -109,6 +139,58 @@ public class CDMALTEPhone extends CDMAPhone { } @Override + public void + selectNetworkManually(OperatorInfo network, + Message response) { + // wrap the response message in our own message along with + // the operator's id. + NetworkSelectMessage nsm = new NetworkSelectMessage(); + nsm.message = response; + nsm.operatorNumeric = network.getOperatorNumeric(); + nsm.operatorAlphaLong = network.getOperatorAlphaLong(); + + // get the message + Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); + + mCM.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg); + } + + /** + * Used to track the settings upon completion of the network change. + */ + private void handleSetSelectNetwork(AsyncResult ar) { + // look for our wrapper within the asyncresult, skip the rest if it + // is null. + if (!(ar.userObj instanceof NetworkSelectMessage)) { + if (DBG) Log.d(LOG_TAG, "unexpected result from user object."); + return; + } + + NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj; + + // found the object, now we send off the message we had originally + // attached to the request. + if (nsm.message != null) { + if (DBG) Log.d(LOG_TAG, "sending original message to recipient"); + AsyncResult.forMessage(nsm.message, ar.result, ar.exception); + nsm.message.sendToTarget(); + } + + // open the shared preferences editor, and write the value. + // nsm.operatorNumeric is "" if we're in automatic.selection. + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); + SharedPreferences.Editor editor = sp.edit(); + editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric); + editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong); + + // commit and log the result. + if (! editor.commit()) { + Log.e(LOG_TAG, "failed to commit network selection preference"); + } + + } + + @Override public boolean updateCurrentCarrierInProvider() { if (mIccRecords != null) { try { diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index 8f5a2eb930a7..3d6cd6821c40 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -726,7 +726,7 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { isPrlLoaded = false; } if (!isPrlLoaded) { - newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_FLASH); + newSS.setCdmaRoamingIndicator(EriInfo.ROAMING_INDICATOR_OFF); } else if (!isSidsAllZeros()) { if (!namMatch && !mIsInPrl) { // Use default |