Merge commit 'korg/cupcake'

This commit is contained in:
The Android Open Source Project
2009-03-27 15:31:11 -07:00
4 changed files with 155 additions and 66 deletions

View File

@@ -22,7 +22,9 @@ import android.media.AudioManager;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.view.View;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.util.AttributeSet;
/**
* Base class for keyguard views. {@link #reset} is where you should
@@ -41,6 +43,13 @@ public abstract class KeyguardViewBase extends FrameLayout {
public KeyguardViewBase(Context context) {
super(context);
// drop shadow below status bar in keyguard too
mForegroundInPadding = false;
setForegroundGravity(Gravity.FILL_HORIZONTAL | Gravity.TOP);
setForeground(
context.getResources().getDrawable(
com.android.internal.R.drawable.title_bar_shadow));
}
// used to inject callback

View File

@@ -16,11 +16,14 @@
package com.android.internal.policy.impl;
import com.android.internal.telephony.SimCard;
import com.android.internal.widget.LockPatternUtils;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import static android.app.StatusBarManager.DISABLE_NONE;
import static android.app.StatusBarManager.DISABLE_EXPAND;
import static android.app.StatusBarManager.DISABLE_NONE;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -30,15 +33,13 @@ import android.os.LocalPowerManager;
import android.os.Message;
import android.os.PowerManager;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.util.Config;
import android.util.Log;
import android.util.EventLog;
import android.util.Log;
import android.view.KeyEvent;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
import com.android.internal.telephony.SimCard;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.widget.LockPatternUtils;
/**
* Mediates requests related to the keyguard. This includes queries about the
@@ -203,6 +204,8 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
private boolean mKeyboardOpen = false;
private boolean mScreenOn = false;
/**
* we send this intent when the keyguard is dismissed.
*/
@@ -232,8 +235,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
IntentFilter filter = new IntentFilter();
filter.addAction(DELAYED_KEYGUARD_ACTION);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
context.registerReceiver(mBroadCastReceiver, filter);
mAlarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
@@ -274,6 +276,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
*/
public void onScreenTurnedOff(int why) {
synchronized (this) {
mScreenOn = false;
if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")");
if (mExitSecureCallback != null) {
@@ -310,6 +313,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
*/
public void onScreenTurnedOn() {
synchronized (this) {
mScreenOn = true;
mDelayedShowingSequence++;
if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence);
notifyScreenOnLocked();
@@ -436,6 +440,16 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
// if another app is disabling us, don't show
if (!mExternallyEnabled) {
if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled");
// note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes
// for an occasional ugly flicker in this situation:
// 1) receive a call with the screen on (no keyguard) or make a call
// 2) screen times out
// 3) user hits key to turn screen back on
// instead, we reenable the keyguard when we know the screen is off and the call
// ends (see the broadcast receiver below)
// TODO: clean this up when we have better support at the window manager level
// for apps that wish to be on top of the keyguard
return;
}
@@ -612,6 +626,19 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
if (mDelayedShowingSequence == sequence) {
doKeyguard();
}
} else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)
&& TelephonyManager.EXTRA_STATE_IDLE.equals(intent.getStringExtra(
TelephonyManager.EXTRA_STATE)) // call ending
&& !mScreenOn // screen off
&& mExternallyEnabled) { // not disabled by any app
// note: this is a way to gracefully reenable the keyguard when the call
// ends and the screen is off without always reenabling the keyguard
// each time the screen turns off while in call (and having an occasional ugly
// flicker while turning back on the screen and disabling the keyguard again).
if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the "
+ "keyguard is showing");
doKeyguard();
}
}
};

View File

