import android.text.InputFilter;
import android.text.LoginFilter;
import android.text.TextWatcher;
-import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
*/
public class AccountUnlockScreen extends RelativeLayout implements KeyguardScreen,
View.OnClickListener, ServiceConnection, TextWatcher {
+
+
private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
private static final String LOCK_PATTERN_CLASS =
"com.android.settings.ChooseLockPattern";
public boolean needsInput() {
return true;
}
-
+
/** {@inheritDoc} */
public void onPause() {
return super.dispatchKeyEvent(event);
}
- /**
- * Given the string the user entered in the 'username' field, find
- * the stored account that they probably intended. Prefer, in order:
- *
- * - an exact match for what was typed, or
- * - a case-insensitive match for what was typed, or
- * - if they didn't include a domain, an exact match of the username, or
- * - if they didn't include a domain, a case-insensitive
- * match of the username.
- *
- * If there is a tie for the best match, choose neither --
- * the user needs to be more specific.
- *
- * @return an account name from the database, or null if we can't
- * find a single best match.
- */
- private String findIntendedAccount(String username) {
- String[] accounts = null;
- try {
- accounts = mAccountsService.getAccounts();
- } catch (RemoteException e) {
- return null;
- }
- if (accounts == null) {
- return null;
- }
-
- // Try to figure out which account they meant if they
- // typed only the username (and not the domain), or got
- // the case wrong.
-
- String bestAccount = null;
- int bestScore = 0;
- for (String a: accounts) {
- int score = 0;
- if (username.equals(a)) {
- score = 4;
- } else if (username.equalsIgnoreCase(a)) {
- score = 3;
- } else if (username.indexOf('@') < 0) {
- int i = a.indexOf('@');
- if (i >= 0) {
- String aUsername = a.substring(0, i);
- if (username.equals(aUsername)) {
- score = 2;
- } else if (username.equalsIgnoreCase(aUsername)) {
- score = 1;
- }
- }
- }
- if (score > bestScore) {
- bestAccount = a;
- bestScore = score;
- } else if (score == bestScore) {
- bestAccount = null;
- }
- }
- return bestAccount;
- }
-
private boolean checkPassword() {
final String login = mLogin.getText().toString();
final String password = mPassword.getText().toString();
try {
- String account = findIntendedAccount(login);
- if (account == null) {
- return false;
- }
- return mAccountsService.shouldUnlock(account, password);
+ return mAccountsService.shouldUnlock(login, password);
} catch (RemoteException e) {
return false;
}
package com.android.internal.policy.impl;
+import com.android.internal.R;
+import com.google.android.collect.Lists;
+
import android.app.AlertDialog;
import android.app.StatusBarManager;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.DialogInterface;
+import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.DialogInterface;
import android.media.AudioManager;
+import android.os.LocalPowerManager;
import android.os.Handler;
import android.os.Message;
-import android.provider.Settings;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.util.Log;
+import android.os.SystemClock;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.TextView;
-import com.android.internal.R;
-import com.google.android.collect.Lists;
import java.util.ArrayList;
*/
class GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
- private static final String TAG = "GlobalActions";
-
private StatusBarManager mStatusBar;
private final Context mContext;
+ private final LocalPowerManager mPowerManager;
private final AudioManager mAudioManager;
-
private ArrayList<Action> mItems;
private AlertDialog mDialog;
private ToggleAction mSilentModeToggle;
- private ToggleAction mAirplaneModeOn;
private MyAdapter mAdapter;
private boolean mKeyguardShowing = false;
private boolean mDeviceProvisioned = false;
- private ToggleAction.State mAirplaneState = ToggleAction.State.Off;
/**
- * @param context everything needs a context :(
+ * @param context everything needs a context :)
+ * @param powerManager used to turn the screen off (the lock action).
*/
- public GlobalActions(Context context) {
+ public GlobalActions(Context context, LocalPowerManager powerManager) {
mContext = context;
+ mPowerManager = powerManager;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
// receive broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.registerReceiver(mBroadcastReceiver, filter);
-
- // get notified of phone state changes
- TelephonyManager telephonyManager =
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
}
/**
}
};
- mAirplaneModeOn = new ToggleAction(
- R.drawable.ic_lock_airplane_mode,
- R.drawable.ic_lock_airplane_mode_off,
- R.string.global_actions_toggle_airplane_mode,
- R.string.global_actions_airplane_mode_on_status,
- R.string.global_actions_airplane_mode_off_status) {
-
- void onToggle(boolean on) {
- // Change the system setting
- Settings.System.putInt(
- mContext.getContentResolver(),
- Settings.System.AIRPLANE_MODE_ON,
- on ? 1 : 0);
- Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- intent.putExtra("state", on);
- mContext.sendBroadcast(intent);
- }
-
- @Override
- protected void changeStateFromPress(boolean buttonOn) {
- mState = buttonOn ? State.TurningOn : State.TurningOff;
- mAirplaneState = mState;
- }
+ mItems = Lists.newArrayList(
+ /* Disabled pending bug 1304831 -- key or touch events wake up device before it
+ * can go to sleep.
+ // first: lock screen
+ new SinglePressAction(com.android.internal.R.drawable.ic_lock_lock, R.string.global_action_lock) {
- public boolean showDuringKeyguard() {
- return true;
- }
+ public void onPress() {
+ mPowerManager.goToSleep(SystemClock.uptimeMillis() + 1);
+ }
- public boolean showBeforeProvisioning() {
- return false;
- }
- };
+ public boolean showDuringKeyguard() {
+ return false;
+ }
- mItems = Lists.newArrayList(
- // silent mode
+ public boolean showBeforeProvisioning() {
+ return false;
+ }
+ },
+ */
+ // next: silent mode
mSilentModeToggle,
- // next: airplane mode
- mAirplaneModeOn,
// last: power off
- new SinglePressAction(
- com.android.internal.R.drawable.ic_lock_power_off,
- R.string.global_action_power_off) {
+ new SinglePressAction(com.android.internal.R.drawable.ic_lock_power_off, R.string.global_action_power_off) {
public void onPress() {
// shutdown by making sure radio and power are handled accordingly.
}
private void prepareDialog() {
+ // TODO: May need another 'Vibrate' toggle button, but for now treat them the same
final boolean silentModeOn =
mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
- mSilentModeToggle.updateState(
- silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
- mAirplaneModeOn.updateState(mAirplaneState);
+ mSilentModeToggle.updateState(silentModeOn);
mAdapter.notifyDataSetChanged();
if (mKeyguardShowing) {
mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
}
-
/** {@inheritDoc} */
public void onDismiss(DialogInterface dialog) {
mStatusBar.disable(StatusBarManager.DISABLE_NONE);
return count;
}
- @Override
- public boolean isEnabled(int position) {
- return getItem(position).isEnabled();
- }
-
- @Override
- public boolean areAllItemsEnabled() {
- return false;
- }
-
public Action getItem(int position) {
int filteredPos = 0;
public View getView(int position, View convertView, ViewGroup parent) {
Action action = getItem(position);
- return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+ return action.create(mContext, (LinearLayout) convertView, LayoutInflater.from(mContext));
}
}
* What each item in the global actions dialog must be able to support.
*/
private interface Action {
- View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater);
+ LinearLayout create(Context context, LinearLayout convertView, LayoutInflater inflater);
void onPress();
* device is provisioned.
*/
boolean showBeforeProvisioning();
-
- boolean isEnabled();
}
/**
mMessageResId = messageResId;
}
- public boolean isEnabled() {
- return true;
- }
-
abstract public void onPress();
- public View create(
- Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
- View v = (convertView != null) ?
+ public LinearLayout create(Context context, LinearLayout convertView, LayoutInflater inflater) {
+ LinearLayout v = (LinearLayout) ((convertView != null) ?
convertView :
- inflater.inflate(R.layout.global_actions_item, parent, false);
+ inflater.inflate(R.layout.global_actions_item, null));
ImageView icon = (ImageView) v.findViewById(R.id.icon);
TextView messageView = (TextView) v.findViewById(R.id.message);
* A toggle action knows whether it is on or off, and displays an icon
* and status message accordingly.
*/
- private static abstract class ToggleAction implements Action {
+ static abstract class ToggleAction implements Action {
- enum State {
- Off(false),
- TurningOn(true),
- TurningOff(true),
- On(false);
-
- private final boolean inTransition;
-
- State(boolean intermediate) {
- inTransition = intermediate;
- }
-
- public boolean inTransition() {
- return inTransition;
- }
- }
-
- protected State mState = State.Off;
+ private boolean mOn = false;
// prefs
private final int mEnabledIconResId;
mDisabledStatusMessageResId = disabledStatusMessageResId;
}
- public View create(Context context, View convertView, ViewGroup parent,
+ public LinearLayout create(Context context, LinearLayout convertView,
LayoutInflater inflater) {
- View v = (convertView != null) ?
+ LinearLayout v = (LinearLayout) ((convertView != null) ?
convertView :
inflater.inflate(R
- .layout.global_actions_item, parent, false);
+ .layout.global_actions_item, null));
ImageView icon = (ImageView) v.findViewById(R.id.icon);
TextView messageView = (TextView) v.findViewById(R.id.message);
messageView.setText(mMessageResId);
- boolean on = ((mState == State.On) || (mState == State.TurningOn));
icon.setImageDrawable(context.getResources().getDrawable(
- (on ? mEnabledIconResId : mDisabledIconResid)));
- statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
+ (mOn ? mEnabledIconResId : mDisabledIconResid)));
+ statusView.setText(mOn ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
statusView.setVisibility(View.VISIBLE);
- final boolean enabled = isEnabled();
- messageView.setEnabled(enabled);
- statusView.setEnabled(enabled);
- icon.setEnabled(enabled);
- v.setEnabled(enabled);
-
return v;
}
- public final void onPress() {
- if (mState.inTransition()) {
- Log.w(TAG, "shouldn't be able to toggle when in transition");
- return;
- }
-
- final boolean nowOn = !(mState == State.On);
- onToggle(nowOn);
- changeStateFromPress(nowOn);
- }
-
- public boolean isEnabled() {
- return !mState.inTransition();
- }
-
- /**
- * Implementations may override this if their state can be in on of the intermediate
- * states until some notification is received (e.g airplane mode is 'turning off' until
- * we know the wireless connections are back online
- * @param buttonOn Whether the button was turned on or off
- */
- protected void changeStateFromPress(boolean buttonOn) {
- mState = buttonOn ? State.On : State.Off;
+ public void onPress() {
+ updateState(!mOn);
+ onToggle(mOn);
}
abstract void onToggle(boolean on);
- public void updateState(State state) {
- mState = state;
+ public void updateState(boolean on) {
+ mOn = on;
}
}
}
};
- PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
- @Override
- public void onServiceStateChanged(ServiceState serviceState) {
- final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF;
- mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off;
- mAirplaneModeOn.updateState(mAirplaneState);
- mAdapter.notifyDataSetChanged();
- }
- };
-
private static final int MESSAGE_DISMISS = 0;
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.PixelFormat;
-import android.graphics.ColorFilter;
import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;
(LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
- LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
showAlmostAtAccountLoginDialog();
- } else if (mHasAccount
- && failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
+ } else if (mHasAccount && failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) {
mLockPatternUtils.setPermanentlyLocked(true);
updateScreen(mMode);
} else if ((failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)
setFocusableInTouchMode(true);
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
- // wall paper background
- final BitmapDrawable drawable = (BitmapDrawable) context.getWallpaper();
- setBackgroundDrawable(
- new FastBitmapDrawable(drawable.getBitmap()));
-
// create both the lock and unlock screen so they are quickly available
// when the screen turns on
mLockScreen = createLockScreen();
final View visibleScreen = (mode == Mode.LockScreen)
? mLockScreen : getUnlockScreenForCurrentUnlockMode();
- // do this before changing visibility so focus isn't requested before the input
- // flag is set
- mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());
-
if (mScreenOn) {
if (goneScreen.getVisibility() == View.VISIBLE) {
goneScreen.setVisibility(View.GONE);
visibleScreen.setVisibility(View.VISIBLE);
-
+ mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput());
+
if (!visibleScreen.requestFocus()) {
throw new IllegalStateException("keyguard screen must be able to take "
+ "focus when shown " + visibleScreen.getClass().getCanonicalName());
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
dialog.show();
}
-
- /**
- * Used to put wallpaper on the background of the lock screen. Centers it Horizontally and
- * vertically.
- */
- static private class FastBitmapDrawable extends Drawable {
- private Bitmap mBitmap;
-
- private FastBitmapDrawable(Bitmap bitmap) {
- mBitmap = bitmap;
- }
-
- @Override
- public void draw(Canvas canvas) {
- canvas.drawBitmap(
- mBitmap,
- (getBounds().width() - mBitmap.getWidth()) / 2,
- (getBounds().height() - mBitmap.getHeight()) / 2,
- null);
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- public void setAlpha(int alpha) {
- }
-
- @Override
- public void setColorFilter(ColorFilter cf) {
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mBitmap.getWidth();
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mBitmap.getHeight();
- }
-
- @Override
- public int getMinimumWidth() {
- return mBitmap.getWidth();
- }
-
- @Override
- public int getMinimumHeight() {
- return mBitmap.getHeight();
- }
- }
}
private boolean mKeycodeCameraTimeoutActive = false;
static final int MSG_MENU_LONG_PRESS = 1;
- static final int MSG_MENU_LONG_PRESS_COMPLETE = 2;
- static final int MSG_CALL_LONG_PRESS = 3;
- static final int MSG_CALL_LONG_PRESS_COMPLETE = 4;
- static final int MSG_CAMERA_LONG_PRESS = 5;
- static final int MSG_CAMERA_LONG_PRESS_COMPLETE = 6;
+ static final int MSG_CALL_LONG_PRESS = 2;
+ static final int MSG_CAMERA_LONG_PRESS = 3;
private final Handler mKeycodeMenuTimeoutHandler = new Handler() {
@Override
switch (msg.what) {
case MSG_MENU_LONG_PRESS: {
if (mPanelChordingKey == 0) return;
- // Before actually doing the long press, enqueue another
- // message and do the processing there. This helps if
- // the app isn't being responsive, and finally woke up --
- // if the window manager wasn't told about it processing
- // the down key for too long, it would enqueue the key up
- // at a time after the timeout of this message. So we go
- // through another message, to make sure we process an up
- // before continuing.
- mKeycodeMenuTimeoutHandler.sendEmptyMessage(
- MSG_MENU_LONG_PRESS_COMPLETE);
- break;
- }
- case MSG_CALL_LONG_PRESS: {
- if (!mKeycodeCallTimeoutActive) return;
- // See above.
- mKeycodeMenuTimeoutHandler.sendEmptyMessage(
- MSG_CALL_LONG_PRESS_COMPLETE);
- break;
- }
- case MSG_CAMERA_LONG_PRESS: {
- if (!mKeycodeCameraTimeoutActive) return;
- // See above.
- mKeycodeMenuTimeoutHandler.sendEmptyMessage(
- MSG_CAMERA_LONG_PRESS_COMPLETE);
- break;
- }
- case MSG_MENU_LONG_PRESS_COMPLETE: {
- if (mPanelChordingKey == 0) return;
mPanelChordingKey = 0;
mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
InputMethodManager imm = (InputMethodManager)
imm.showSoftInputUnchecked(InputMethodManager.SHOW_FORCED);
}
} break;
- case MSG_CALL_LONG_PRESS_COMPLETE: {
+ case MSG_CALL_LONG_PRESS: {
if (!mKeycodeCallTimeoutActive) return;
mKeycodeCallTimeoutActive = false;
mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
startCallActivity();
}
} break;
- case MSG_CAMERA_LONG_PRESS_COMPLETE: {
+ case MSG_CAMERA_LONG_PRESS: {
if (!mKeycodeCameraTimeoutActive) return;
mKeycodeCameraTimeoutActive = false;
mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null);
intent.putExtra(Intent.EXTRA_KEY_EVENT, (KeyEvent) msg.obj);
getContext().sendOrderedBroadcast(intent, null);
- sendCloseSystemWindows();
} break;
}
}