summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java4
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java11
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewManager.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java74
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java222
5 files changed, 261 insertions, 51 deletions
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 76d3df0..f45556f 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -293,6 +293,10 @@ class KeyguardStatusViewManager implements OnClickListener {
mUpdateMonitor.registerInfoCallback(mInfoCallback);
mUpdateMonitor.registerSimStateCallback(mSimStateCallback);
resetStatusInfo();
+ //Issue the faceunlock failure message in a centralized place
+ if (mUpdateMonitor.getMaxFaceUnlockAttemptsReached()) {
+ setInstructionText(getContext().getString(R.string.faceunlock_multiple_failures));
+ }
}
void resetStatusInfo() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index b4b82aa..1d6f39a 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -81,6 +81,8 @@ public class KeyguardUpdateMonitor {
private CharSequence mTelephonySpn;
private int mFailedAttempts = 0;
+ private int mFailedFaceUnlockAttempts = 0;
+ private static final int FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 15;
private boolean mClockVisible;
@@ -630,6 +632,7 @@ public class KeyguardUpdateMonitor {
public void clearFailedAttempts() {
mFailedAttempts = 0;
+ mFailedFaceUnlockAttempts = 0;
}
public void reportFailedAttempt() {
@@ -643,4 +646,12 @@ public class KeyguardUpdateMonitor {
public int getPhoneState() {
return mPhoneState;
}
+
+ public void reportFailedFaceUnlockAttempt() {
+ mFailedFaceUnlockAttempts++;
+ }
+
+ public boolean getMaxFaceUnlockAttemptsReached() {
+ return mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index ff8d5ac..4bba71b 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -118,6 +118,7 @@ public class KeyguardViewManager implements KeyguardWindowController {
int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
| WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING
+ | WindowManager.LayoutParams.FLAG_SLIPPERY
/*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;
if (!mNeedsInput) {
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 6eff4b6..0d0461b 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -52,6 +52,7 @@ import android.os.Handler;
import android.os.Message;
import android.os.IBinder;
import android.os.Parcelable;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -101,8 +102,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
private View mLockScreen;
private View mUnlockScreen;
- private volatile boolean mScreenOn = false;
- private volatile boolean mWindowFocused = false;
+ private boolean mScreenOn;
+ private boolean mWindowFocused = false;
private boolean mEnableFallback = false; // assume no fallback UI until we know better
private boolean mShowLockBeforeUnlock = false;
@@ -132,10 +133,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
// So the user has a consistent amount of time when brought to the backup method from FaceLock
private final int BACKUP_LOCK_TIMEOUT = 5000;
- // Needed to keep track of failed FaceUnlock attempts
- private int mFailedFaceUnlockAttempts = 0;
- private static final int FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 15;
-
/**
* The current {@link KeyguardScreen} will use this to communicate back to us.
*/
@@ -147,6 +144,11 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
//Also true if we've activated a phone call, either emergency dialing or incoming
//This resets when the phone is turned off with no current call
private boolean mHasOverlay;
+ //True if a dialog is currently displaying on top of this window
+ //Unlike other overlays, this does not close with a power button cycle
+ private boolean mHasDialog = false;
+ //True if this device is currently plugged in
+ private boolean mPluggedIn;
/**
@@ -309,6 +311,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
mLockPatternUtils = lockPatternUtils;
mWindowController = controller;
mHasOverlay = false;
+ mPluggedIn = mUpdateMonitor.isDevicePluggedIn();
+ mScreenOn = ((PowerManager)context.getSystemService(Context.POWER_SERVICE)).isScreenOn();
mUpdateMonitor.registerInfoCallback(this);
@@ -370,7 +374,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_EMERGENCY_DIALER_TIMEOUT);
}
- // FaceLock must be stopped if it is running
+ // FaceLock must be stopped if it is running when emergency call is pressed
stopAndUnbindFromFaceLock();
pokeWakelock(EMERGENCY_CALL_TIMEOUT);
@@ -459,7 +463,6 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
}
public void reportSuccessfulUnlockAttempt() {
- mFailedFaceUnlockAttempts = 0;
mLockPatternUtils.reportSuccessfulPasswordAttempt();
}
};
@@ -557,7 +560,8 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
if (DEBUG) Log.d(TAG, "screen off");
mScreenOn = false;
mForgotPattern = false;
- mHasOverlay = mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
+ mHasOverlay = mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE ||
+ mHasDialog;
// Emulate activity life-cycle for both lock and unlock screen.
if (mLockScreen != null) {
@@ -577,22 +581,26 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
* FaceLock, but only if we're not dealing with a call
*/
private void activateFaceLockIfAble() {
- final boolean tooManyFaceUnlockTries =
- (mFailedFaceUnlockAttempts >= FAILED_FACE_UNLOCK_ATTEMPTS_BEFORE_BACKUP);
+ final boolean tooManyFaceUnlockTries = mUpdateMonitor.getMaxFaceUnlockAttemptsReached();
final int failedBackupAttempts = mUpdateMonitor.getFailedAttempts();
final boolean backupIsTimedOut =
(failedBackupAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT);
if (tooManyFaceUnlockTries) Log.i(TAG, "tooManyFaceUnlockTries: " + tooManyFaceUnlockTries);
if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE
+ && usingFaceLock()
&& !mHasOverlay
&& !tooManyFaceUnlockTries
&& !backupIsTimedOut) {
bindToFaceLock();
+
// Show FaceLock area, but only for a little bit so lockpattern will become visible if
// FaceLock fails to start or crashes
- if (usingFaceLock()) {
- showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
- }
+ showFaceLockAreaWithTimeout(FACELOCK_VIEW_AREA_SERVICE_TIMEOUT);
+
+ // When switching between portrait and landscape view while FaceLock is running, the
+ // screen will eventually go dark unless we poke the wakelock when FaceLock is
+ // restarted
+ mKeyguardScreenCallback.pokeWakelock();
} else {
hideFaceLockArea();
}
@@ -647,8 +655,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
mHasOverlay = true;
stopAndUnbindFromFaceLock();
hideFaceLockArea();
- } else if (runFaceLock) {
- activateFaceLockIfAble();
+ } else {
+ mHasDialog = false;
+ if (runFaceLock) activateFaceLockIfAble();
}
}
@@ -718,10 +727,19 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
post(mRecreateRunnable);
}
- //Ignore these events; they are implemented only because they come from the same interface
+ /** When somebody plugs in or unplugs the device, we don't want to display faceunlock */
@Override
- public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel)
- {}
+ public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) {
+ mHasOverlay |= mPluggedIn != pluggedIn;
+ mPluggedIn = pluggedIn;
+ //If it's already running, don't close it down: the unplug didn't start it
+ if (!mFaceLockServiceRunning) {
+ stopAndUnbindFromFaceLock();
+ hideFaceLockArea();
+ }
+ }
+
+ //Ignore these events; they are implemented only because they come from the same interface
@Override
public void onTimeChanged() {}
@Override
@@ -1049,6 +1067,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
}
private void showDialog(String title, String message) {
+ mHasDialog = true;
final AlertDialog dialog = new AlertDialog.Builder(mContext)
.setTitle(title)
.setMessage(message)
@@ -1292,8 +1311,11 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
}
if (mFaceLockAreaView != null) {
+ int[] faceLockPosition;
+ faceLockPosition = new int[2];
+ mFaceLockAreaView.getLocationInWindow(faceLockPosition);
startFaceLock(mFaceLockAreaView.getWindowToken(),
- mFaceLockAreaView.getLeft(), mFaceLockAreaView.getTop(),
+ faceLockPosition[0], faceLockPosition[1],
mFaceLockAreaView.getWidth(), mFaceLockAreaView.getHeight());
}
}
@@ -1311,14 +1333,14 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
};
// Tells the FaceLock service to start displaying its UI and perform recognition
- public void startFaceLock(IBinder windowToken, int x, int y, int h, int w)
+ public void startFaceLock(IBinder windowToken, int x, int y, int w, int h)
{
if (usingFaceLock()) {
synchronized (mFaceLockServiceRunningLock) {
if (!mFaceLockServiceRunning) {
if (DEBUG) Log.d(TAG, "Starting FaceLock");
try {
- mFaceLockService.startUi(windowToken, x, y, h, w);
+ mFaceLockService.startUi(windowToken, x, y, w, h);
} catch (RemoteException e) {
Log.e(TAG, "Caught exception starting FaceLock: " + e.toString());
return;
@@ -1360,7 +1382,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
public void unlock() {
if (DEBUG) Log.d(TAG, "FaceLock unlock()");
showFaceLockArea(); // Keep fallback covered
- stopFaceLock();
+ stopAndUnbindFromFaceLock();
mKeyguardScreenCallback.keyguardDone(true);
mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
@@ -1372,7 +1394,7 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
public void cancel() {
if (DEBUG) Log.d(TAG, "FaceLock cancel()");
hideFaceLockArea(); // Expose fallback
- stopFaceLock();
+ stopAndUnbindFromFaceLock();
mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
}
@@ -1381,9 +1403,9 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
@Override
public void reportFailedAttempt() {
if (DEBUG) Log.d(TAG, "FaceLock reportFailedAttempt()");
- mFailedFaceUnlockAttempts++;
+ mUpdateMonitor.reportFailedFaceUnlockAttempt();
hideFaceLockArea(); // Expose fallback
- stopFaceLock();
+ stopAndUnbindFromFaceLock();
mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0b223c1..468f0d5 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -45,6 +45,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.LocalPowerManager;
+import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
@@ -61,7 +62,6 @@ import com.android.internal.app.ShutdownThread;
import com.android.internal.policy.PolicyManager;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.telephony.ITelephony;
-import com.android.internal.view.BaseInputHandler;
import com.android.internal.widget.PointerLocationView;
import android.util.DisplayMetrics;
@@ -75,8 +75,8 @@ import android.view.IApplicationToken;
import android.view.IWindowManager;
import android.view.InputChannel;
import android.view.InputDevice;
-import android.view.InputQueue;
-import android.view.InputHandler;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -164,6 +164,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
+ // Should screen savers use their own timeout, or the SCREEN_OFF_TIMEOUT?
+ static final boolean SEPARATE_TIMEOUT_FOR_SCREEN_SAVER = false;
+
static final int LONG_PRESS_POWER_NOTHING = 0;
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
@@ -316,7 +319,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mSystemReady;
boolean mSystemBooted;
boolean mHdmiPlugged;
- int mUiMode = Configuration.UI_MODE_TYPE_NORMAL;
+ int mUiMode;
int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
int mLidOpenRotation;
int mCarDockRotation;
@@ -348,25 +351,32 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowState mFocusedWindow;
IApplicationToken mFocusedApp;
- private final InputHandler mPointerLocationInputHandler = new BaseInputHandler() {
+ final class PointerLocationInputEventReceiver extends InputEventReceiver {
+ public PointerLocationInputEventReceiver(InputChannel inputChannel, Looper looper) {
+ super(inputChannel, looper);
+ }
+
@Override
- public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
+ public void onInputEvent(InputEvent event) {
boolean handled = false;
try {
- if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ if (event instanceof MotionEvent
+ && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ final MotionEvent motionEvent = (MotionEvent)event;
synchronized (mLock) {
if (mPointerLocationView != null) {
- mPointerLocationView.addPointerEvent(event);
+ mPointerLocationView.addPointerEvent(motionEvent);
handled = true;
}
}
}
} finally {
- finishedCallback.finished(handled);
+ finishInputEvent(event, handled);
}
}
- };
-
+ }
+ PointerLocationInputEventReceiver mPointerLocationInputEventReceiver;
+
// The current size of the screen; really; (ir)regardless of whether the status
// bar can be hidden or not
int mUnrestrictedScreenLeft, mUnrestrictedScreenTop;
@@ -426,6 +436,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mLockScreenTimeout;
boolean mLockScreenTimerActive;
+ // visual screen saver support
+ int mScreenSaverTimeout = 0;
+ boolean mScreenSaverEnabledByUser = false;
+ boolean mScreenSaverMayRun = true; // false if a wakelock is held
+ boolean mPluggedIn;
+
// Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.)
int mEndcallBehavior;
@@ -488,6 +504,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
resolver.registerContentObserver(Settings.System.getUriFor(
"fancy_rotation_anim"), false, this);
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.SCREENSAVER_ENABLED), false, this);
+ if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ "screensaver_timeout"), false, this);
+ } // otherwise SCREEN_OFF_TIMEOUT will do nicely
updateSettings();
}
@@ -771,6 +793,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
settingsObserver.observe();
mShortcutManager = new ShortcutManager(context, mHandler);
mShortcutManager.observe();
+ mUiMode = context.getResources().getInteger(
+ com.android.internal.R.integer.config_defaultUiModeType);
mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -816,6 +840,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Intent.EXTRA_DOCK_STATE_UNDOCKED);
}
+ // watch the plug to know whether to trigger the screen saver
+ filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ intent = context.registerReceiver(mPowerReceiver, filter);
+ if (intent != null) {
+ mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
+ }
+
mVibrator = new Vibrator();
mLongPressVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_longPressVibePattern);
@@ -964,6 +996,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHasSoftInput = hasSoftInput;
updateRotation = true;
}
+
+ mScreenSaverEnabledByUser = 0 != Settings.Secure.getInt(resolver,
+ Settings.Secure.SCREENSAVER_ENABLED, 1);
+
+ if (SEPARATE_TIMEOUT_FOR_SCREEN_SAVER) {
+ mScreenSaverTimeout = Settings.Secure.getInt(resolver,
+ "screensaver_timeout", 0);
+ } else {
+ mScreenSaverTimeout = Settings.System.getInt(resolver,
+ Settings.System.SCREEN_OFF_TIMEOUT, 0);
+ if (mScreenSaverTimeout > 0) {
+ // We actually want to activate the screensaver just before the
+ // power manager's screen timeout
+ mScreenSaverTimeout -= 5000;
+ }
+ }
+ updateScreenSaverTimeoutLocked();
}
if (updateRotation) {
updateRotation(true);
@@ -987,9 +1036,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mPointerLocationInputChannel == null) {
try {
mPointerLocationInputChannel =
- mWindowManager.monitorInput("PointerLocationView");
- InputQueue.registerInputChannel(mPointerLocationInputChannel,
- mPointerLocationInputHandler, mHandler.getLooper().getQueue());
+ mWindowManager.monitorInput("PointerLocationView");
+ mPointerLocationInputEventReceiver =
+ new PointerLocationInputEventReceiver(
+ mPointerLocationInputChannel, mHandler.getLooper());
} catch (RemoteException ex) {
Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
ex);
@@ -997,8 +1047,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
if (removeView != null) {
+ if (mPointerLocationInputEventReceiver != null) {
+ mPointerLocationInputEventReceiver.dispose();
+ mPointerLocationInputEventReceiver = null;
+ }
if (mPointerLocationInputChannel != null) {
- InputQueue.unregisterInputChannel(mPointerLocationInputChannel);
mPointerLocationInputChannel.dispose();
mPointerLocationInputChannel = null;
}
@@ -1829,13 +1882,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* to determine when the nav bar should be shown and prevent applications from
* receiving those touches.
*/
- final InputHandler mHideNavInputHandler = new BaseInputHandler() {
+ final class HideNavInputEventReceiver extends InputEventReceiver {
+ public HideNavInputEventReceiver(InputChannel inputChannel, Looper looper) {
+ super(inputChannel, looper);
+ }
+
@Override
- public void handleMotion(MotionEvent event, InputQueue.FinishedCallback finishedCallback) {
+ public void onInputEvent(InputEvent event) {
boolean handled = false;
try {
- if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ if (event instanceof MotionEvent
+ && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+ final MotionEvent motionEvent = (MotionEvent)event;
+ if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
// When the user taps down, we re-show the nav bar.
boolean changed = false;
synchronized (mLock) {
@@ -1872,9 +1931,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
} finally {
- finishedCallback.finished(handled);
+ finishInputEvent(event, handled);
}
}
+ }
+ final InputEventReceiver.Factory mHideNavInputEventReceiverFactory =
+ new InputEventReceiver.Factory() {
+ @Override
+ public InputEventReceiver createInputEventReceiver(
+ InputChannel inputChannel, Looper looper) {
+ return new HideNavInputEventReceiver(inputChannel, looper);
+ }
};
@Override
@@ -1938,7 +2005,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
} else if (mHideNavFakeWindow == null) {
mHideNavFakeWindow = mWindowManagerFuncs.addFakeWindow(
- mHandler.getLooper(), mHideNavInputHandler,
+ mHandler.getLooper(), mHideNavInputEventReceiverFactory,
"hidden nav", WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER,
0, false, false, true);
}
@@ -2721,6 +2788,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
}
+ if (keyCode == KeyEvent.KEYCODE_POWER) {
+ policyFlags |= WindowManagerPolicy.FLAG_WAKE;
+ }
+ final boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
+ | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
+
// Basic policy based on screen state and keyguard.
// FIXME: This policy isn't quite correct. We shouldn't care whether the screen
// is on or off, really. We should care about whether the device is in an
@@ -2730,16 +2803,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// the device some other way (which is why we have an exemption here for injected
// events).
int result;
- if (isScreenOn || isInjected) {
+ if (isScreenOn || (isInjected && !isWakeKey)) {
// When the screen is on or if the key is injected pass the key to the application.
result = ACTION_PASS_TO_USER;
} else {
// When the screen is off and the key is not injected, determine whether
// to wake the device but don't pass the key to the application.
result = 0;
-
- final boolean isWakeKey = (policyFlags
- & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
if (down && isWakeKey) {
if (keyguardActive) {
// If the keyguard is showing, let it decide what to do with the wake key.
@@ -3021,6 +3091,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
+ BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
+ mPluggedIn = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
+ if (localLOGV) Log.v(TAG, "BATTERY_CHANGED: " + intent + " plugged=" + mPluggedIn);
+ }
+ }
+ };
+
/** {@inheritDoc} */
public void screenTurnedOff(int why) {
EventLog.writeEvent(70000, 0);
@@ -3032,6 +3111,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
synchronized (mLock) {
updateOrientationListenerLp();
updateLockScreenTimeout();
+ updateScreenSaverTimeoutLocked();
}
}
@@ -3078,6 +3158,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mScreenOnEarly = true;
updateOrientationListenerLp();
updateLockScreenTimeout();
+ updateScreenSaverTimeoutLocked();
}
}
@@ -3476,6 +3557,85 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
}
}
+
+ synchronized (mLock) {
+ // Only posts messages; holds no additional locks.
+ updateScreenSaverTimeoutLocked();
+ }
+ }
+
+ Runnable mScreenSaverActivator = new Runnable() {
+ public void run() {
+ if (!(mScreenSaverMayRun && mScreenOnEarly)) {
+ Log.w(TAG, "mScreenSaverActivator ran, but the screensaver should not be showing. Who's driving this thing?");
+ return;
+ }
+ if (!mPluggedIn) {
+ if (localLOGV) Log.v(TAG, "mScreenSaverActivator: not running screen saver when not plugged in");
+ return;
+ }
+ // Quick fix for automation tests.
+ // The correct fix is to move this triggering logic to PowerManager, where more complete
+ // information about wakelocks (including StayOnWhilePluggedIn) is available.
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+ BatteryManager.BATTERY_PLUGGED_AC) != 0) {
+ Log.v(TAG, "mScreenSaverActivator: not running screen saver when STAY_ON_WHILE_PLUGGED_IN");
+ return;
+ }
+
+ if (localLOGV) Log.v(TAG, "mScreenSaverActivator entering dreamland");
+
+ try {
+ String component = Settings.Secure.getString(
+ mContext.getContentResolver(), Settings.Secure.SCREENSAVER_COMPONENT);
+ if (component == null) {
+ component = mContext.getResources().getString(R.string.config_defaultDreamComponent);
+ }
+ if (component != null) {
+ // dismiss the notification shade, recents, etc.
+ mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT));
+
+ ComponentName cn = ComponentName.unflattenFromString(component);
+ Intent intent = new Intent(Intent.ACTION_MAIN)
+ .setComponent(cn)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+ | Intent.FLAG_ACTIVITY_NO_USER_ACTION
+ | Intent.FLAG_FROM_BACKGROUND
+ | Intent.FLAG_ACTIVITY_NO_HISTORY
+ );
+ mContext.startActivity(intent);
+ } else {
+ Log.e(TAG, "Couldn't start screen saver: none selected");
+ }
+ } catch (android.content.ActivityNotFoundException exc) {
+ // no screensaver? give up
+ Log.e(TAG, "Couldn't start screen saver: none installed");
+ }
+ }
+ };
+
+ // Must call while holding mLock
+ private void updateScreenSaverTimeoutLocked() {
+ if (mScreenSaverActivator == null) return;
+
+ mHandler.removeCallbacks(mScreenSaverActivator);
+ if (mScreenSaverEnabledByUser && mScreenSaverMayRun && mScreenOnEarly && mScreenSaverTimeout > 0) {
+ if (localLOGV)
+ Log.v(TAG, "scheduling screensaver for " + mScreenSaverTimeout + "ms from now");
+ mHandler.postDelayed(mScreenSaverActivator, mScreenSaverTimeout);
+ } else {
+ if (localLOGV) {
+ if (!mScreenSaverEnabledByUser || mScreenSaverTimeout == 0)
+ Log.v(TAG, "screen saver disabled by user");
+ else if (!mScreenOnEarly)
+ Log.v(TAG, "screen saver disabled while screen off");
+ else
+ Log.v(TAG, "screen saver disabled by wakelock");
+ }
+ }
}
Runnable mScreenLockTimeout = new Runnable() {
@@ -3681,6 +3841,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
public void screenOnStartedLw() {
+ // The window manager has just grabbed a wake lock. This is our cue to disable the screen
+ // saver.
+ synchronized (mLock) {
+ mScreenSaverMayRun = false;
+ }
}
public void screenOnStoppedLw() {
@@ -3689,6 +3854,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
long curTime = SystemClock.uptimeMillis();
mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT);
}
+
+ synchronized (mLock) {
+ // even if the keyguard is up, now that all the wakelocks have been released, we
+ // should re-enable the screen saver
+ mScreenSaverMayRun = true;
+ updateScreenSaverTimeoutLocked();
+ }
}
}