diff options
Diffstat (limited to 'policy')
5 files changed, 494 insertions, 66 deletions
diff --git a/policy/src/com/android/internal/policy/impl/BurnInProtectionHelper.java b/policy/src/com/android/internal/policy/impl/BurnInProtectionHelper.java new file mode 100644 index 0000000..11c739c --- /dev/null +++ b/policy/src/com/android/internal/policy/impl/BurnInProtectionHelper.java @@ -0,0 +1,266 @@ +package com.android.internal.policy.impl; + +import android.animation.Animator; +import android.animation.ValueAnimator; +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.hardware.display.DisplayManager; +import android.hardware.display.DisplayManagerInternal; +import android.os.SystemClock; +import android.util.Slog; +import android.view.Display; +import android.view.animation.LinearInterpolator; + +import com.android.server.LocalServices; + +import java.io.PrintWriter; +import java.util.concurrent.TimeUnit; + +public class BurnInProtectionHelper implements DisplayManager.DisplayListener, + Animator.AnimatorListener, ValueAnimator.AnimatorUpdateListener { + private static final String TAG = "BurnInProtection"; + + // Default value when max burnin radius is not set. + public static final int BURN_IN_MAX_RADIUS_DEFAULT = -1; + + private static final long BURNIN_PROTECTION_WAKEUP_INTERVAL_MS = TimeUnit.MINUTES.toMillis(1); + private static final long BURNIN_PROTECTION_MINIMAL_INTERVAL_MS = TimeUnit.SECONDS.toMillis(10); + + private static final boolean DEBUG = false; + + private static final String ACTION_BURN_IN_PROTECTION = + "android.internal.policy.action.BURN_IN_PROTECTION"; + + private static final int BURN_IN_SHIFT_STEP = 2; + private static final long CENTERING_ANIMATION_DURATION_MS = 100; + private final ValueAnimator mCenteringAnimator; + + private boolean mBurnInProtectionActive; + private boolean mFirstUpdate; + + private final int mMinHorizontalBurnInOffset; + private final int mMaxHorizontalBurnInOffset; + private final int mMinVerticalBurnInOffset; + private final int mMaxVerticalBurnInOffset; + + private final int mBurnInRadiusMaxSquared; + + private int mLastBurnInXOffset = 0; + /* 1 means increasing, -1 means decreasing */ + private int mXOffsetDirection = 1; + private int mLastBurnInYOffset = 0; + /* 1 means increasing, -1 means decreasing */ + private int mYOffsetDirection = 1; + + private final AlarmManager mAlarmManager; + private final PendingIntent mBurnInProtectionIntent; + private final DisplayManagerInternal mDisplayManagerInternal; + private final Display mDisplay; + + private BroadcastReceiver mBurnInProtectionReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (DEBUG) { + Slog.d(TAG, "onReceive " + intent); + } + updateBurnInProtection(); + } + }; + + public BurnInProtectionHelper(Context context, int minHorizontalOffset, + int maxHorizontalOffset, int minVerticalOffset, int maxVerticalOffset, + int maxOffsetRadius) { + mMinHorizontalBurnInOffset = minHorizontalOffset; + mMaxHorizontalBurnInOffset = maxHorizontalOffset; + mMinVerticalBurnInOffset = minVerticalOffset; + mMaxVerticalBurnInOffset = maxVerticalOffset; + if (maxOffsetRadius != BURN_IN_MAX_RADIUS_DEFAULT) { + mBurnInRadiusMaxSquared = maxOffsetRadius * maxOffsetRadius; + } else { + mBurnInRadiusMaxSquared = BURN_IN_MAX_RADIUS_DEFAULT; + } + + mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); + mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + context.registerReceiver(mBurnInProtectionReceiver, + new IntentFilter(ACTION_BURN_IN_PROTECTION)); + Intent intent = new Intent(ACTION_BURN_IN_PROTECTION); + intent.setPackage(context.getPackageName()); + intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + mBurnInProtectionIntent = PendingIntent.getBroadcast(context, 0, + intent, PendingIntent.FLAG_UPDATE_CURRENT); + DisplayManager displayManager = + (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE); + mDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + displayManager.registerDisplayListener(this, null /* handler */); + + mCenteringAnimator = ValueAnimator.ofFloat(1f, 0f); + mCenteringAnimator.setDuration(CENTERING_ANIMATION_DURATION_MS); + mCenteringAnimator.setInterpolator(new LinearInterpolator()); + mCenteringAnimator.addListener(this); + mCenteringAnimator.addUpdateListener(this); + } + + public void startBurnInProtection() { + if (!mBurnInProtectionActive) { + mBurnInProtectionActive = true; + mFirstUpdate = true; + mCenteringAnimator.cancel(); + updateBurnInProtection(); + } + } + + private void updateBurnInProtection() { + if (mBurnInProtectionActive) { + // We don't want to adjust offsets immediately after the device goes into ambient mode. + // Instead, we want to wait until it's more likely that the user is not observing the + // screen anymore. + if (mFirstUpdate) { + mFirstUpdate = false; + } else { + adjustOffsets(); + mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(), + mLastBurnInXOffset, mLastBurnInYOffset); + } + // We use currentTimeMillis to compute the next wakeup time since we want to wake up at + // the same time as we wake up to update ambient mode to minimize power consumption. + // However, we use elapsedRealtime to schedule the alarm so that setting the time can't + // disable burn-in protection for extended periods. + final long nowWall = System.currentTimeMillis(); + final long nowElapsed = SystemClock.elapsedRealtime(); + // Next adjustment at least ten seconds in the future. + long nextWall = nowWall + BURNIN_PROTECTION_MINIMAL_INTERVAL_MS; + // And aligned to the minute. + nextWall = nextWall - nextWall % BURNIN_PROTECTION_WAKEUP_INTERVAL_MS + + BURNIN_PROTECTION_WAKEUP_INTERVAL_MS; + // Use elapsed real time that is adjusted to full minute on wall clock. + final long nextElapsed = nowElapsed + (nextWall - nowWall); + if (DEBUG) { + Slog.d(TAG, "scheduling next wake-up, now wall time " + nowWall + + ", next wall: " + nextWall + ", now elapsed: " + nowElapsed + + ", next elapsed: " + nextElapsed); + } + mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, nextElapsed, + mBurnInProtectionIntent); + } else { + mAlarmManager.cancel(mBurnInProtectionIntent); + mCenteringAnimator.start(); + } + } + + public void cancelBurnInProtection() { + if (mBurnInProtectionActive) { + mBurnInProtectionActive = false; + updateBurnInProtection(); + } + } + + /** + * Gently shifts current burn-in offsets, minimizing the change for the user. + * + * Shifts are applied in following fashion: + * 1) shift horizontally from minimum to the maximum; + * 2) shift vertically by one from minimum to the maximum; + * 3) shift horizontally from maximum to the minimum; + * 4) shift vertically by one from minimum to the maximum. + * 5) if you reach the maximum vertically, start shifting back by one from maximum to minimum. + * + * On top of that, stay within specified radius. If the shift distance from the center is + * higher than the radius, skip these values and go the next position that is within the radius. + */ + private void adjustOffsets() { + do { + // By default, let's just shift the X offset. + final int xChange = mXOffsetDirection * BURN_IN_SHIFT_STEP; + mLastBurnInXOffset += xChange; + if (mLastBurnInXOffset > mMaxHorizontalBurnInOffset + || mLastBurnInXOffset < mMinHorizontalBurnInOffset) { + // Whoops, we went too far horizontally. Let's retract.. + mLastBurnInXOffset -= xChange; + // change horizontal direction.. + mXOffsetDirection *= -1; + // and let's shift the Y offset. + final int yChange = mYOffsetDirection * BURN_IN_SHIFT_STEP; + mLastBurnInYOffset += yChange; + if (mLastBurnInYOffset > mMaxVerticalBurnInOffset + || mLastBurnInYOffset < mMinVerticalBurnInOffset) { + // Whoops, we went to far vertically. Let's retract.. + mLastBurnInYOffset -= yChange; + // and change vertical direction. + mYOffsetDirection *= -1; + } + } + // If we are outside of the radius, let's try again. + } while (mBurnInRadiusMaxSquared != BURN_IN_MAX_RADIUS_DEFAULT + && mLastBurnInXOffset * mLastBurnInXOffset + mLastBurnInYOffset * mLastBurnInYOffset + > mBurnInRadiusMaxSquared); + } + + public void dump(String prefix, PrintWriter pw) { + pw.println(prefix + TAG); + prefix += " "; + pw.println(prefix + "mBurnInProtectionActive=" + mBurnInProtectionActive); + pw.println(prefix + "mHorizontalBurnInOffsetsBounds=(" + mMinHorizontalBurnInOffset + ", " + + mMaxHorizontalBurnInOffset + ")"); + pw.println(prefix + "mVerticalBurnInOffsetsBounds=(" + mMinVerticalBurnInOffset + ", " + + mMaxVerticalBurnInOffset + ")"); + pw.println(prefix + "mBurnInRadiusMaxSquared=" + mBurnInRadiusMaxSquared); + pw.println(prefix + "mLastBurnInOffset=(" + mLastBurnInXOffset + ", " + + mLastBurnInYOffset + ")"); + pw.println(prefix + "mOfsetChangeDirections=(" + mXOffsetDirection + ", " + + mYOffsetDirection + ")"); + } + + @Override + public void onDisplayAdded(int i) { + } + + @Override + public void onDisplayRemoved(int i) { + } + + @Override + public void onDisplayChanged(int displayId) { + if (displayId == mDisplay.getDisplayId()) { + if (mDisplay.getState() == Display.STATE_DOZE + || mDisplay.getState() == Display.STATE_DOZE_SUSPEND) { + startBurnInProtection(); + } else { + cancelBurnInProtection(); + } + } + } + + @Override + public void onAnimationStart(Animator animator) { + } + + @Override + public void onAnimationEnd(Animator animator) { + if (animator == mCenteringAnimator && !mBurnInProtectionActive) { + // No matter how the animation finishes, we want to zero the offsets. + mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(), 0, 0); + } + } + + @Override + public void onAnimationCancel(Animator animator) { + } + + @Override + public void onAnimationRepeat(Animator animator) { + } + + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + if (!mBurnInProtectionActive) { + final float value = (Float) valueAnimator.getAnimatedValue(); + mDisplayManagerInternal.setDisplayOffsets(mDisplay.getDisplayId(), + (int) (mLastBurnInXOffset * value), (int) (mLastBurnInYOffset * value)); + } + } +} diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index b0b2886..07fc4c7 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -100,6 +100,8 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac private static final String GLOBAL_ACTION_KEY_USERS = "users"; private static final String GLOBAL_ACTION_KEY_SETTINGS = "settings"; private static final String GLOBAL_ACTION_KEY_LOCKDOWN = "lockdown"; + private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist"; + private static final String GLOBAL_ACTION_KEY_ASSIST = "assist"; private final Context mContext; private final WindowManagerFuncs mWindowManagerFuncs; @@ -291,6 +293,10 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac mItems.add(getSettingsAction()); } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) { mItems.add(getLockdownAction()); + } else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) { + mItems.add(getVoiceAssistAction()); + } else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) { + mItems.add(getAssistAction()); } else { Log.e(TAG, "Invalid global action key " + actionKey); } @@ -436,6 +442,50 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac }; } + private Action getAssistAction() { + return new SinglePressAction(com.android.internal.R.drawable.ic_action_assist_focused, + R.string.global_action_assist) { + @Override + public void onPress() { + Intent intent = new Intent(Intent.ACTION_ASSIST); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + mContext.startActivity(intent); + } + + @Override + public boolean showDuringKeyguard() { + return true; + } + + @Override + public boolean showBeforeProvisioning() { + return true; + } + }; + } + + private Action getVoiceAssistAction() { + return new SinglePressAction(com.android.internal.R.drawable.ic_voice_search, + R.string.global_action_voice_assist) { + @Override + public void onPress() { + Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + mContext.startActivity(intent); + } + + @Override + public boolean showDuringKeyguard() { + return true; + } + + @Override + public boolean showBeforeProvisioning() { + return true; + } + }; + } + private Action getLockdownAction() { return new SinglePressAction(com.android.internal.R.drawable.ic_lock_lock, R.string.global_action_lockdown) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index b4811da..c9028c4 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -25,6 +25,7 @@ import static android.view.WindowManager.LayoutParams.*; import android.app.SearchManager; import android.os.UserHandle; import com.android.internal.R; +import com.android.internal.util.ScreenShapeHelper; import com.android.internal.view.RootViewSurfaceTaker; import com.android.internal.view.StandaloneActionMode; import com.android.internal.view.menu.ContextMenuBuilder; @@ -61,6 +62,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemProperties; import android.transition.Scene; import android.transition.Transition; import android.transition.TransitionInflater; @@ -145,7 +147,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { TypedValue mFixedWidthMinor; TypedValue mFixedHeightMajor; TypedValue mFixedHeightMinor; - TypedValue mOutsetBottom; + int mOutsetBottomPx; // This is the top-level view of the window, containing the window decor. private DecorView mDecor; @@ -2379,12 +2381,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { @Override public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { - if (mOutsetBottom != null) { - final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); - int bottom = (int) mOutsetBottom.getDimension(metrics); + if (mOutsetBottomPx != 0) { WindowInsets newInsets = insets.replaceSystemWindowInsets( insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), - insets.getSystemWindowInsetRight(), bottom); + insets.getSystemWindowInsetRight(), mOutsetBottomPx); return super.dispatchApplyWindowInsets(newInsets); } else { return super.dispatchApplyWindowInsets(insets); @@ -2603,12 +2603,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } } - if (mOutsetBottom != null) { + if (mOutsetBottomPx != 0) { int mode = MeasureSpec.getMode(heightMeasureSpec); if (mode != MeasureSpec.UNSPECIFIED) { - int outset = (int) mOutsetBottom.getDimension(metrics); int height = MeasureSpec.getSize(heightMeasureSpec); - heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + outset, mode); + heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + mOutsetBottomPx, mode); } } @@ -3441,10 +3440,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { final boolean shouldUseBottomOutset = display.getDisplayId() == Display.DEFAULT_DISPLAY || (getForcedWindowFlags() & FLAG_FULLSCREEN) != 0; - if (shouldUseBottomOutset && a.hasValue(R.styleable.Window_windowOutsetBottom)) { - if (mOutsetBottom == null) mOutsetBottom = new TypedValue(); - a.getValue(R.styleable.Window_windowOutsetBottom, - mOutsetBottom); + if (shouldUseBottomOutset) { + mOutsetBottomPx = ScreenShapeHelper.getWindowOutsetBottomPx( + getContext().getResources().getDisplayMetrics(), a); } } @@ -4159,12 +4157,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { return mMediaController; } - private boolean isTranslucent() { - TypedArray a = getWindowStyle(); - return a.getBoolean(a.getResourceId( - R.styleable.Window_windowIsTranslucent, 0), false); - } - @Override public void setEnterTransition(Transition enterTransition) { mEnterTransition = enterTransition; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index c8cfab8..634b57e 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -47,6 +47,7 @@ import android.media.IAudioService; import android.media.Ringtone; import android.media.RingtoneManager; import android.media.session.MediaSessionLegacyHelper; +import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.FactoryTest; @@ -91,6 +92,7 @@ import android.view.MotionEvent; import android.view.Surface; import android.view.View; import android.view.ViewConfiguration; +import android.view.ViewRootImpl; import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -153,6 +155,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1; static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2; static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME = 3; + static final int SHORT_PRESS_POWER_GO_HOME = 4; static final int LONG_PRESS_POWER_NOTHING = 0; static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; @@ -172,6 +175,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int DOUBLE_TAP_HOME_NOTHING = 0; static final int DOUBLE_TAP_HOME_RECENT_SYSTEM_UI = 1; + static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0; + static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1; + static final int APPLICATION_MEDIA_SUBLAYER = -2; static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1; static final int APPLICATION_PANEL_SUBLAYER = 1; @@ -251,6 +257,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { Vibrator mVibrator; // Vibrator for giving feedback of orientation changes SearchManager mSearchManager; AccessibilityManager mAccessibilityManager; + BurnInProtectionHelper mBurnInProtectionHelper; // Vibrator pattern for haptic feedback of a long press. long[] mLongPressVibePattern; @@ -366,6 +373,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLongPressOnPowerBehavior; int mDoublePressOnPowerBehavior; int mTriplePressOnPowerBehavior; + int mShortPressOnSleepBehavior; boolean mAwake; boolean mScreenOnEarly; boolean mScreenOnFully; @@ -534,6 +542,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { private boolean mAllowTheaterModeWakeFromLidSwitch; private boolean mAllowTheaterModeWakeFromWakeGesture; + // Whether to support long press from power button in non-interactive mode + private boolean mSupportLongPressPowerWhenNonInteractive; + // Whether to go to sleep entering theater mode from power button private boolean mGoToSleepOnButtonPressTheaterMode; @@ -885,12 +896,21 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } else { wakeUpFromPowerKey(event.getDownTime()); - final int maxCount = getMaxMultiPressPowerCount(); - if (maxCount <= 1) { - mPowerKeyHandled = true; - } else { + if (mSupportLongPressPowerWhenNonInteractive && hasLongPressOnPowerBehavior()) { + Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS); + msg.setAsynchronous(true); + mHandler.sendMessageDelayed(msg, + ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); mBeganFromNonInteractive = true; + } else { + final int maxCount = getMaxMultiPressPowerCount(); + + if (maxCount <= 1) { + mPowerKeyHandled = true; + } else { + mBeganFromNonInteractive = true; + } } } } @@ -971,6 +991,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE); launchHomeFromHotKey(); break; + case SHORT_PRESS_POWER_GO_HOME: + launchHomeFromHotKey(true /* awakenFromDreams */, false /*respectKeyguard*/); + break; } } } @@ -1040,6 +1063,20 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void sleepPress(KeyEvent event) { + switch (mShortPressOnSleepBehavior) { + case SHORT_PRESS_SLEEP_GO_TO_SLEEP: + mPowerManager.goToSleep(event.getEventTime(), + PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); + break; + case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME: + launchHomeFromHotKey(false /* awakenDreams */, true /*respectKeyguard*/); + mPowerManager.goToSleep(event.getEventTime(), + PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); + break; + } + } + private int getResolvedLongPressOnPowerBehavior() { if (FactoryTest.isLongPressOnPowerOffEnabled()) { return LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM; @@ -1170,6 +1207,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { } }; + private boolean isRoundWindow() { + return mContext.getResources().getBoolean(com.android.internal.R.bool.config_windowIsRound) + || (Build.HARDWARE.contains("goldfish") + && SystemProperties.getBoolean(ViewRootImpl.PROPERTY_EMULATOR_CIRCULAR, false)); + } + /** {@inheritDoc} */ @Override public void init(Context context, IWindowManager windowManager, @@ -1180,6 +1223,41 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); + // Init display burn-in protection + boolean burnInProtectionEnabled = context.getResources().getBoolean( + com.android.internal.R.bool.config_enableBurnInProtection); + // Allow a system property to override this. Used by developer settings. + boolean burnInProtectionDevMode = + SystemProperties.getBoolean("persist.debug.force_burn_in", false); + if (burnInProtectionEnabled || burnInProtectionDevMode) { + final int minHorizontal; + final int maxHorizontal; + final int minVertical; + final int maxVertical; + final int maxRadius; + if (burnInProtectionDevMode) { + minHorizontal = -8; + maxHorizontal = 8; + minVertical = -8; + maxVertical = -4; + maxRadius = (isRoundWindow()) ? 6 : -1; + } else { + Resources resources = context.getResources(); + minHorizontal = resources.getInteger( + com.android.internal.R.integer.config_burnInProtectionMinHorizontalOffset); + maxHorizontal = resources.getInteger( + com.android.internal.R.integer.config_burnInProtectionMaxHorizontalOffset); + minVertical = resources.getInteger( + com.android.internal.R.integer.config_burnInProtectionMinVerticalOffset); + maxVertical = resources.getInteger( + com.android.internal.R.integer.config_burnInProtectionMaxVerticalOffset); + maxRadius = resources.getInteger( + com.android.internal.R.integer.config_burnInProtectionMaxRadius); + } + mBurnInProtectionHelper = new BurnInProtectionHelper( + context, minHorizontal, maxHorizontal, minVertical, maxVertical, maxRadius); + } + mHandler = new PolicyHandler(); mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler); mOrientationListener = new MyOrientationListener(mContext, mHandler); @@ -1253,6 +1331,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { mGoToSleepOnButtonPressTheaterMode = mContext.getResources().getBoolean( com.android.internal.R.bool.config_goToSleepOnButtonPressTheaterMode); + mSupportLongPressPowerWhenNonInteractive = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_supportLongPressPowerWhenNonInteractive); + mShortPressOnPowerBehavior = mContext.getResources().getInteger( com.android.internal.R.integer.config_shortPressOnPowerBehavior); mLongPressOnPowerBehavior = mContext.getResources().getInteger( @@ -1261,6 +1342,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.integer.config_doublePressOnPowerBehavior); mTriplePressOnPowerBehavior = mContext.getResources().getInteger( com.android.internal.R.integer.config_triplePressOnPowerBehavior); + mShortPressOnSleepBehavior = mContext.getResources().getInteger( + com.android.internal.R.integer.config_shortPressOnSleepBehavior); readConfigurationDependentBehaviors(); @@ -2980,45 +3063,57 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + void launchHomeFromHotKey() { + launchHomeFromHotKey(true /* awakenFromDreams */, true /*respectKeyguard*/); + } + /** * A home key -> launch home action was detected. Take the appropriate action * given the situation with the keyguard. */ - void launchHomeFromHotKey() { - if (isKeyguardShowingAndNotOccluded()) { - // don't launch home if keyguard showing - } else if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) { - // when in keyguard restricted mode, must first verify unlock - // before launching home - mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() { - @Override - public void onKeyguardExitResult(boolean success) { - if (success) { - try { - ActivityManagerNative.getDefault().stopAppSwitches(); - } catch (RemoteException e) { + void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) { + if (respectKeyguard) { + if (isKeyguardShowingAndNotOccluded()) { + // don't launch home if keyguard showing + return; + } + + if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) { + // when in keyguard restricted mode, must first verify unlock + // before launching home + mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() { + @Override + public void onKeyguardExitResult(boolean success) { + if (success) { + try { + ActivityManagerNative.getDefault().stopAppSwitches(); + } catch (RemoteException e) { + } + sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); + startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); } - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); - startDockOrHome(); } - } - }); - } else { - // no keyguard stuff to worry about, just launch home! - try { - ActivityManagerNative.getDefault().stopAppSwitches(); - } catch (RemoteException e) { + }); + return; } - if (mRecentsVisible) { - // Hide Recents and notify it to launch Home + } + + // no keyguard stuff to worry about, just launch home! + try { + ActivityManagerNative.getDefault().stopAppSwitches(); + } catch (RemoteException e) { + } + if (mRecentsVisible) { + // Hide Recents and notify it to launch Home + if (awakenFromDreams) { awakenDreams(); - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); - hideRecentApps(false, true); - } else { - // Otherwise, just launch Home - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); - startDockOrHome(); } + sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); + hideRecentApps(false, true); + } else { + // Otherwise, just launch Home + sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); + startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); } } @@ -3419,8 +3514,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ @Override public int getSystemDecorLayerLw() { - if (mStatusBar != null) return mStatusBar.getSurfaceLayer(); - if (mNavigationBar != null) return mNavigationBar.getSurfaceLayer(); + if (mStatusBar != null && mStatusBar.isVisibleLw()) { + return mStatusBar.getSurfaceLayer(); + } + + if (mNavigationBar != null && mNavigationBar.isVisibleLw()) { + return mNavigationBar.getSurfaceLayer(); + } + return 0; } @@ -4674,12 +4775,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { case KeyEvent.KEYCODE_SLEEP: { result &= ~ACTION_PASS_TO_USER; + isWakeKey = false; if (!mPowerManager.isInteractive()) { useHapticFeedback = false; // suppress feedback if already non-interactive } - mPowerManager.goToSleep(event.getEventTime(), - PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0); - isWakeKey = false; + sleepPress(event); break; } @@ -5829,19 +5929,33 @@ public class PhoneWindowManager implements WindowManagerPolicy { return null; } - void startDockOrHome() { - awakenDreams(); + void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) { + if (awakenFromDreams) { + awakenDreams(); + } Intent dock = createHomeDockIntent(); if (dock != null) { try { + if (fromHomeKey) { + dock.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); + } startActivityAsUser(dock, UserHandle.CURRENT); return; } catch (ActivityNotFoundException e) { } } - startActivityAsUser(mHomeIntent, UserHandle.CURRENT); + Intent intent; + + if (fromHomeKey) { + intent = new Intent(mHomeIntent); + intent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, fromHomeKey); + } else { + intent = mHomeIntent; + } + + startActivityAsUser(intent, UserHandle.CURRENT); } /** @@ -5860,7 +5974,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } catch (RemoteException e) { } sendCloseSystemWindows(); - startDockOrHome(); + startDockOrHome(false /*fromHomeKey*/, true /* awakenFromDreams */); } else { // This code brings home to the front or, if it is already // at the front, puts the device to sleep. @@ -6394,5 +6508,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mOrientationListener != null) { mOrientationListener.dump(pw, prefix); } + if (mBurnInProtectionHelper != null) { + mBurnInProtectionHelper.dump(prefix, pw); + } } } 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 6e8f550..6c98e50 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ActivityInfo; +import android.content.res.Resources; import android.graphics.PixelFormat; import android.os.Bundle; import android.os.IBinder; @@ -27,9 +28,6 @@ import com.android.internal.policy.IKeyguardShowCallback; * local or remote instances of keyguard. */ public class KeyguardServiceDelegate { - public static final String KEYGUARD_PACKAGE = "com.android.systemui"; - public static final String KEYGUARD_CLASS = "com.android.systemui.keyguard.KeyguardService"; - private static final String TAG = "KeyguardServiceDelegate"; private static final boolean DEBUG = true; @@ -111,10 +109,15 @@ public class KeyguardServiceDelegate { public void bindService(Context context) { Intent intent = new Intent(); - intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS); + final Resources resources = context.getApplicationContext().getResources(); + + final ComponentName keyguardComponent = ComponentName.unflattenFromString( + resources.getString(com.android.internal.R.string.config_keyguardComponent)); + intent.setComponent(keyguardComponent); + if (!context.bindServiceAsUser(intent, mKeyguardConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { - Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS); + Log.v(TAG, "*** Keyguard: can't bind to " + keyguardComponent); mKeyguardState.showing = false; mKeyguardState.showingAndNotOccluded = false; mKeyguardState.secure = false; |