@@ -101,6 +101,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final String TAG = "WindowManager";
static final boolean DEBUG = false;
static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
static final boolean DEBUG_LAYOUT = false;
static final boolean SHOW_STARTING_ANIMATIONS = true;
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
@@ -165,7 +166,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Handler mHandler;
boolean mLidOpen;
int mSensorRotation = -1;
boolean mScreenOn = false;
boolean mOrientationSensorEnabled = false;
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -206,6 +206,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int ENDCALL_SLEEPS = 0x2;
static final int DEFAULT_ENDCALL_BEHAVIOR = ENDCALL_SLEEPS;
int mEndcallBehavior;
// Nothing to see here, move along...
int mFancyRotationAnimation;
ShortcutManager mShortcutManager;
PowerManager.WakeLock mBroadcastWakeLock;
@@ -225,13 +228,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Settings.System.ACCELEROMETER_ROTATION), false, this);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
resolver.registerContentObserver(Settings.System.getUriFor(
"fancy_rotation_anim"), false, this);
update();
}
@Override public void onChange(boolean selfChange) {
update();
try {
mWindowManager.setRotation(USE_LAST_ROTATION, false);
mWindowManager.setRotation(USE_LAST_ROTATION, false,
mFancyRotationAnimation);
} catch (RemoteException e) {
// Ignore
}
@@ -242,6 +248,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
synchronized (mLock) {
mEndcallBehavior = Settings.System.getInt(resolver,
Settings.System.END_BUTTON_BEHAVIOR, DEFAULT_ENDCALL_BEHAVIOR);
mFancyRotationAnimation = Settings.System.getInt(resolver,
"fancy_rotation_anim", 0) != 0 ? 0x80 : 0;
int accelerometerDefault = Settings.System.getInt(resolver,
Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION);
if (mAccelerometerDefault != accelerometerDefault) {
@@ -253,7 +261,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean hasSoftInput = imId != null && imId.length() > 0;
if (mHasSoftInput != hasSoftInput) {
mHasSoftInput = hasSoftInput;
updateRotation();
updateRotation(0);
}
}
}
@@ -267,41 +275,41 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void onOrientationChanged(int rotation) {
// Send updates based on orientation value
if (rotation != mSensorRotation) {
if(localLOGV) Log.i(TAG, "onOrientationChanged, rotation changed from "+rotation+" to "+mSensorRotation);
// Update window manager. The lid rotation hasn't changed,
// but we want it to re-evaluate the final rotation in case
// it needs to call back and get the sensor orientation.
mSensorRotation = rotation;
try {
mWindowManager.setRotation(rotation, false);
} catch (RemoteException e) {
// Ignore
}
if (true) Log.i(TAG, "onOrientationChanged, rotation changed to " +rotation);
try {
mWindowManager.setRotation(rotation, false,
mFancyRotationAnimation);
} catch (RemoteException e) {
// Ignore
}
}
}
MyOrientationListener mOrientationListener;
boolean useSensorForOrientationLp() {
if(mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
boolean useSensorForOrientationLp(int appOrientation) {
if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
return true;
}
if (mAccelerometerDefault != 0 && (
mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_USER ||
mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) {
appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER ||
appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) {
return true;
}
return false;
}
/*
* We always let the sensor be switched on by default except when
* the user has explicitly disabled sensor based rotation or when the
* screen is switched off.
*/
boolean needSensorRunningLp() {
if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
// If the application has explicitly requested to follow the
// orientation, then we need to turn the sensor or.
return true;
}
if (mAccelerometerDefault != 0) {
if (mAccelerometerDefault == 0) {
// If the setting for using the sensor by default is enabled, then
// we will always leave it on. Note that the user could go to
// a window that forces an orientation that does not use the
@@ -310,9 +318,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// orientation for a little bit, which can cause orientation
// changes to lag, so we'd like to keep it always on. (It will
// still be turned off when the screen is off.)
return true;
return false;
}
return false;
return true;
}
/*
@@ -343,9 +351,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (!mOrientationSensorEnabled) {
mOrientationListener.enable();
if(localLOGV) Log.i(TAG, "Enabling listeners");
// We haven't had the sensor on, so don't yet know
// the rotation.
mSensorRotation = -1;
mOrientationSensorEnabled = true;
}
}
@@ -354,7 +359,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (disable && mOrientationSensorEnabled) {
mOrientationListener.disable();
if(localLOGV) Log.i(TAG, "Disabling listeners");
mSensorRotation = -1;
mOrientationSensorEnabled = false;
}
}
@@ -992,6 +996,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// If the status bar is hidden, we don't want to cause
// windows behind it to scroll.
mDockTop = mContentTop = mCurTop = mStatusBar.getFrameLw().bottom;
if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mDockBottom="
+ mDockBottom + " mContentBottom="
+ mContentBottom + " mCurBottom=" + mCurBottom);
}
}
}
@@ -1152,11 +1159,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {
df.right = df.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000;
}
if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle()
+ ": sim=#" + Integer.toHexString(sim)
+ " pf=" + pf.toShortString() + " df=" + df.toShortString()
+ " cf=" + cf.toShortString() + " vf=" + vf.toShortString());
if (false) {
if ("com.google.android.youtube".equals(attrs.packageName)
&& attrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
if (true || localLOGV) Log.v(TAG, "Computing frame of " + win +
": pf=" + pf.toShortString() + " df=" + df.toShortString()
": sim=#" + Integer.toHexString(sim)
+ " pf=" + pf.toShortString() + " df=" + df.toShortString()
+ " cf=" + cf.toShortString() + " vf=" + vf.toShortString());
}
}
@@ -1176,6 +1189,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mCurBottom > top) {
mCurBottom = top;
}
if (DEBUG_LAYOUT) Log.v(TAG, "Input method: mDockBottom="
+ mDockBottom + " mContentBottom="
+ mContentBottom + " mCurBottom=" + mCurBottom);
}
}
@@ -1252,7 +1268,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (event.keycode == 0) {
// lid changed state
mLidOpen = event.value == 0;
updateRotation();
updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
if (keyguardIsShowingTq()) {
if (mLidOpen) {
// only do this if it's opening -- closing the device shouldn't turn it
@@ -1602,9 +1618,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
public void screenTurnedOff(int why) {
EventLog.writeEvent(70000, 0);
mKeyguardMediator.onScreenTurnedOff(why);
synchronized (mLock) {
EventLog.writeEvent(70000, 0);
mKeyguardMediator.onScreenTurnedOff(why);
mScreenOn = false;
updateOrientationListenerLp();
}
@@ -1612,9 +1628,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
public void screenTurnedOn() {
EventLog.writeEvent(70000, 1);
mKeyguardMediator.onScreenTurnedOn();
synchronized (mLock) {
EventLog.writeEvent(70000, 1);
mKeyguardMediator.onScreenTurnedOn();
mScreenOn = true;
updateOrientationListenerLp();
}
@@ -1682,9 +1698,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mLidOpen) {
return Surface.ROTATION_90;
} else {
if (useSensorForOrientationLp()) {
if (useSensorForOrientationLp(orientation)) {
// If the user has enabled auto rotation by default, do it.
return mSensorRotation >= 0 ? mSensorRotation : lastRotation;
int curRotation = mOrientationListener.getCurrentRotation();
return curRotation >= 0 ? curRotation : lastRotation;
}
return Surface.ROTATION_0;
}
@@ -1727,10 +1744,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
public void enableScreenAfterBoot() {
readLidState();
updateRotation();
updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
}
void updateRotation() {
void updateRotation(int animFlags) {
mPowerManager.setKeyboardVisibility(mLidOpen);
int rotation= Surface.ROTATION_0;
if (mLidOpen) {
@@ -1740,7 +1757,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
//if lid is closed orientation will be portrait
try {
//set orientation on WindowManager
mWindowManager.setRotation(rotation, true);
mWindowManager.setRotation(rotation, true,
mFancyRotationAnimation | animFlags);
} catch (RemoteException e) {
// Ignore
}

View File

@@ -19,6 +19,8 @@ package com.android.internal.policy.impl;
import android.app.ProgressDialog;
import android.app.AlertDialog;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.IBluetoothDevice;
import android.content.Context;
import android.content.DialogInterface;
import android.os.RemoteException;
@@ -35,9 +37,12 @@ final class ShutdownThread extends Thread {
private static final String TAG = "ShutdownThread";
private static final int MAX_NUM_PHONE_STATE_READS = 16;
private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500;
private static final ITelephony sPhone =
private static final ITelephony sPhone =
ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
private static final IBluetoothDevice sBluetooth =
IBluetoothDevice.Stub.asInterface(ServiceManager.getService(Context.BLUETOOTH_SERVICE));
// state tracking
private static Object sIsStartedGuard = new Object();
private static boolean sIsStarted = false;
@@ -62,7 +67,7 @@ final class ShutdownThread extends Thread {
return;
}
}
Log.d(TAG, "Notifying thread to start radio shutdown");
if (confirm) {
@@ -106,31 +111,61 @@ final class ShutdownThread extends Thread {
sInstance.start();
}
/**
* Makes sure we handle the shutdown gracefully.
* Shuts off power regardless of radio state if the alloted time has passed.
/**
* Makes sure we handle the shutdown gracefully.
* Shuts off power regardless of radio and bluetooth state if the alloted time has passed.
*/
public void run() {
//shutdown the phone radio if possible.
if (sPhone != null) {
try {
//shutdown radio
sPhone.setRadio(false);
boolean bluetoothOff;
boolean radioOff;
for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++){
// poll radio up to 64 times, with a 0.5 sec delay between each call,
// totaling 32 sec.
if (!sPhone.isRadioOn()) {
Log.d(TAG, "Radio shutdown complete.");
break;
}
SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
}
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException caught from failed radio shutdown.", ex);
try {
bluetoothOff = sBluetooth == null ||
sBluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF;
if (!bluetoothOff) {
sBluetooth.disable(false); // disable but don't persist new state
}
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
bluetoothOff = true;
}
try {
radioOff = sPhone == null || !sPhone.isRadioOn();
if (!radioOff) {
sPhone.setRadio(false);
}
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during radio shutdown", ex);
radioOff = true;
}
// Wait a max of 32 seconds for clean shutdown
for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++) {
if (!bluetoothOff) {
try {
bluetoothOff =
sBluetooth.getBluetoothState() == BluetoothDevice.BLUETOOTH_STATE_OFF;
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during bluetooth shutdown", ex);
bluetoothOff = true;
}
}
if (!radioOff) {
try {
radioOff = !sPhone.isRadioOn();
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException during radio shutdown", ex);
radioOff = true;
}
}
if (radioOff && bluetoothOff) {
Log.d(TAG, "Radio and Bluetooth shutdown complete.");
break;
}
SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC);
}
//shutdown power
Log.d(TAG, "Shutting down power.");
Power.shutdown();