diff options
Diffstat (limited to 'policy')
4 files changed, 211 insertions, 137 deletions
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 2fea785..6b0095a 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -3179,7 +3179,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { com.android.internal.R.attr.dialogTitleDecorLayout, res, true); layoutResource = res.resourceId; } else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) { - layoutResource = com.android.internal.R.layout.screen_action_bar; + layoutResource = a.getResourceId( + com.android.internal.R.styleable.Window_windowActionBarFullscreenDecorLayout, + com.android.internal.R.layout.screen_action_bar); } else { layoutResource = com.android.internal.R.layout.screen_title; } diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 9977193..8e68dfc 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -66,6 +66,7 @@ import android.os.Vibrator; import android.provider.Settings; import android.service.dreams.DreamService; import android.service.dreams.IDreamManager; +import android.telephony.TelephonyManager; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; @@ -354,6 +355,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { // the same as mCur*, but may be larger if the screen decor has supplied // content insets. int mContentLeft, mContentTop, mContentRight, mContentBottom; + // During layout, the frame in which voice content should be displayed + // to the user, accounting for all screen decoration except for any + // space they deem as available for other content. + int mVoiceContentLeft, mVoiceContentTop, mVoiceContentRight, mVoiceContentBottom; // During layout, the current screen borders along which input method // windows are placed. int mDockLeft, mDockTop, mDockRight, mDockBottom; @@ -1261,6 +1266,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { case TYPE_INPUT_METHOD: case TYPE_WALLPAPER: case TYPE_PRIVATE_PRESENTATION: + case TYPE_VOICE_INTERACTION: // The window manager will check these. break; case TYPE_PHONE: @@ -1427,74 +1433,77 @@ public class PhoneWindowManager implements WindowManagerPolicy { return 3; case TYPE_SEARCH_BAR: return 4; + case TYPE_VOICE_INTERACTION: + // voice interaction layer is almost immediately above apps. + return 5; case TYPE_RECENTS_OVERLAY: case TYPE_SYSTEM_DIALOG: - return 5; + return 6; case TYPE_TOAST: // toasts and the plugged-in battery thing - return 6; + return 7; case TYPE_PRIORITY_PHONE: // SIM errors and unlock. Not sure if this really should be in a high layer. - return 7; + return 8; case TYPE_DREAM: // used for Dreams (screensavers with TYPE_DREAM windows) - return 8; + return 9; case TYPE_SYSTEM_ALERT: // like the ANR / app crashed dialogs - return 9; + return 10; case TYPE_INPUT_METHOD: // on-screen keyboards and other such input method user interfaces go here. - return 10; + return 11; case TYPE_INPUT_METHOD_DIALOG: // on-screen keyboards and other such input method user interfaces go here. - return 11; + return 12; case TYPE_KEYGUARD_SCRIM: // the safety window that shows behind keyguard while keyguard is starting - return 12; - case TYPE_STATUS_BAR_SUB_PANEL: return 13; - case TYPE_STATUS_BAR: + case TYPE_STATUS_BAR_SUB_PANEL: return 14; - case TYPE_STATUS_BAR_PANEL: + case TYPE_STATUS_BAR: return 15; - case TYPE_KEYGUARD_DIALOG: + case TYPE_STATUS_BAR_PANEL: return 16; + case TYPE_KEYGUARD_DIALOG: + return 17; case TYPE_VOLUME_OVERLAY: // the on-screen volume indicator and controller shown when the user // changes the device volume - return 17; + return 18; case TYPE_SYSTEM_OVERLAY: // the on-screen volume indicator and controller shown when the user // changes the device volume - return 18; + return 19; case TYPE_NAVIGATION_BAR: // the navigation bar, if available, shows atop most things - return 19; + return 20; case TYPE_NAVIGATION_BAR_PANEL: // some panels (e.g. search) need to show on top of the navigation bar - return 20; + return 21; case TYPE_SYSTEM_ERROR: // system-level error dialogs - return 21; + return 22; case TYPE_MAGNIFICATION_OVERLAY: // used to highlight the magnified portion of a display - return 22; + return 23; case TYPE_DISPLAY_OVERLAY: // used to simulate secondary display devices - return 23; + return 24; case TYPE_DRAG: // the drag layer: input for drag-and-drop is associated with this window, // which sits above all other focusable windows - return 24; - case TYPE_SECURE_SYSTEM_OVERLAY: return 25; - case TYPE_BOOT_PROGRESS: + case TYPE_SECURE_SYSTEM_OVERLAY: return 26; + case TYPE_BOOT_PROGRESS: + return 27; case TYPE_POINTER: // the (mouse) pointer layer - return 27; - case TYPE_HIDDEN_NAV_CONSUMER: return 28; + case TYPE_HIDDEN_NAV_CONSUMER: + return 29; } Log.e(TAG, "Unknown window type: " + type); return 2; @@ -1563,11 +1572,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) { + public boolean doesForceHide(WindowManager.LayoutParams attrs) { return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0; } @Override + public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs) { + return attrs.type == TYPE_STATUS_BAR; + } + + @Override public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) { switch (attrs.type) { case TYPE_STATUS_BAR: @@ -1921,9 +1935,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { ServiceManager.checkService(DreamService.DREAM_SERVICE)); } - static ITelephony getTelephonyService() { - return ITelephony.Stub.asInterface( - ServiceManager.checkService(Context.TELEPHONY_SERVICE)); + TelephonyManager getTelephonyService() { + return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); } static IAudioService getAudioService() { @@ -2006,14 +2019,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { // If an incoming call is ringing, HOME is totally disabled. // (The user is already on the InCallScreen at this point, // and his ONLY options are to answer or reject the call.) - try { - ITelephony telephonyService = getTelephonyService(); - if (telephonyService != null && telephonyService.isRinging()) { - Log.i(TAG, "Ignoring HOME; there's a ringing incoming call."); - return -1; - } - } catch (RemoteException ex) { - Log.w(TAG, "RemoteException from getPhoneInterface()", ex); + TelephonyManager telephonyManager = getTelephonyService(); + if (telephonyManager != null && telephonyManager.isRinging()) { + Log.i(TAG, "Ignoring HOME; there's a ringing incoming call."); + return -1; } // Delay handling home if a double-tap is possible. @@ -2705,13 +2714,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { mRestrictedScreenTop = mUnrestrictedScreenTop; mRestrictedScreenWidth = mSystemGestures.screenWidth = mUnrestrictedScreenWidth; mRestrictedScreenHeight = mSystemGestures.screenHeight = mUnrestrictedScreenHeight; - mDockLeft = mContentLeft = mStableLeft = mStableFullscreenLeft + mDockLeft = mContentLeft = mVoiceContentLeft = mStableLeft = mStableFullscreenLeft = mCurLeft = mUnrestrictedScreenLeft; - mDockTop = mContentTop = mStableTop = mStableFullscreenTop + mDockTop = mContentTop = mVoiceContentTop = mStableTop = mStableFullscreenTop = mCurTop = mUnrestrictedScreenTop; - mDockRight = mContentRight = mStableRight = mStableFullscreenRight + mDockRight = mContentRight = mVoiceContentRight = mStableRight = mStableFullscreenRight = mCurRight = displayWidth - overscanRight; - mDockBottom = mContentBottom = mStableBottom = mStableFullscreenBottom + mDockBottom = mContentBottom = mVoiceContentBottom = mStableBottom = mStableFullscreenBottom = mCurBottom = displayHeight - overscanBottom; mDockLayer = 0x10000000; mStatusBarLayer = -1; @@ -2822,10 +2831,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // Make sure the content and current rectangles are updated to // account for the restrictions from the navigation bar. - mContentTop = mCurTop = mDockTop; - mContentBottom = mCurBottom = mDockBottom; - mContentLeft = mCurLeft = mDockLeft; - mContentRight = mCurRight = mDockRight; + mContentTop = mVoiceContentTop = mCurTop = mDockTop; + mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; + mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; + mContentRight = mVoiceContentRight = mCurRight = mDockRight; mStatusBarLayer = mNavigationBar.getSurfaceLayer(); // And compute the final frame. mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame, @@ -2872,10 +2881,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { // status bar is visible. mDockTop = mUnrestrictedScreenTop + mStatusBarHeight; - mContentTop = mCurTop = mDockTop; - mContentBottom = mCurBottom = mDockBottom; - mContentLeft = mCurLeft = mDockLeft; - mContentRight = mCurRight = mDockRight; + mContentTop = mVoiceContentTop = mCurTop = mDockTop; + mContentBottom = mVoiceContentBottom = mCurBottom = mDockBottom; + mContentLeft = mVoiceContentLeft = mCurLeft = mDockLeft; + mContentRight = mVoiceContentRight = mCurRight = mDockRight; if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " + String.format( @@ -2946,7 +2955,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Ungh. So to deal with that, make sure the content frame // we end up using is not covering the IM dock. cf.set(attached.getContentFrameLw()); - if (attached.getSurfaceLayer() < mDockLayer) { + if (attached.isVoiceInteraction()) { + if (cf.left < mVoiceContentLeft) cf.left = mVoiceContentLeft; + if (cf.top < mVoiceContentTop) cf.top = mVoiceContentTop; + if (cf.right > mVoiceContentRight) cf.right = mVoiceContentRight; + if (cf.bottom > mVoiceContentBottom) cf.bottom = mVoiceContentBottom; + } else if (attached.getSurfaceLayer() < mDockLayer) { if (cf.left < mContentLeft) cf.left = mContentLeft; if (cf.top < mContentTop) cf.top = mContentTop; if (cf.right > mContentRight) cf.right = mContentRight; @@ -3154,16 +3168,23 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if ((fl & FLAG_FULLSCREEN) == 0) { - if (adjust != SOFT_INPUT_ADJUST_RESIZE) { - cf.left = mDockLeft; - cf.top = mDockTop; - cf.right = mDockRight; - cf.bottom = mDockBottom; + if (win.isVoiceInteraction()) { + cf.left = mVoiceContentLeft; + cf.top = mVoiceContentTop; + cf.right = mVoiceContentRight; + cf.bottom = mVoiceContentBottom; } else { - cf.left = mContentLeft; - cf.top = mContentTop; - cf.right = mContentRight; - cf.bottom = mContentBottom; + if (adjust != SOFT_INPUT_ADJUST_RESIZE) { + cf.left = mDockLeft; + cf.top = mDockTop; + cf.right = mDockRight; + cf.bottom = mDockBottom; + } else { + cf.left = mContentLeft; + cf.top = mContentTop; + cf.right = mContentRight; + cf.bottom = mContentBottom; + } } } else { // Full screen windows are always given a layout that is as if the @@ -3375,6 +3396,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { setLastInputMethodWindowLw(null, null); offsetInputMethodWindowLw(win); } + if (attrs.type == TYPE_VOICE_INTERACTION && win.isVisibleOrBehindKeyguardLw() + && !win.getGivenInsetsPendingLw()) { + offsetVoiceInputWindowLw(win); + } } private void offsetInputMethodWindowLw(WindowState win) { @@ -3383,6 +3408,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mContentBottom > top) { mContentBottom = top; } + if (mVoiceContentBottom > top) { + mVoiceContentBottom = top; + } top = win.getVisibleFrameLw().top; top += win.getGivenVisibleInsetsLw().top; if (mCurBottom > top) { @@ -3393,6 +3421,40 @@ public class PhoneWindowManager implements WindowManagerPolicy { + mContentBottom + " mCurBottom=" + mCurBottom); } + private void offsetVoiceInputWindowLw(WindowState win) { + final int gravity = win.getAttrs().gravity; + switch (gravity&((Gravity.AXIS_PULL_BEFORE|Gravity.AXIS_PULL_AFTER) + << Gravity.AXIS_X_SHIFT)) { + case Gravity.AXIS_PULL_BEFORE<<Gravity.AXIS_X_SHIFT: { + int right = win.getContentFrameLw().right - win.getGivenContentInsetsLw().right; + if (mVoiceContentLeft < right) { + mVoiceContentLeft = right; + } + } break; + case Gravity.AXIS_PULL_AFTER<<Gravity.AXIS_X_SHIFT: { + int left = win.getContentFrameLw().left - win.getGivenContentInsetsLw().left; + if (mVoiceContentRight < left) { + mVoiceContentRight = left; + } + } break; + } + switch (gravity&((Gravity.AXIS_PULL_BEFORE|Gravity.AXIS_PULL_AFTER) + << Gravity.AXIS_Y_SHIFT)) { + case Gravity.AXIS_PULL_BEFORE<<Gravity.AXIS_Y_SHIFT: { + int bottom = win.getContentFrameLw().bottom - win.getGivenContentInsetsLw().bottom; + if (mVoiceContentTop < bottom) { + mVoiceContentTop = bottom; + } + } break; + case Gravity.AXIS_PULL_AFTER<<Gravity.AXIS_Y_SHIFT: { + int top = win.getContentFrameLw().top - win.getGivenContentInsetsLw().top; + if (mVoiceContentBottom < top) { + mVoiceContentBottom = top; + } + } break; + } + } + /** {@inheritDoc} */ @Override public void finishLayoutLw() { @@ -3957,37 +4019,33 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } 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); + TelephonyManager telephonyManager = getTelephonyService(); + if (telephonyManager != null) { + if (telephonyManager.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.) + telephonyManager.silenceRinger(); + + // And *don't* pass this key thru to the current activity + // (which is probably the InCallScreen.) + result &= ~ACTION_PASS_TO_USER; + break; + } + if (telephonyManager.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; } } @@ -4004,14 +4062,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { case KeyEvent.KEYCODE_ENDCALL: { result &= ~ACTION_PASS_TO_USER; if (down) { - ITelephony telephonyService = getTelephonyService(); + TelephonyManager telephonyManager = getTelephonyService(); boolean hungUp = false; - if (telephonyService != null) { - try { - hungUp = telephonyService.endCall(); - } catch (RemoteException ex) { - Log.w(TAG, "ITelephony threw RemoteException", ex); - } + if (telephonyManager != null) { + hungUp = telephonyManager.endCall(); } interceptPowerKeyDown(!interactive || hungUp); } else { @@ -4047,23 +4101,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { interceptScreenshotChord(); } - ITelephony telephonyService = getTelephonyService(); + TelephonyManager telephonyManager = 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() && interactive) { - // 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); + if (telephonyManager != null) { + if (telephonyManager.isRinging()) { + // Pressing Power while there's a ringing incoming + // call should silence the ringer. + telephonyManager.silenceRinger(); + } else if ((mIncallPowerBehavior + & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0 + && telephonyManager.isOffhook() && interactive) { + // Otherwise, if "Power button ends call" is enabled, + // the Power button will hang up any current active call. + hungUp = telephonyManager.endCall(); } } interceptPowerKeyDown(!interactive || hungUp @@ -4096,16 +4146,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { case KeyEvent.KEYCODE_MEDIA_PAUSE: case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: if (down) { - ITelephony telephonyService = getTelephonyService(); - if (telephonyService != null) { - try { - if (!telephonyService.isIdle()) { - // Suppress PLAY/PAUSE toggle when phone is ringing or in-call - // to avoid music playback. - break; - } - } catch (RemoteException ex) { - Log.w(TAG, "ITelephony threw RemoteException", ex); + TelephonyManager telephonyManager = getTelephonyService(); + if (telephonyManager != null) { + if (!telephonyManager.isIdle()) { + // Suppress PLAY/PAUSE toggle when phone is ringing or in-call + // to avoid music playback. + break; } } } @@ -4135,20 +4181,16 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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); + TelephonyManager telephonyManager = getTelephonyService(); + if (telephonyManager != null) { + if (telephonyManager.isRinging()) { + Log.i(TAG, "interceptKeyBeforeQueueing:" + + " CALL key-down while ringing: Answer the call!"); + telephonyManager.answerRingingCall(); + + // And *don't* pass this key thru to the current activity + // (which is presumably the InCallScreen.) + result &= ~ACTION_PASS_TO_USER; } } } @@ -4523,6 +4565,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @Override + public void startKeyguardExitAnimation(final long fadeoutDuration) { + if (mKeyguardDelegate != null) { + mHandler.post(new Runnable() { + @Override + public void run() { + mKeyguardDelegate.startKeyguardExitAnimation(fadeoutDuration); + } + }); + } + } + void sendCloseSystemWindows() { sendCloseSystemWindows(mContext, null); } @@ -5496,6 +5550,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { pw.print(","); pw.print(mContentTop); pw.print(")-("); pw.print(mContentRight); pw.print(","); pw.print(mContentBottom); pw.println(")"); + pw.print(prefix); pw.print("mVoiceContent=("); pw.print(mVoiceContentLeft); + pw.print(","); pw.print(mVoiceContentTop); + pw.print(")-("); pw.print(mVoiceContentRight); + pw.print(","); pw.print(mVoiceContentBottom); pw.println(")"); pw.print(prefix); pw.print("mDock=("); pw.print(mDockLeft); pw.print(","); pw.print(mDockTop); pw.print(")-("); pw.print(mDockRight); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java index 966924b..faf7020 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java @@ -274,6 +274,12 @@ public class KeyguardServiceDelegate { mKeyguardState.currentUser = newUserId; } + public void startKeyguardExitAnimation(long fadeoutDuration) { + if (mKeyguardService != null) { + mKeyguardService.startKeyguardExitAnimation(fadeoutDuration); + } + } + private static final View createScrim(Context context) { View view = new View(context); diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java index 7cb48fa..f236ce7 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java @@ -190,6 +190,14 @@ public class KeyguardServiceWrapper implements IKeyguardService { } } + public void startKeyguardExitAnimation(long fadeoutDuration) { + try { + mService.startKeyguardExitAnimation(fadeoutDuration); + } catch (RemoteException e) { + Slog.w(TAG , "Remote Exception", e); + } + } + public void showAssistant() { // Not used by PhoneWindowManager } |