summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
authorSteve Kondik <shade@chemlab.org>2011-12-16 14:45:56 -0800
committerSteve Kondik <shade@chemlab.org>2011-12-16 14:45:56 -0800
commitbec96948c8ea41c022fe7e68ccdfdaa1a1128871 (patch)
treed18f611794386ae7058f3a4b66e2c867bf14c70a /policy
parent7e350ef016b80203bc1b1c275729fe8c441a7728 (diff)
parent8b6ed2d17d5e7e47944026679c9cba66611ab27f (diff)
downloadframeworks_base-bec96948c8ea41c022fe7e68ccdfdaa1a1128871.zip
frameworks_base-bec96948c8ea41c022fe7e68ccdfdaa1a1128871.tar.gz
frameworks_base-bec96948c8ea41c022fe7e68ccdfdaa1a1128871.tar.bz2
Merge branch 'ics-mr1' of https://android.googlesource.com/platform/frameworks/base into aosp
Conflicts: core/res/res/values/strings.xml policy/src/com/android/internal/policy/impl/GlobalActions.java services/java/com/android/server/WifiService.java services/sensorservice/SensorDevice.cpp telephony/java/com/android/internal/telephony/RIL.java Change-Id: I89ec56d5ff282a2eb879ca40fb6d74ebcf752837
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/GlobalActions.java265
-rw-r--r--policy/src/com/android/internal/policy/impl/IconUtilities.java10
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java61
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java137
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewBase.java40
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewManager.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java18
-rw-r--r--policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java23
-rw-r--r--policy/src/com/android/internal/policy/impl/LockScreen.java8
-rw-r--r--policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java16
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java44
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java406
-rw-r--r--policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java50
-rw-r--r--policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java37
-rw-r--r--policy/src/com/android/internal/policy/impl/SimUnlockScreen.java37
15 files changed, 675 insertions, 478 deletions
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index ed1fa76..dfece30 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -67,13 +67,15 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private static final String TAG = "GlobalActions";
+ private static final boolean SHOW_SILENT_TOGGLE = true;
+
private final Context mContext;
private final AudioManager mAudioManager;
private ArrayList<Action> mItems;
private AlertDialog mDialog;
- private ToggleAction mSilentModeToggle;
+ private SilentModeAction mSilentModeAction;
private ToggleAction mAirplaneModeOn;
private MyAdapter mAdapter;
@@ -124,39 +126,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
* @return A new dialog.
*/
private AlertDialog createDialog() {
- mSilentModeToggle = new ToggleAction(
- R.drawable.ic_audio_vol_mute,
- R.drawable.ic_audio_vol,
- R.string.global_action_toggle_silent_mode,
- R.string.global_action_silent_mode_on_status,
- R.string.global_action_silent_mode_off_status) {
-
- void willCreate() {
- mEnabledIconResId = (Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.VIBRATE_IN_SILENT, 1) == 1)
- ? R.drawable.ic_audio_ring_notif_vibrate
- : R.drawable.ic_audio_vol_mute;
- }
-
- void onToggle(boolean on) {
- if (on) {
- mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.VIBRATE_IN_SILENT, 1) == 1)
- ? AudioManager.RINGER_MODE_VIBRATE
- : AudioManager.RINGER_MODE_SILENT);
- } else {
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
- }
- }
-
- public boolean showDuringKeyguard() {
- return true;
- }
-
- public boolean showBeforeProvisioning() {
- return false;
- }
- };
+ mSilentModeAction = new SilentModeAction(mAudioManager, mHandler);
mAirplaneModeOn = new ToggleAction(
R.drawable.ic_lock_airplane_mode,
@@ -198,65 +168,78 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
};
- mItems = Lists.newArrayList(
- // silent mode
- mSilentModeToggle,
- // next: airplane mode
- mAirplaneModeOn,
- // next: screenshot
- new SinglePressAction(com.android.internal.R.drawable.ic_lock_screenshot, R.string.global_action_screenshot) {
- public void onPress() {
- takeScreenshot();
- }
+ mItems = new ArrayList<Action>();
- public boolean showDuringKeyguard() {
- return true;
- }
+ // first: power off
+ mItems.add(
+ new SinglePressAction(
+ com.android.internal.R.drawable.ic_lock_power_off,
+ R.string.global_action_power_off) {
- public boolean showBeforeProvisioning() {
- return true;
- }
- },
- // next: reboot
- new SinglePressAction(com.android.internal.R.drawable.ic_lock_reboot, R.string.global_action_reboot) {
- public void onPress() {
- ShutdownThread.reboot(mContext, "null", true);
- }
+ public void onPress() {
+ // shutdown by making sure radio and power are handled accordingly.
+ ShutdownThread.shutdown(mContext, true);
+ }
- public boolean showDuringKeyguard() {
- return true;
- }
+ public boolean showDuringKeyguard() {
+ return true;
+ }
- public boolean showBeforeProvisioning() {
- return true;
- }
- },
- // last: power off
- new SinglePressAction(com.android.internal.R.drawable.ic_lock_power_off, R.string.global_action_power_off) {
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ });
- public void onPress() {
- // shutdown by making sure radio and power are handled accordingly.
- ShutdownThread.shutdown(mContext, true);
- }
+ // next: reboot
+ mItems.add(
+ new SinglePressAction(com.android.internal.R.drawable.ic_lock_reboot, R.string.global_action_reboot) {
+ public void onPress() {
+ ShutdownThread.reboot(mContext, "null", true);
+ }
- public boolean showDuringKeyguard() {
- return true;
- }
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ });
+
+ // next: screenshot
+ mItems.add(
+ new SinglePressAction(com.android.internal.R.drawable.ic_lock_screenshot, R.string.global_action_screenshot) {
+ public void onPress() {
+ takeScreenshot();
+ }
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return true;
+ }
+ });
+
+ // next: airplane mode
+ mItems.add(mAirplaneModeOn);
+
+ // last: silent mode
+ if (SHOW_SILENT_TOGGLE) {
+ mItems.add(mSilentModeAction);
+ }
- public boolean showBeforeProvisioning() {
- return true;
- }
- });
mAdapter = new MyAdapter();
final AlertDialog.Builder ab = new AlertDialog.Builder(mContext);
ab.setAdapter(mAdapter, this)
- .setInverseBackgroundForced(true)
- .setTitle(R.string.global_actions);
+ .setInverseBackgroundForced(true);
final AlertDialog dialog = ab.create();
+ dialog.getListView().setItemsCanFocus(true);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
dialog.setOnDismissListener(this);
@@ -349,8 +332,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private void prepareDialog() {
final boolean silentModeOn =
mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
- mSilentModeToggle.updateState(
- silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
mAirplaneModeOn.updateState(mAirplaneState);
mAdapter.notifyDataSetChanged();
if (mKeyguardShowing) {
@@ -358,21 +339,31 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
} else {
mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
}
+
mDialog.setTitle(R.string.global_actions);
+
+ if (SHOW_SILENT_TOGGLE) {
+ IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ mContext.registerReceiver(mRingerModeReceiver, filter);
+ }
}
/** {@inheritDoc} */
public void onDismiss(DialogInterface dialog) {
+ if (SHOW_SILENT_TOGGLE) {
+ mContext.unregisterReceiver(mRingerModeReceiver);
+ }
}
/** {@inheritDoc} */
public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
+ if (!(mAdapter.getItem(which) instanceof SilentModeAction)) {
+ dialog.dismiss();
+ }
mAdapter.getItem(which).onPress();
}
-
/**
* The adapter used for the list within the global actions dialog, taking
* into account whether the keyguard is showing via
@@ -493,9 +484,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
public View create(
Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
- View v = (convertView != null) ?
- convertView :
- inflater.inflate(R.layout.global_actions_item, parent, false);
+ View v = inflater.inflate(R.layout.global_actions_item, parent, false);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -572,27 +561,31 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
LayoutInflater inflater) {
willCreate();
- View v = (convertView != null) ?
- convertView :
- inflater.inflate(R
+ View v = inflater.inflate(R
.layout.global_actions_item, parent, false);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
TextView messageView = (TextView) v.findViewById(R.id.message);
TextView statusView = (TextView) v.findViewById(R.id.status);
+ final boolean enabled = isEnabled();
- messageView.setText(mMessageResId);
+ if (messageView != null) {
+ messageView.setText(mMessageResId);
+ messageView.setEnabled(enabled);
+ }
boolean on = ((mState == State.On) || (mState == State.TurningOn));
- icon.setImageDrawable(context.getResources().getDrawable(
- (on ? mEnabledIconResId : mDisabledIconResid)));
- statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
- statusView.setVisibility(View.VISIBLE);
+ if (icon != null) {
+ icon.setImageDrawable(context.getResources().getDrawable(
+ (on ? mEnabledIconResId : mDisabledIconResid)));
+ icon.setEnabled(enabled);
+ }
- final boolean enabled = isEnabled();
- messageView.setEnabled(enabled);
- statusView.setEnabled(enabled);
- icon.setEnabled(enabled);
+ if (statusView != null) {
+ statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
+ statusView.setVisibility(View.VISIBLE);
+ statusView.setEnabled(enabled);
+ }
v.setEnabled(enabled);
return v;
@@ -630,6 +623,70 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
}
+ private static class SilentModeAction implements Action, View.OnClickListener {
+
+ private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
+
+ private final AudioManager mAudioManager;
+ private final Handler mHandler;
+
+ SilentModeAction(AudioManager audioManager, Handler handler) {
+ mAudioManager = audioManager;
+ mHandler = handler;
+ }
+
+ private int ringerModeToIndex(int ringerMode) {
+ // They just happen to coincide
+ return ringerMode;
+ }
+
+ private int indexToRingerMode(int index) {
+ // They just happen to coincide
+ return index;
+ }
+
+ public View create(Context context, View convertView, ViewGroup parent,
+ LayoutInflater inflater) {
+ View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);
+
+ int selectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());
+ for (int i = 0; i < 3; i++) {
+ View itemView = v.findViewById(ITEM_IDS[i]);
+ itemView.setSelected(selectedIndex == i);
+ // Set up click handler
+ itemView.setTag(i);
+ itemView.setOnClickListener(this);
+ }
+ return v;
+ }
+
+ public void onPress() {
+ }
+
+ public boolean showDuringKeyguard() {
+ return true;
+ }
+
+ public boolean showBeforeProvisioning() {
+ return false;
+ }
+
+ public boolean isEnabled() {
+ return true;
+ }
+
+ void willCreate() {
+ }
+
+ public void onClick(View v) {
+ if (!(v.getTag() instanceof Integer)) return;
+
+ int index = (Integer) v.getTag();
+ mAudioManager.setRingerMode(indexToRingerMode(index));
+ mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);
+ }
+ }
+
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -661,13 +718,27 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
};
+ private BroadcastReceiver mRingerModeReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
+ mHandler.sendEmptyMessage(MESSAGE_REFRESH);
+ }
+ }
+ };
+
private static final int MESSAGE_DISMISS = 0;
+ private static final int MESSAGE_REFRESH = 1;
+ private static final int DIALOG_DISMISS_DELAY = 300; // ms
+
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == MESSAGE_DISMISS) {
if (mDialog != null) {
mDialog.dismiss();
}
+ } else if (msg.what == MESSAGE_REFRESH) {
+ mAdapter.notifyDataSetChanged();
}
}
};
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index 4564f90..e997355 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -38,6 +38,8 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
import android.content.res.Resources;
import android.content.Context;
@@ -74,9 +76,13 @@ final class IconUtilities {
mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2);
mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL));
- mGlowColorPressedPaint.setColor(0xffffc300);
+
+ TypedValue value = new TypedValue();
+ mGlowColorPressedPaint.setColor(context.getTheme().resolveAttribute(
+ android.R.attr.colorPressedHighlight, value, true) ? value.data : 0xffffc300);
mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
- mGlowColorFocusedPaint.setColor(0xffff8e00);
+ mGlowColorFocusedPaint.setColor(context.getTheme().resolveAttribute(
+ android.R.attr.colorFocusedHighlight, value, true) ? value.data : 0xffff8e00);
mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30));
ColorMatrix cm = new ColorMatrix();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
index 6614d79..ee54de1 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java
@@ -91,7 +91,7 @@ class KeyguardStatusViewManager implements OnClickListener {
private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
private Button mEmergencyCallButton;
- private boolean mUnlockDisabledDueToSimState;
+ private boolean mEmergencyButtonEnabledBecauseSimLocked;
// Shadowed text values
private CharSequence mCarrierText;
@@ -101,9 +101,10 @@ class KeyguardStatusViewManager implements OnClickListener {
private CharSequence mOwnerInfoText;
private boolean mShowingStatus;
private KeyguardScreenCallback mCallback;
- private final boolean mShowEmergencyButtonByDefault;
+ private final boolean mEmergencyCallButtonEnabledInScreen;
private CharSequence mPlmn;
private CharSequence mSpn;
+ protected int mPhoneState;
private class TransientTextManager {
private TextView mTextView;
@@ -154,12 +155,20 @@ class KeyguardStatusViewManager implements OnClickListener {
}
};
+ /**
+ *
+ * @param view the containing view of all widgets
+ * @param updateMonitor the update monitor to use
+ * @param lockPatternUtils lock pattern util object
+ * @param callback used to invoke emergency dialer
+ * @param emergencyButtonEnabledInScreen whether emergency button is enabled by default
+ */
public KeyguardStatusViewManager(View view, KeyguardUpdateMonitor updateMonitor,
LockPatternUtils lockPatternUtils, KeyguardScreenCallback callback,
- boolean showEmergencyButtonByDefault) {
+ boolean emergencyButtonEnabledInScreen) {
if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()");
mContainer = view;
- mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
+ mDateFormatString = getContext().getString(R.string.abbrev_wday_month_day_no_year);
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = updateMonitor;
mCallback = callback;
@@ -171,7 +180,7 @@ class KeyguardStatusViewManager implements OnClickListener {
mOwnerInfoView = (TextView) findViewById(R.id.propertyOf);
mTransportView = (TransportControlView) findViewById(R.id.transport);
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
- mShowEmergencyButtonByDefault = showEmergencyButtonByDefault;
+ mEmergencyCallButtonEnabledInScreen = emergencyButtonEnabledInScreen;
// Hide transport control view until we know we need to show it.
if (mTransportView != null) {
@@ -452,12 +461,12 @@ class KeyguardStatusViewManager implements OnClickListener {
*
* @param simState
*/
- private void updateCarrierTextWithSimStatus(State simState) {
+ private void updateCarrierStateWithSimStatus(State simState) {
if (DEBUG) Log.d(TAG, "updateCarrierTextWithSimStatus(), simState = " + simState);
CharSequence carrierText = null;
int carrierHelpTextId = 0;
- mUnlockDisabledDueToSimState = false;
+ mEmergencyButtonEnabledBecauseSimLocked = false;
mStatus = getStatusForIccState(simState);
mSimState = simState;
switch (mStatus) {
@@ -472,39 +481,49 @@ class KeyguardStatusViewManager implements OnClickListener {
break;
case SimMissing:
+ // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
+ // This depends on mPlmn containing the text "Emergency calls only" when the radio
+ // has some connectivity. Otherwise, it should be null or empty and just show
+ // "No SIM card"
carrierText = getContext().getText(R.string.lockscreen_missing_sim_message_short);
+ if (mLockPatternUtils.isEmergencyCallCapable()) {
+ carrierText = makeCarierString(carrierText, mPlmn);
+ }
carrierHelpTextId = R.string.lockscreen_missing_sim_instructions_long;
break;
case SimPermDisabled:
carrierText = getContext().getText(R.string.lockscreen_missing_sim_message_short);
carrierHelpTextId = R.string.lockscreen_permanent_disabled_sim_instructions;
- mUnlockDisabledDueToSimState = true;
+ mEmergencyButtonEnabledBecauseSimLocked = true;
break;
case SimMissingLocked:
carrierText = makeCarierString(mPlmn,
getContext().getText(R.string.lockscreen_missing_sim_message_short));
carrierHelpTextId = R.string.lockscreen_missing_sim_instructions;
- mUnlockDisabledDueToSimState = true;
+ mEmergencyButtonEnabledBecauseSimLocked = true;
break;
case SimLocked:
carrierText = makeCarierString(mPlmn,
getContext().getText(R.string.lockscreen_sim_locked_message));
+ mEmergencyButtonEnabledBecauseSimLocked = true;
break;
case SimPukLocked:
carrierText = makeCarierString(mPlmn,
getContext().getText(R.string.lockscreen_sim_puk_locked_message));
if (!mLockPatternUtils.isPukUnlockScreenEnable()) {
- mUnlockDisabledDueToSimState = true;
+ // This means we're showing the PUK unlock screen
+ mEmergencyButtonEnabledBecauseSimLocked = true;
}
break;
}
setCarrierText(carrierText);
setCarrierHelpText(carrierHelpTextId);
+ updateEmergencyCallButtonState(mPhoneState);
}
private View findViewById(int id) {
@@ -569,9 +588,12 @@ class KeyguardStatusViewManager implements OnClickListener {
private void updateEmergencyCallButtonState(int phoneState) {
if (mEmergencyCallButton != null) {
- boolean showIfCapable = mShowEmergencyButtonByDefault || mUnlockDisabledDueToSimState;
+ boolean enabledBecauseSimLocked =
+ mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked()
+ && mEmergencyButtonEnabledBecauseSimLocked;
+ boolean shown = mEmergencyCallButtonEnabledInScreen || enabledBecauseSimLocked;
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton,
- phoneState, showIfCapable);
+ phoneState, shown);
}
}
@@ -594,7 +616,7 @@ class KeyguardStatusViewManager implements OnClickListener {
public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
mPlmn = plmn;
mSpn = spn;
- updateCarrierTextWithSimStatus(mSimState);
+ updateCarrierStateWithSimStatus(mSimState);
}
public void onRingerModeChanged(int state) {
@@ -602,6 +624,7 @@ class KeyguardStatusViewManager implements OnClickListener {
}
public void onPhoneStateChanged(int phoneState) {
+ mPhoneState = phoneState;
updateEmergencyCallButtonState(phoneState);
}
@@ -618,7 +641,7 @@ class KeyguardStatusViewManager implements OnClickListener {
private SimStateCallback mSimStateCallback = new SimStateCallback() {
public void onSimStateChanged(State simState) {
- updateCarrierTextWithSimStatus(simState);
+ updateCarrierStateWithSimStatus(simState);
}
};
@@ -635,11 +658,13 @@ class KeyguardStatusViewManager implements OnClickListener {
* @return
*/
private static CharSequence makeCarierString(CharSequence plmn, CharSequence spn) {
- if (plmn != null && spn == null) {
- return plmn;
- } else if (plmn != null && spn != null) {
+ final boolean plmnValid = !TextUtils.isEmpty(plmn);
+ final boolean spnValid = !TextUtils.isEmpty(spn);
+ if (plmnValid && spnValid) {
return plmn + "|" + spn;
- } else if (plmn == null && spn != null) {
+ } else if (plmnValid) {
+ return plmn;
+ } else if (spnValid) {
return spn;
} else {
return "";
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 008f5d8..b4b82aa 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -21,11 +21,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
-import static android.os.BatteryManager.BATTERY_STATUS_CHARGING;
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
+import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
+import static android.os.BatteryManager.EXTRA_STATUS;
+import static android.os.BatteryManager.EXTRA_PLUGGED;
+import static android.os.BatteryManager.EXTRA_LEVEL;
+import static android.os.BatteryManager.EXTRA_HEALTH;
import android.media.AudioManager;
-import android.media.IRemoteControlClient;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
@@ -72,9 +75,7 @@ public class KeyguardUpdateMonitor {
private boolean mDeviceProvisioned;
- private int mBatteryLevel;
-
- private int mBatteryStatus;
+ private BatteryStatus mBatteryStatus;
private CharSequence mTelephonyPlmn;
private CharSequence mTelephonySpn;
@@ -109,10 +110,14 @@ public class KeyguardUpdateMonitor {
* the intent and provide a {@link SimCard.State} result.
*/
private static class SimArgs {
-
public final IccCard.State simState;
- private SimArgs(Intent intent) {
+ SimArgs(IccCard.State state) {
+ simState = state;
+ }
+
+ static SimArgs fromIntent(Intent intent) {
+ IccCard.State state;
if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
}
@@ -123,27 +128,28 @@ public class KeyguardUpdateMonitor {
if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
absentReason)) {
- this.simState = IccCard.State.PERM_DISABLED;
+ state = IccCard.State.PERM_DISABLED;
} else {
- this.simState = IccCard.State.ABSENT;
+ state = IccCard.State.ABSENT;
}
} else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
- this.simState = IccCard.State.READY;
+ state = IccCard.State.READY;
} else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
final String lockedReason = intent
.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
- this.simState = IccCard.State.PIN_REQUIRED;
+ state = IccCard.State.PIN_REQUIRED;
} else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
- this.simState = IccCard.State.PUK_REQUIRED;
+ state = IccCard.State.PUK_REQUIRED;
} else {
- this.simState = IccCard.State.UNKNOWN;
+ state = IccCard.State.UNKNOWN;
}
} else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
- this.simState = IccCard.State.NETWORK_LOCKED;
+ state = IccCard.State.NETWORK_LOCKED;
} else {
- this.simState = IccCard.State.UNKNOWN;
+ state = IccCard.State.UNKNOWN;
}
+ return new SimArgs(state);
}
public String toString() {
@@ -151,6 +157,20 @@ public class KeyguardUpdateMonitor {
}
}
+ private static class BatteryStatus {
+ public final int status;
+ public final int level;
+ public final int plugged;
+ public final int health;
+ public BatteryStatus(int status, int level, int plugged, int health) {
+ this.status = status;
+ this.level = level;
+ this.plugged = plugged;
+ this.health = health;
+ }
+
+ }
+
public KeyguardUpdateMonitor(Context context) {
mContext = context;
@@ -162,7 +182,7 @@ public class KeyguardUpdateMonitor {
handleTimeUpdate();
break;
case MSG_BATTERY_UPDATE:
- handleBatteryUpdate(msg.arg1, msg.arg2);
+ handleBatteryUpdate((BatteryStatus) msg.obj);
break;
case MSG_CARRIER_INFO_UPDATE:
handleCarrierInfoUpdate();
@@ -226,8 +246,7 @@ public class KeyguardUpdateMonitor {
// take a guess to start
mSimState = IccCard.State.READY;
- mBatteryStatus = BATTERY_STATUS_UNKNOWN;
- mBatteryLevel = 100;
+ mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
mTelephonyPlmn = getDefaultPlmn();
@@ -256,18 +275,16 @@ public class KeyguardUpdateMonitor {
mTelephonySpn = getTelephonySpnFrom(intent);
mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
} else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
- final int pluggedInStatus = intent
- .getIntExtra("status", BATTERY_STATUS_UNKNOWN);
- int batteryLevel = intent.getIntExtra("level", 0);
+ final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
+ final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
+ final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
+ final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
final Message msg = mHandler.obtainMessage(
- MSG_BATTERY_UPDATE,
- pluggedInStatus,
- batteryLevel);
+ MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
mHandler.sendMessage(msg);
} else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(
- MSG_SIM_STATE_CHANGE,
- new SimArgs(intent)));
+ MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
} else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
@@ -325,15 +342,16 @@ public class KeyguardUpdateMonitor {
/**
* Handle {@link #MSG_BATTERY_UPDATE}
*/
- private void handleBatteryUpdate(int batteryStatus, int batteryLevel) {
+ private void handleBatteryUpdate(BatteryStatus batteryStatus) {
if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
- if (isBatteryUpdateInteresting(batteryStatus, batteryLevel)) {
- mBatteryStatus = batteryStatus;
- mBatteryLevel = batteryLevel;
- final boolean pluggedIn = isPluggedIn(batteryStatus);;
+ final boolean batteryUpdateInteresting =
+ isBatteryUpdateInteresting(mBatteryStatus, batteryStatus);
+ mBatteryStatus = batteryStatus;
+ if (batteryUpdateInteresting) {
for (int i = 0; i < mInfoCallbacks.size(); i++) {
+ // TODO: pass BatteryStatus object to onRefreshBatteryInfo() instead...
mInfoCallbacks.get(i).onRefreshBatteryInfo(
- shouldShowBatteryInfo(), pluggedIn, batteryLevel);
+ shouldShowBatteryInfo(),isPluggedIn(batteryStatus), batteryStatus.level);
}
}
}
@@ -377,39 +395,40 @@ public class KeyguardUpdateMonitor {
}
/**
- * @param status One of the statuses of {@link android.os.BatteryManager}
- * @return Whether the status maps to a status for being plugged in.
+ * @param pluggedIn state from {@link android.os.BatteryManager#EXTRA_PLUGGED}
+ * @return Whether the device is considered "plugged in."
*/
- private boolean isPluggedIn(int status) {
- return status == BATTERY_STATUS_CHARGING || status == BATTERY_STATUS_FULL;
+ private static boolean isPluggedIn(BatteryStatus status) {
+ return status.plugged == BatteryManager.BATTERY_PLUGGED_AC
+ || status.plugged == BatteryManager.BATTERY_PLUGGED_USB;
}
- private boolean isBatteryUpdateInteresting(int batteryStatus, int batteryLevel) {
- // change in plug is always interesting
- final boolean isPluggedIn = isPluggedIn(batteryStatus);
- final boolean wasPluggedIn = isPluggedIn(mBatteryStatus);
+ private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
+ final boolean nowPluggedIn = isPluggedIn(current);
+ final boolean wasPluggedIn = isPluggedIn(old);
final boolean stateChangedWhilePluggedIn =
- wasPluggedIn == true && isPluggedIn == true && (mBatteryStatus != batteryStatus);
- if (wasPluggedIn != isPluggedIn || stateChangedWhilePluggedIn) {
+ wasPluggedIn == true && nowPluggedIn == true
+ && (old.status != current.status);
+
+ // change in plug state is always interesting
+ if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
return true;
}
// change in battery level while plugged in
- if (isPluggedIn && mBatteryLevel != batteryLevel) {
+ if (nowPluggedIn && old.level != current.level) {
return true;
}
- if (!isPluggedIn) {
- // not plugged in and below threshold
- if (isBatteryLow(batteryLevel) && batteryLevel != mBatteryLevel) {
- return true;
- }
+ // change where battery needs charging
+ if (!nowPluggedIn && isBatteryLow(current) && current.level != old.level) {
+ return true;
}
return false;
}
- private boolean isBatteryLow(int batteryLevel) {
- return batteryLevel < LOW_BATTERY_THRESHOLD;
+ private static boolean isBatteryLow(BatteryStatus status) {
+ return status.level < LOW_BATTERY_THRESHOLD;
}
/**
@@ -518,8 +537,8 @@ public class KeyguardUpdateMonitor {
if (!mInfoCallbacks.contains(callback)) {
mInfoCallbacks.add(callback);
// Notify listener of the current state
- callback.onRefreshBatteryInfo(shouldShowBatteryInfo(), isPluggedIn(mBatteryStatus),
- mBatteryLevel);
+ callback.onRefreshBatteryInfo(shouldShowBatteryInfo(),isPluggedIn(mBatteryStatus),
+ mBatteryStatus.level);
callback.onTimeChanged();
callback.onRingerModeChanged(mRingMode);
callback.onPhoneStateChanged(mPhoneState);
@@ -556,12 +575,16 @@ public class KeyguardUpdateMonitor {
}
/**
- * Report that the user succesfully entered the sim pin or puk so we
+ * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
* have the information earlier than waiting for the intent
* broadcast from the telephony code.
+ *
+ * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
+ * through mHandler, this *must* be called from the UI thread.
*/
public void reportSimUnlocked() {
mSimState = IccCard.State.READY;
+ handleSimStateChange(new SimArgs(mSimState));
}
public boolean isKeyguardBypassEnabled() {
@@ -573,16 +596,16 @@ public class KeyguardUpdateMonitor {
}
public boolean isDeviceCharged() {
- return mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL
- || mBatteryLevel >= 100; // in case a particular device doesn't flag it
+ return mBatteryStatus.status == BATTERY_STATUS_FULL
+ || mBatteryStatus.level >= 100; // in case particular device doesn't flag it
}
public int getBatteryLevel() {
- return mBatteryLevel;
+ return mBatteryStatus.level;
}
public boolean shouldShowBatteryInfo() {
- return isPluggedIn(mBatteryStatus) || isBatteryLow(mBatteryLevel);
+ return isPluggedIn(mBatteryStatus) || isBatteryLow(mBatteryStatus);
}
public CharSequence getTelephonyPlmn() {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index 26bd697..f204070 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -46,6 +46,10 @@ public abstract class KeyguardViewBase extends FrameLayout {
private KeyguardViewCallback mCallback;
private AudioManager mAudioManager;
private TelephonyManager mTelephonyManager = null;
+ // Whether the volume keys should be handled by keyguard. If true, then
+ // they will be handled here for specific media types such as music, otherwise
+ // the audio service will bring up the volume dialog.
+ private static final boolean KEYGUARD_MANAGES_VOLUME = true;
// This is a faster way to draw the background on devices without hardware acceleration
Drawable mBackgroundDrawable = new Drawable() {
@@ -203,24 +207,28 @@ public abstract class KeyguardViewBase extends FrameLayout {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
- synchronized (this) {
- if (mAudioManager == null) {
- mAudioManager = (AudioManager) getContext().getSystemService(
- Context.AUDIO_SERVICE);
+ if (KEYGUARD_MANAGES_VOLUME) {
+ synchronized (this) {
+ if (mAudioManager == null) {
+ mAudioManager = (AudioManager) getContext().getSystemService(
+ Context.AUDIO_SERVICE);
+ }
}
+ // Volume buttons should only function for music.
+ if (mAudioManager.isMusicActive()) {
+ // TODO: Actually handle MUTE.
+ mAudioManager.adjustStreamVolume(
+ AudioManager.STREAM_MUSIC,
+ keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ ? AudioManager.ADJUST_RAISE
+ : AudioManager.ADJUST_LOWER,
+ 0);
+ }
+ // Don't execute default volume behavior
+ return true;
+ } else {
+ return false;
}
- // Volume buttons should only function for music.
- if (mAudioManager.isMusicActive()) {
- // TODO: Actually handle MUTE.
- mAudioManager.adjustStreamVolume(
- AudioManager.STREAM_MUSIC,
- keyCode == KeyEvent.KEYCODE_VOLUME_UP
- ? AudioManager.ADJUST_RAISE
- : AudioManager.ADJUST_LOWER,
- 0);
- }
- // Don't execute default volume behavior
- return true;
}
}
} else if (event.getAction() == KeyEvent.ACTION_UP) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 0499cfa..ff8d5ac 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -138,6 +138,7 @@ public class KeyguardViewManager implements KeyguardWindowController {
lp.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
}
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
lp.setTitle("Keyguard");
mWindowLayoutParams = lp;
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index c802bc1..b514689 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -830,12 +830,13 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
* action should be posted to a handler.
*
* @param keyCode The keycode of the key that woke the device
+ * @param isDocked True if the device is in the dock
* @return Whether we poked the wake lock (and turned the screen on)
*/
- public boolean onWakeKeyWhenKeyguardShowingTq(int keyCode) {
+ public boolean onWakeKeyWhenKeyguardShowingTq(int keyCode, boolean isDocked) {
if (DEBUG) Log.d(TAG, "onWakeKeyWhenKeyguardShowing(" + keyCode + ")");
- if (isWakeKeyWhenKeyguardShowing(keyCode)) {
+ if (isWakeKeyWhenKeyguardShowing(keyCode, isDocked)) {
// give the keyguard view manager a chance to adjust the state of the
// keyguard based on the key that woke the device before poking
// the wake lock
@@ -846,11 +847,22 @@ public class KeyguardViewMediator implements KeyguardViewCallback,
}
}
- private boolean isWakeKeyWhenKeyguardShowing(int keyCode) {
+ /**
+ * When the keyguard is showing we ignore some keys that might otherwise typically
+ * be considered wake keys. We filter them out here.
+ *
+ * {@link KeyEvent#KEYCODE_POWER} is notably absent from this list because it
+ * is always considered a wake key.
+ */
+ private boolean isWakeKeyWhenKeyguardShowing(int keyCode, boolean isDocked) {
switch (keyCode) {
+ // ignore volume keys unless docked
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE:
+ return isDocked;
+
+ // ignore media and camera keys
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY:
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 0f21bdb..6eff4b6 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -244,8 +244,14 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
// TODO: examine all widgets to derive clock status
mUpdateMonitor.reportClockVisible(false);
- // TODO: We should disable the wallpaper instead
- setBackgroundColor(0xff000000);
+ // If there's not a bg protection view containing the transport, then show a black
+ // background. Otherwise, allow the normal background to show.
+ if (findViewById(R.id.transport_bg_protect) == null) {
+ // TODO: We should disable the wallpaper instead
+ setBackgroundColor(0xff000000);
+ } else {
+ resetBackground();
+ }
}
public void requestHide(View view) {
@@ -552,9 +558,12 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
mScreenOn = false;
mForgotPattern = false;
mHasOverlay = mUpdateMonitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
- if (mMode == Mode.LockScreen) {
+
+ // Emulate activity life-cycle for both lock and unlock screen.
+ if (mLockScreen != null) {
((KeyguardScreen) mLockScreen).onPause();
- } else {
+ }
+ if (mUnlockScreen != null) {
((KeyguardScreen) mUnlockScreen).onPause();
}
@@ -645,9 +654,11 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler
@Override
public void show() {
- if (mMode == Mode.LockScreen) {
+ // Emulate activity life-cycle for both lock and unlock screen.
+ if (mLockScreen != null) {
((KeyguardScreen) mLockScreen).onResume();
- } else {
+ }
+ if (mUnlockScreen != null) {
((KeyguardScreen) mUnlockScreen).onResume();
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 3469483..24a2420 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -34,6 +34,7 @@ import android.view.ViewGroup;
import android.widget.*;
import android.util.Log;
import android.media.AudioManager;
+import android.provider.MediaStore;
import android.provider.Settings;
import java.io.File;
@@ -225,9 +226,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
mCallback.goToUnlockScreen();
} else if (target == 2 || target == 3) { // 2 = alt/portrait, 3 = alt/landscape
if (!mCameraDisabled) {
- // Broadcast an intent to start the Camera
- Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
- mContext.sendOrderedBroadcast(intent, null);
+ // Start the Camera
+ Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivity(intent);
mCallback.goToUnlockScreen();
} else {
toggleRingMode();
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index 3ad716b..06cd69e 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -35,15 +35,18 @@ import android.text.InputType;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.text.method.TextKeyListener;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.EditText;
import android.widget.LinearLayout;
+import android.widget.Space;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
@@ -114,6 +117,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED, 0)
!= 0);
+ boolean imeOrDeleteButtonVisible = false;
if (mIsAlpha) {
// We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
@@ -129,6 +133,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
View pinDelete = findViewById(R.id.pinDel);
if (pinDelete != null) {
pinDelete.setVisibility(View.VISIBLE);
+ imeOrDeleteButtonVisible = true;
pinDelete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -181,6 +186,7 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
Context.INPUT_METHOD_SERVICE);
if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
switchImeButton.setVisibility(View.VISIBLE);
+ imeOrDeleteButtonVisible = true;
switchImeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mCallback.pokeWakelock(); // Leave the screen on a bit longer
@@ -188,6 +194,16 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen
}
});
}
+
+ // If no icon is visible, reset the left margin on the password field so the text is
+ // still centered.
+ if (!imeOrDeleteButtonVisible) {
+ android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
+ if (params instanceof MarginLayoutParams) {
+ ((MarginLayoutParams)params).leftMargin = 0;
+ mPasswordEntry.setLayoutParams(params);
+ }
+ }
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index af86ae9..f1fe43b 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -1816,22 +1816,42 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public boolean dispatchKeyShortcutEvent(KeyEvent ev) {
- // Perform the shortcut (mPreparedPanel can be null since
- // global shortcuts (such as search) don't rely on a
- // prepared panel or menu).
- boolean handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
- Menu.FLAG_PERFORM_NO_CLOSE);
- if (handled) {
- if (mPreparedPanel != null) {
- mPreparedPanel.isHandled = true;
+ // If the panel is already prepared, then perform the shortcut using it.
+ boolean handled;
+ if (mPreparedPanel != null) {
+ handled = performPanelShortcut(mPreparedPanel, ev.getKeyCode(), ev,
+ Menu.FLAG_PERFORM_NO_CLOSE);
+ if (handled) {
+ if (mPreparedPanel != null) {
+ mPreparedPanel.isHandled = true;
+ }
+ return true;
}
- return true;
}
// Shortcut not handled by the panel. Dispatch to the view hierarchy.
final Callback cb = getCallback();
- return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchKeyShortcutEvent(ev)
- : super.dispatchKeyShortcutEvent(ev);
+ handled = cb != null && !isDestroyed() && mFeatureId < 0
+ ? cb.dispatchKeyShortcutEvent(ev) : super.dispatchKeyShortcutEvent(ev);
+ if (handled) {
+ return true;
+ }
+
+ // If the panel is not prepared, then we may be trying to handle a shortcut key
+ // combination such as Control+C. Temporarily prepare the panel then mark it
+ // unprepared again when finished to ensure that the panel will again be prepared
+ // the next time it is shown for real.
+ if (mPreparedPanel == null) {
+ PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
+ preparePanel(st, ev);
+ handled = performPanelShortcut(st, ev.getKeyCode(), ev,
+ Menu.FLAG_PERFORM_NO_CLOSE);
+ st.isPrepared = false;
+ if (handled) {
+ return true;
+ }
+ }
+ return false;
}
@Override
@@ -2562,6 +2582,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) {
addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
+ } else {
+ clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
}
if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 0a77654..0b223c1 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -39,7 +39,7 @@ import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.os.Binder;
+import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -68,8 +68,10 @@ import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
+import android.view.IApplicationToken;
import android.view.IWindowManager;
import android.view.InputChannel;
import android.view.InputDevice;
@@ -157,6 +159,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final boolean SHOW_STARTING_ANIMATIONS = true;
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
+ // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
+ // No longer recommended for desk docks; still useful in car docks.
+ static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
+ static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = 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;
@@ -221,7 +228,30 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Useful scan codes.
private static final int SW_LID = 0x00;
private static final int BTN_MOUSE = 0x110;
-
+
+ /* Table of Application Launch keys. Maps from key codes to intent categories.
+ *
+ * These are special keys that are used to launch particular kinds of applications,
+ * such as a web browser. HID defines nearly a hundred of them in the Consumer (0x0C)
+ * usage page. We don't support quite that many yet...
+ */
+ static SparseArray<String> sApplicationLaunchKeyCategories;
+ static {
+ sApplicationLaunchKeyCategories = new SparseArray<String>();
+ sApplicationLaunchKeyCategories.append(
+ KeyEvent.KEYCODE_EXPLORER, Intent.CATEGORY_APP_BROWSER);
+ sApplicationLaunchKeyCategories.append(
+ KeyEvent.KEYCODE_ENVELOPE, Intent.CATEGORY_APP_EMAIL);
+ sApplicationLaunchKeyCategories.append(
+ KeyEvent.KEYCODE_CONTACTS, Intent.CATEGORY_APP_CONTACTS);
+ sApplicationLaunchKeyCategories.append(
+ KeyEvent.KEYCODE_CALENDAR, Intent.CATEGORY_APP_CALENDAR);
+ sApplicationLaunchKeyCategories.append(
+ KeyEvent.KEYCODE_MUSIC, Intent.CATEGORY_APP_MUSIC);
+ sApplicationLaunchKeyCategories.append(
+ KeyEvent.KEYCODE_CALCULATOR, Intent.CATEGORY_APP_CALCULATOR);
+ }
+
/**
* Lock protecting internal state. Must not call out into window
* manager with lock held. (This lock will be acquired in places
@@ -268,9 +298,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
GlobalActions mGlobalActions;
volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
boolean mPendingPowerKeyUpCanceled;
- RecentApplicationsDialog mRecentAppsDialog;
Handler mHandler;
+ static final int RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS = 0;
+ static final int RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW = 1;
+ static final int RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH = 2;
+
+ RecentApplicationsDialog mRecentAppsDialog;
+ int mRecentAppsDialogHeldModifiers;
+
private static final int LID_ABSENT = -1;
private static final int LID_CLOSED = 0;
private static final int LID_OPEN = 1;
@@ -310,6 +346,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// The last window we were told about in focusChanged.
WindowState mFocusedWindow;
+ IApplicationToken mFocusedApp;
private final InputHandler mPointerLocationInputHandler = new BaseInputHandler() {
@Override
@@ -360,6 +397,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mResettingSystemUiFlags = 0;
// Bits that we are currently always keeping cleared.
int mForceClearedSystemUiFlags = 0;
+ // What we last reported to system UI about whether the compatibility
+ // menu needs to be displayed.
+ boolean mLastFocusNeedsMenu = false;
FakeWindow mHideNavFakeWindow = null;
@@ -370,8 +410,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final Rect mTmpNavigationFrame = new Rect();
WindowState mTopFullscreenOpaqueWindowState;
- WindowState mTopAppWindowState;
- WindowState mLastTopAppWindowState;
boolean mTopIsFullscreen;
boolean mForceStatusBar;
boolean mHideLockScreen;
@@ -388,10 +426,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mLockScreenTimeout;
boolean mLockScreenTimerActive;
- // visual screen saver support
- int mScreenSaverTimeout;
- boolean mScreenSaverEnabled = false;
-
// Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.)
int mEndcallBehavior;
@@ -454,8 +488,6 @@ 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.System.getUriFor(
- Settings.Secure.DREAM_TIMEOUT), false, this);
updateSettings();
}
@@ -493,7 +525,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return true;
}
if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) ||
- (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) {
+ (mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) {
// enable accelerometer if we are docked in a dock that enables accelerometer
// orientation management,
return true;
@@ -665,7 +699,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
- showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
+ showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
try {
mStatusBarService.toggleRecentApps();
@@ -676,10 +710,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
/**
- * Create (if necessary) and launch the recent apps dialog, or hide it if it is
- * already shown.
+ * Create (if necessary) and show or dismiss the recent apps dialog according
+ * according to the requested behavior.
*/
- void showOrHideRecentAppsDialog(final int heldModifiers, final boolean dismissIfShown) {
+ void showOrHideRecentAppsDialog(final int behavior) {
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -687,12 +721,33 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mRecentAppsDialog = new RecentApplicationsDialog(mContext);
}
if (mRecentAppsDialog.isShowing()) {
- if (dismissIfShown) {
- mRecentAppsDialog.dismiss();
+ switch (behavior) {
+ case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
+ mRecentAppsDialog.dismiss();
+ break;
+ case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
+ mRecentAppsDialog.dismissAndSwitch();
+ break;
+ case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
+ default:
+ break;
}
} else {
- mRecentAppsDialog.setHeldModifiers(heldModifiers);
- mRecentAppsDialog.show();
+ switch (behavior) {
+ case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
+ mRecentAppsDialog.show();
+ break;
+ case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
+ try {
+ mWindowManager.setInTouchMode(false);
+ } catch (RemoteException e) {
+ }
+ mRecentAppsDialog.show();
+ break;
+ case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
+ default:
+ break;
+ }
}
}
});
@@ -760,6 +815,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
Intent.EXTRA_DOCK_STATE_UNDOCKED);
}
+
mVibrator = new Vibrator();
mLongPressVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_longPressVibePattern);
@@ -908,11 +964,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHasSoftInput = hasSoftInput;
updateRotation = true;
}
-
- mScreenSaverTimeout = Settings.System.getInt(resolver,
- Settings.Secure.DREAM_TIMEOUT, 0);
- mScreenSaverEnabled = true;
- updateScreenSaverTimeoutLocked();
}
if (updateRotation) {
updateRotation(true);
@@ -1183,7 +1234,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation) {
- return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation);
+ // This is the same as getNonDecorDisplayHeight, unless the status bar
+ // can hide. If the status bar can hide, we don't count that as part
+ // of the decor; however for purposes of configurations, we do want to
+ // exclude it since applications can't generally use that part of the
+ // screen.
+ return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation)
+ - (mStatusBarCanHide ? mStatusBarHeight : 0);
}
public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
@@ -1568,7 +1625,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return 0;
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
if (down && repeatCount == 0) {
- showOrHideRecentAppsDialog(0, true /*dismissIfShown*/);
+ showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS);
}
return -1;
}
@@ -1604,6 +1661,62 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ // Invoke shortcuts using Meta.
+ if (down && repeatCount == 0
+ && (metaState & KeyEvent.META_META_ON) != 0) {
+ final KeyCharacterMap kcm = event.getKeyCharacterMap();
+ Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
+ metaState & ~(KeyEvent.META_META_ON
+ | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
+ if (shortcutIntent != null) {
+ shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ mContext.startActivity(shortcutIntent);
+ } catch (ActivityNotFoundException ex) {
+ Slog.w(TAG, "Dropping shortcut key combination because "
+ + "the activity to which it is registered was not found: "
+ + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
+ }
+ return -1;
+ }
+ }
+
+ // Handle application launch keys.
+ if (down && repeatCount == 0) {
+ String category = sApplicationLaunchKeyCategories.get(keyCode);
+ if (category != null) {
+ Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, category);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException ex) {
+ Slog.w(TAG, "Dropping application launch key because "
+ + "the activity to which it is registered was not found: "
+ + "keyCode=" + keyCode + ", category=" + category, ex);
+ }
+ return -1;
+ }
+ }
+
+ // Display task switcher for ALT-TAB or Meta-TAB.
+ if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
+ if (mRecentAppsDialogHeldModifiers == 0) {
+ final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
+ if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
+ || KeyEvent.metaStateHasModifiers(
+ shiftlessModifiers, KeyEvent.META_META_ON)) {
+ mRecentAppsDialogHeldModifiers = shiftlessModifiers;
+ showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW);
+ return -1;
+ }
+ }
+ } else if (!down && mRecentAppsDialogHeldModifiers != 0
+ && (metaState & mRecentAppsDialogHeldModifiers) == 0) {
+ mRecentAppsDialogHeldModifiers = 0;
+ showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
+ }
+
+ // Let the application handle the key.
return 0;
}
@@ -1625,39 +1738,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final KeyCharacterMap kcm = event.getKeyCharacterMap();
final int keyCode = event.getKeyCode();
final int metaState = event.getMetaState();
- final boolean initialDown = event.getAction() == KeyEvent.ACTION_DOWN
- && event.getRepeatCount() == 0;
-
- if (initialDown) {
- // Invoke shortcuts using Meta as a fallback.
- if ((metaState & KeyEvent.META_META_ON) != 0) {
- Intent shortcutIntent = mShortcutManager.getIntent(kcm, keyCode,
- metaState & ~(KeyEvent.META_META_ON
- | KeyEvent.META_META_LEFT_ON | KeyEvent.META_META_RIGHT_ON));
- if (shortcutIntent != null) {
- shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- mContext.startActivity(shortcutIntent);
- } catch (ActivityNotFoundException ex) {
- Slog.w(TAG, "Dropping shortcut key combination because "
- + "the activity to which it is registered was not found: "
- + "META+" + KeyEvent.keyCodeToString(keyCode), ex);
- }
- return null;
- }
- }
-
- // Display task switcher for ALT-TAB or Meta-TAB.
- if (keyCode == KeyEvent.KEYCODE_TAB) {
- final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
- if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
- || KeyEvent.metaStateHasModifiers(
- shiftlessModifiers, KeyEvent.META_META_ON)) {
- showOrHideRecentAppsDialog(shiftlessModifiers, false /*dismissIfShown*/);
- return null;
- }
- }
- }
// Check for fallback actions specified by the key character map.
if (getFallbackAction(kcm, keyCode, metaState, mFallbackAction)) {
@@ -2243,7 +2323,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
public void beginAnimationLw(int displayWidth, int displayHeight) {
mTopFullscreenOpaqueWindowState = null;
- mTopAppWindowState = null;
mForceStatusBar = false;
mHideLockScreen = false;
@@ -2281,12 +2360,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
}
- if (mTopAppWindowState == null && win.isVisibleOrBehindKeyguardLw()) {
- if (attrs.type >= FIRST_APPLICATION_WINDOW
- && attrs.type <= LAST_APPLICATION_WINDOW) {
- mTopAppWindowState = win;
- }
- }
}
/** {@inheritDoc} */
@@ -2342,35 +2415,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mTopIsFullscreen = topIsFullscreen;
- if (mTopAppWindowState != null && mTopAppWindowState != mLastTopAppWindowState) {
- mLastTopAppWindowState = mTopAppWindowState;
-
- final boolean topNeedsMenu = (mTopAppWindowState.getAttrs().flags
- & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
-
- mHandler.post(new Runnable() {
- public void run() {
- if (mStatusBarService == null) {
- // This is the one that can not go away, but it doesn't come up
- // before the window manager does, so don't fail if it doesn't
- // exist. This works as long as no fullscreen windows come up
- // before the status bar service does.
- mStatusBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService("statusbar"));
- }
- final IStatusBarService sbs = mStatusBarService;
- if (mStatusBarService != null) {
- try {
- sbs.topAppWindowChanged(topNeedsMenu);
- } catch (RemoteException e) {
- // This should be impossible because we're in the same process.
- mStatusBarService = null;
- }
- }
- }
- });
- }
-
// Hide the key guard if a visible window explicitly specifies that it wants to be displayed
// when the screen is locked
if (mKeyguard != null) {
@@ -2479,7 +2523,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// keyguard, then we need to have it turn on the
// screen once it is shown.
mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(
- KeyEvent.KEYCODE_POWER);
+ KeyEvent.KEYCODE_POWER, mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
}
} else {
// Light up the keyboard if we are sliding up.
@@ -2699,7 +2743,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (down && isWakeKey) {
if (keyguardActive) {
// If the keyguard is showing, let it decide what to do with the wake key.
- mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode);
+ mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(keyCode,
+ mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED);
} else {
// Otherwise, wake the device ourselves.
result |= ACTION_POKE_USER_ACTIVITY;
@@ -2987,7 +3032,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
synchronized (mLock) {
updateOrientationListenerLp();
updateLockScreenTimeout();
- updateScreenSaverTimeoutLocked();
}
}
@@ -3034,7 +3078,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mScreenOnEarly = true;
updateOrientationListenerLp();
updateLockScreenTimeout();
- updateScreenSaverTimeoutLocked();
}
}
@@ -3124,11 +3167,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
sensorRotation = lastRotation;
}
- int preferredRotation = -1;
- if (mHdmiPlugged) {
- // Ignore sensor when plugged into HDMI.
- preferredRotation = mHdmiRotation;
- } else if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
+ final int preferredRotation;
+ if (mLidOpen == LID_OPEN && mLidOpenRotation >= 0) {
// Ignore sensor when lid switch is open and rotation is forced.
preferredRotation = mLidOpenRotation;
} else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
@@ -3138,13 +3178,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// enable 180 degree rotation while docked.
preferredRotation = mCarDockEnablesAccelerometer
? sensorRotation : mCarDockRotation;
- } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
+ } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
&& (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
// Ignore sensor when in desk dock unless explicitly enabled.
// This case can override the behavior of NOSENSOR, and can also
// enable 180 degree rotation while docked.
preferredRotation = mDeskDockEnablesAccelerometer
? sensorRotation : mDeskDockRotation;
+ } else if (mHdmiPlugged) {
+ // Ignore sensor when plugged into HDMI.
+ // Note that the dock orientation overrides the HDMI orientation.
+ preferredRotation = mHdmiRotation;
} else if ((mAccelerometerDefault != 0 /* implies not rotation locked */
&& (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
|| orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED))
@@ -3171,28 +3217,39 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
// Apply rotation lock.
preferredRotation = mUserRotation;
+ } else {
+ // No overriding preference.
+ // We will do exactly what the application asked us to do.
+ preferredRotation = -1;
}
- // TODO: Sometimes, we might want to override the application-requested
- // orientation, such as when HDMI is plugged in or when docked.
- // We can do that by modifying the appropriate cases above to return
- // the preferred orientation directly instead of continuing on down here.
-
switch (orientation) {
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- // Always return portrait if orientation set to portrait.
+ // Return portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
return mPortraitRotation;
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- // Always return landscape if orientation set to landscape.
+ // Return landscape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
return mLandscapeRotation;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- // Always return portrait if orientation set to portrait.
+ // Return reverse portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
return mUpsideDownRotation;
case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- // Always return seascape if orientation set to reverse landscape.
+ // Return seascape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
return mSeascapeRotation;
case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
@@ -3376,6 +3433,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManager.LayoutParams.FLAG_DIM_BEHIND
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN);
mBootMsgDialog.getWindow().setDimAmount(1);
+ WindowManager.LayoutParams lp = mBootMsgDialog.getWindow().getAttributes();
+ lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+ mBootMsgDialog.getWindow().setAttributes(lp);
mBootMsgDialog.setCancelable(false);
mBootMsgDialog.show();
}
@@ -3416,73 +3476,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
}
}
-
- // Turn this off for now, screen savers not currently enabled.
- if (false) {
- synchronized (mLock) {
- updateScreenSaverTimeoutLocked();
- }
- }
- }
-
- Runnable mScreenSaverActivator = null;
- /*new Runnable() {
- public void run() {
- synchronized (this) {
- if (!(mScreenSaverEnabled && mScreenOn)) {
- Log.w(TAG, "mScreenSaverActivator ran, but the screensaver should not be showing. Who's driving this thing?");
- return;
- }
-
- if (localLOGV) Log.v(TAG, "mScreenSaverActivator entering dreamland");
- try {
- String component = Settings.System.getString(
- mContext.getContentResolver(), Settings.Secure.DREAM_COMPONENT);
- if (component != null) {
- 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_ACTIVITY_SINGLE_TOP);
- 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;
-
- // GAH... acquiring a lock within a lock? Please let's fix this.
- // (Also note this is called from userActivity, with the power manager
- // lock held. Not good.)
- synchronized (mScreenSaverActivator) {
- mHandler.removeCallbacks(mScreenSaverActivator);
- if (mScreenSaverEnabled && mScreenOnEarly && mScreenSaverTimeout > 0) {
- if (localLOGV)
- Log.v(TAG, "scheduling screensaver for " + mScreenSaverTimeout + "ms from now");
- mHandler.postDelayed(mScreenSaverActivator, mScreenSaverTimeout);
- } else {
- if (localLOGV) {
- if (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() {
@@ -3533,21 +3526,35 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
/**
- * Return an Intent to launch the currently active dock as home. Returns
- * null if the standard home should be launched.
+ * Return an Intent to launch the currently active dock app as home. Returns
+ * null if the standard home should be launched, which is the case if any of the following is
+ * true:
+ * <ul>
+ * <li>The device is not in either car mode or desk mode
+ * <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
+ * <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
+ * <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
+ * <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
+ * </ul>
* @return
*/
Intent createHomeDockIntent() {
- Intent intent;
+ Intent intent = null;
// What home does is based on the mode, not the dock state. That
// is, when in car mode you should be taken to car home regardless
// of whether we are actually in a car dock.
if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
- intent = mCarDockIntent;
+ if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
+ intent = mCarDockIntent;
+ }
} else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
- intent = mDeskDockIntent;
- } else {
+ if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
+ intent = mDeskDockIntent;
+ }
+ }
+
+ if (intent == null) {
return null;
}
@@ -3674,11 +3681,6 @@ 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) {
- mScreenSaverEnabled = false;
- }
}
public void screenOnStoppedLw() {
@@ -3687,13 +3689,6 @@ 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
- mScreenSaverEnabled = true;
- updateScreenSaverTimeoutLocked();
- }
}
}
@@ -3712,10 +3707,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
& ~mResettingSystemUiFlags
& ~mForceClearedSystemUiFlags;
int diff = visibility ^ mLastSystemUiFlags;
- if (diff == 0) {
+ final boolean needsMenu = mFocusedWindow.getNeedsMenuLw(mTopFullscreenOpaqueWindowState);
+ if (diff == 0 && mLastFocusNeedsMenu == needsMenu
+ && mFocusedApp == mFocusedWindow.getAppToken()) {
return 0;
}
mLastSystemUiFlags = visibility;
+ mLastFocusNeedsMenu = needsMenu;
+ mFocusedApp = mFocusedWindow.getAppToken();
mHandler.post(new Runnable() {
public void run() {
if (mStatusBarService == null) {
@@ -3725,6 +3724,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mStatusBarService != null) {
try {
mStatusBarService.setSystemUiVisibility(visibility);
+ mStatusBarService.topAppWindowChanged(needsMenu);
} catch (RemoteException e) {
// not much to be done
mStatusBarService = null;
@@ -3757,6 +3757,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print(" mForceClearedSystemUiFlags=0x");
pw.println(Integer.toHexString(mForceClearedSystemUiFlags));
}
+ if (mLastFocusNeedsMenu) {
+ pw.print(prefix); pw.print("mLastFocusNeedsMenu=");
+ pw.println(mLastFocusNeedsMenu);
+ }
pw.print(prefix); pw.print("mUiMode="); pw.print(mUiMode);
pw.print(" mDockMode="); pw.print(mDockMode);
pw.print(" mCarDockRotation="); pw.print(mCarDockRotation);
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
index aa00fbd..b9903dd 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
@@ -71,8 +71,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
}
};
- private int mHeldModifiers;
-
public RecentApplicationsDialog(Context context) {
super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
@@ -124,17 +122,6 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
}
}
- /**
- * Sets the modifier keys that are being held to keep the dialog open, or 0 if none.
- * Used to make the recent apps dialog automatically dismiss itself when the modifiers
- * all go up.
- * @param heldModifiers The held key modifiers, such as {@link KeyEvent#META_ALT_ON}.
- * Should exclude shift.
- */
- public void setHeldModifiers(int heldModifiers) {
- mHeldModifiers = heldModifiers;
- }
-
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_TAB) {
@@ -174,30 +161,27 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
return super.onKeyDown(keyCode, event);
}
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (mHeldModifiers != 0 && (event.getModifiers() & mHeldModifiers) == 0) {
- final int numIcons = mIcons.length;
- RecentTag tag = null;
- for (int i = 0; i < numIcons; i++) {
- if (mIcons[i].getVisibility() != View.VISIBLE) {
+ /**
+ * Dismiss the dialog and switch to the selected application.
+ */
+ public void dismissAndSwitch() {
+ final int numIcons = mIcons.length;
+ RecentTag tag = null;
+ for (int i = 0; i < numIcons; i++) {
+ if (mIcons[i].getVisibility() != View.VISIBLE) {
+ break;
+ }
+ if (i == 0 || mIcons[i].hasFocus()) {
+ tag = (RecentTag) mIcons[i].getTag();
+ if (mIcons[i].hasFocus()) {
break;
}
- if (i == 0 || mIcons[i].hasFocus()) {
- tag = (RecentTag) mIcons[i].getTag();
- if (mIcons[i].hasFocus()) {
- break;
- }
- }
- }
- if (tag != null) {
- switchTo(tag);
}
- dismiss();
- return true;
}
-
- return super.onKeyUp(keyCode, event);
+ if (tag != null) {
+ switchTo(tag);
+ }
+ dismiss();
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
index 6acd1c5..ba06996 100644
--- a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
@@ -106,7 +106,7 @@ public class SimPukUnlockScreen extends LinearLayout implements KeyguardScreen,
mHeaderText.setSelected(true);
mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, updateMonitor,
- lockpatternutils, callback, true);
+ lockpatternutils, callback, false);
mPinText.setFocusableInTouchMode(true);
mPinText.setOnFocusChangeListener(this);
@@ -242,20 +242,24 @@ public class SimPukUnlockScreen extends LinearLayout implements KeyguardScreen,
new CheckSimPuk(mPukText.getText().toString(),
mPinText.getText().toString()) {
- void onSimLockChangedResponse(boolean success) {
- if (mSimUnlockProgressDialog != null) {
- mSimUnlockProgressDialog.hide();
- }
- if (success) {
- // before closing the keyguard, report back that
- // the sim is unlocked so it knows right away
- mUpdateMonitor.reportSimUnlocked();
- mCallback.goToUnlockScreen();
- } else {
- mHeaderText.setText(R.string.badPuk);
- mPukText.setText("");
- mPinText.setText("");
- }
+ void onSimLockChangedResponse(final boolean success) {
+ mPinText.post(new Runnable() {
+ public void run() {
+ if (mSimUnlockProgressDialog != null) {
+ mSimUnlockProgressDialog.hide();
+ }
+ if (success) {
+ // before closing the keyguard, report back that
+ // the sim is unlocked so it knows right away
+ mUpdateMonitor.reportSimUnlocked();
+ mCallback.goToUnlockScreen();
+ } else {
+ mHeaderText.setText(R.string.badPuk);
+ mPukText.setText("");
+ mPinText.setText("");
+ }
+ }
+ });
}
}.start();
}
@@ -379,6 +383,9 @@ public class SimPukUnlockScreen extends LinearLayout implements KeyguardScreen,
public void onClick(View v) {
if (v == mCancelButton) {
+ // clear the PIN/PUK entry fields if the user cancels
+ mPinText.setText("");
+ mPukText.setText("");
mCallback.goToLockScreen();
return;
}
diff --git a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
index 184748a..9604cdc 100644
--- a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
@@ -100,7 +100,7 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie
mOkButton.setOnClickListener(this);
mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, updateMonitor,
- lockpatternutils, callback, true);
+ lockpatternutils, callback, false);
setFocusableInTouchMode(true);
}
@@ -214,21 +214,25 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie
getSimUnlockProgressDialog().show();
new CheckSimPin(mPinText.getText().toString()) {
- void onSimLockChangedResponse(boolean success) {
- if (mSimUnlockProgressDialog != null) {
- mSimUnlockProgressDialog.hide();
- }
- if (success) {
- // before closing the keyguard, report back that
- // the sim is unlocked so it knows right away
- mUpdateMonitor.reportSimUnlocked();
- mCallback.goToUnlockScreen();
- } else {
- mHeaderText.setText(R.string.keyguard_password_wrong_pin_code);
- mPinText.setText("");
- mEnteredDigits = 0;
- }
- mCallback.pokeWakelock();
+ void onSimLockChangedResponse(final boolean success) {
+ mPinText.post(new Runnable() {
+ public void run() {
+ if (mSimUnlockProgressDialog != null) {
+ mSimUnlockProgressDialog.hide();
+ }
+ if (success) {
+ // before closing the keyguard, report back that
+ // the sim is unlocked so it knows right away
+ mUpdateMonitor.reportSimUnlocked();
+ mCallback.goToUnlockScreen();
+ } else {
+ mHeaderText.setText(R.string.keyguard_password_wrong_pin_code);
+ mPinText.setText("");
+ mEnteredDigits = 0;
+ }
+ mCallback.pokeWakelock();
+ }
+ });
}
}.start();
}
@@ -355,6 +359,7 @@ public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, Vie
public void onClick(View v) {
if (v == mCancelButton) {
+ mPinText.setText(""); // clear the PIN entry field if the user cancels
mCallback.goToLockScreen();
return;
}